vat: fix increment_address(...)
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   api_main_t *am = vlibapi_get_main ();
107   vam->socket_client_main = &socket_client_main;
108   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109                                       "vpp_api_test",
110                                       0 /* default socket rx, tx buffer */ )))
111     return rv;
112
113   /* vpp expects the client index in network order */
114   vam->my_client_index = htonl (socket_client_main.client_index);
115   am->my_client_index = vam->my_client_index;
116   return 0;
117 }
118 #else /* vpp built-in case, we don't do sockets... */
119 int
120 vat_socket_connect (vat_main_t * vam)
121 {
122   return 0;
123 }
124
125 int
126 vl_socket_client_read (int wait)
127 {
128   return -1;
129 };
130
131 int
132 vl_socket_client_write ()
133 {
134   return -1;
135 };
136
137 void *
138 vl_socket_client_msg_alloc (int nbytes)
139 {
140   return 0;
141 }
142 #endif
143
144
145 f64
146 vat_time_now (vat_main_t * vam)
147 {
148 #if VPP_API_TEST_BUILTIN
149   return vlib_time_now (vam->vlib_main);
150 #else
151   return clib_time_now (&vam->clib_time);
152 #endif
153 }
154
155 void
156 errmsg (char *fmt, ...)
157 {
158   vat_main_t *vam = &vat_main;
159   va_list va;
160   u8 *s;
161
162   va_start (va, fmt);
163   s = va_format (0, fmt, &va);
164   va_end (va);
165
166   vec_add1 (s, 0);
167
168 #if VPP_API_TEST_BUILTIN
169   vlib_cli_output (vam->vlib_main, (char *) s);
170 #else
171   {
172     if (vam->ifp != stdin)
173       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
174                vam->input_line_number);
175     else
176       fformat (vam->ofp, "%s\n", (char *) s);
177     fflush (vam->ofp);
178   }
179 #endif
180
181   vec_free (s);
182 }
183
184 #if VPP_API_TEST_BUILTIN == 0
185 static uword
186 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
187 {
188   vat_main_t *vam = va_arg (*args, vat_main_t *);
189   u32 *result = va_arg (*args, u32 *);
190   u8 *if_name;
191   uword *p;
192
193   if (!unformat (input, "%s", &if_name))
194     return 0;
195
196   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
197   if (p == 0)
198     return 0;
199   *result = p[0];
200   return 1;
201 }
202
203 static uword
204 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
205 {
206   return 0;
207 }
208
209 /* Parse an IP4 address %d.%d.%d.%d. */
210 uword
211 unformat_ip4_address (unformat_input_t * input, va_list * args)
212 {
213   u8 *result = va_arg (*args, u8 *);
214   unsigned a[4];
215
216   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
217     return 0;
218
219   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
220     return 0;
221
222   result[0] = a[0];
223   result[1] = a[1];
224   result[2] = a[2];
225   result[3] = a[3];
226
227   return 1;
228 }
229
230 uword
231 unformat_ethernet_address (unformat_input_t * input, va_list * args)
232 {
233   u8 *result = va_arg (*args, u8 *);
234   u32 i, a[6];
235
236   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
237                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
238     return 0;
239
240   /* Check range. */
241   for (i = 0; i < 6; i++)
242     if (a[i] >= (1 << 8))
243       return 0;
244
245   for (i = 0; i < 6; i++)
246     result[i] = a[i];
247
248   return 1;
249 }
250
251 /* Returns ethernet type as an int in host byte order. */
252 uword
253 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
254                                         va_list * args)
255 {
256   u16 *result = va_arg (*args, u16 *);
257   int type;
258
259   /* Numeric type. */
260   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
261     {
262       if (type >= (1 << 16))
263         return 0;
264       *result = type;
265       return 1;
266     }
267   return 0;
268 }
269
270 /* Parse an IP46 address. */
271 uword
272 unformat_ip46_address (unformat_input_t * input, va_list * args)
273 {
274   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
275   ip46_type_t type = va_arg (*args, ip46_type_t);
276   if ((type != IP46_TYPE_IP6) &&
277       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
278     {
279       ip46_address_mask_ip4 (ip46);
280       return 1;
281     }
282   else if ((type != IP46_TYPE_IP4) &&
283            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
284     {
285       return 1;
286     }
287   return 0;
288 }
289
290 /* Parse an IP6 address. */
291 uword
292 unformat_ip6_address (unformat_input_t * input, va_list * args)
293 {
294   ip6_address_t *result = va_arg (*args, ip6_address_t *);
295   u16 hex_quads[8];
296   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
297   uword c, n_colon, double_colon_index;
298
299   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
300   double_colon_index = ARRAY_LEN (hex_quads);
301   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
302     {
303       hex_digit = 16;
304       if (c >= '0' && c <= '9')
305         hex_digit = c - '0';
306       else if (c >= 'a' && c <= 'f')
307         hex_digit = c + 10 - 'a';
308       else if (c >= 'A' && c <= 'F')
309         hex_digit = c + 10 - 'A';
310       else if (c == ':' && n_colon < 2)
311         n_colon++;
312       else
313         {
314           unformat_put_input (input);
315           break;
316         }
317
318       /* Too many hex quads. */
319       if (n_hex_quads >= ARRAY_LEN (hex_quads))
320         return 0;
321
322       if (hex_digit < 16)
323         {
324           hex_quad = (hex_quad << 4) | hex_digit;
325
326           /* Hex quad must fit in 16 bits. */
327           if (n_hex_digits >= 4)
328             return 0;
329
330           n_colon = 0;
331           n_hex_digits++;
332         }
333
334       /* Save position of :: */
335       if (n_colon == 2)
336         {
337           /* More than one :: ? */
338           if (double_colon_index < ARRAY_LEN (hex_quads))
339             return 0;
340           double_colon_index = n_hex_quads;
341         }
342
343       if (n_colon > 0 && n_hex_digits > 0)
344         {
345           hex_quads[n_hex_quads++] = hex_quad;
346           hex_quad = 0;
347           n_hex_digits = 0;
348         }
349     }
350
351   if (n_hex_digits > 0)
352     hex_quads[n_hex_quads++] = hex_quad;
353
354   {
355     word i;
356
357     /* Expand :: to appropriate number of zero hex quads. */
358     if (double_colon_index < ARRAY_LEN (hex_quads))
359       {
360         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
361
362         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
363           hex_quads[n_zero + i] = hex_quads[i];
364
365         for (i = 0; i < n_zero; i++)
366           hex_quads[double_colon_index + i] = 0;
367
368         n_hex_quads = ARRAY_LEN (hex_quads);
369       }
370
371     /* Too few hex quads given. */
372     if (n_hex_quads < ARRAY_LEN (hex_quads))
373       return 0;
374
375     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
376       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
377
378     return 1;
379   }
380 }
381
382 uword
383 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
384 {
385   u32 *r = va_arg (*args, u32 *);
386
387   if (0);
388 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
389   foreach_ipsec_policy_action
390 #undef _
391     else
392     return 0;
393   return 1;
394 }
395
396 u8 *
397 format_ipsec_crypto_alg (u8 * s, va_list * args)
398 {
399   u32 i = va_arg (*args, u32);
400   u8 *t = 0;
401
402   switch (i)
403     {
404 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
405       foreach_ipsec_crypto_alg
406 #undef _
407     default:
408       return format (s, "unknown");
409     }
410   return format (s, "%s", t);
411 }
412
413 u8 *
414 format_ipsec_integ_alg (u8 * s, va_list * args)
415 {
416   u32 i = va_arg (*args, u32);
417   u8 *t = 0;
418
419   switch (i)
420     {
421 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
422       foreach_ipsec_integ_alg
423 #undef _
424     default:
425       return format (s, "unknown");
426     }
427   return format (s, "%s", t);
428 }
429
430 #else /* VPP_API_TEST_BUILTIN == 1 */
431 static uword
432 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
433 {
434   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
435   vnet_main_t *vnm = vnet_get_main ();
436   u32 *result = va_arg (*args, u32 *);
437
438   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
439 }
440
441 static uword
442 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
443 {
444   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
445   vnet_main_t *vnm = vnet_get_main ();
446   u32 *result = va_arg (*args, u32 *);
447
448   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
449 }
450
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 uword
454 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
455 {
456   u32 *r = va_arg (*args, u32 *);
457
458   if (0);
459 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
460   foreach_ipsec_crypto_alg
461 #undef _
462     else
463     return 0;
464   return 1;
465 }
466
467 uword
468 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
469 {
470   u32 *r = va_arg (*args, u32 *);
471
472   if (0);
473 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
474   foreach_ipsec_integ_alg
475 #undef _
476     else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "kbps"))
487     *r = SSE2_QOS_RATE_KBPS;
488   else if (unformat (input, "pps"))
489     *r = SSE2_QOS_RATE_PPS;
490   else
491     return 0;
492   return 1;
493 }
494
495 static uword
496 unformat_policer_round_type (unformat_input_t * input, va_list * args)
497 {
498   u8 *r = va_arg (*args, u8 *);
499
500   if (unformat (input, "closest"))
501     *r = SSE2_QOS_ROUND_TO_CLOSEST;
502   else if (unformat (input, "up"))
503     *r = SSE2_QOS_ROUND_TO_UP;
504   else if (unformat (input, "down"))
505     *r = SSE2_QOS_ROUND_TO_DOWN;
506   else
507     return 0;
508   return 1;
509 }
510
511 static uword
512 unformat_policer_type (unformat_input_t * input, va_list * args)
513 {
514   u8 *r = va_arg (*args, u8 *);
515
516   if (unformat (input, "1r2c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R2C;
518   else if (unformat (input, "1r3c"))
519     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
520   else if (unformat (input, "2r3c-2698"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
522   else if (unformat (input, "2r3c-4115"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
524   else if (unformat (input, "2r3c-mef5cf1"))
525     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
526   else
527     return 0;
528   return 1;
529 }
530
531 static uword
532 unformat_dscp (unformat_input_t * input, va_list * va)
533 {
534   u8 *r = va_arg (*va, u8 *);
535
536   if (0);
537 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
538   foreach_vnet_dscp
539 #undef _
540     else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_action_type (unformat_input_t * input, va_list * va)
547 {
548   sse2_qos_pol_action_params_st *a
549     = va_arg (*va, sse2_qos_pol_action_params_st *);
550
551   if (unformat (input, "drop"))
552     a->action_type = SSE2_QOS_ACTION_DROP;
553   else if (unformat (input, "transmit"))
554     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
555   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
556     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
557   else
558     return 0;
559   return 1;
560 }
561
562 static uword
563 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
564 {
565   u32 *r = va_arg (*va, u32 *);
566   u32 tid;
567
568   if (unformat (input, "ip4"))
569     tid = POLICER_CLASSIFY_TABLE_IP4;
570   else if (unformat (input, "ip6"))
571     tid = POLICER_CLASSIFY_TABLE_IP6;
572   else if (unformat (input, "l2"))
573     tid = POLICER_CLASSIFY_TABLE_L2;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static uword
582 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
583 {
584   u32 *r = va_arg (*va, u32 *);
585   u32 tid;
586
587   if (unformat (input, "ip4"))
588     tid = FLOW_CLASSIFY_TABLE_IP4;
589   else if (unformat (input, "ip6"))
590     tid = FLOW_CLASSIFY_TABLE_IP6;
591   else
592     return 0;
593
594   *r = tid;
595   return 1;
596 }
597
598 #if (VPP_API_TEST_BUILTIN==0)
599
600 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
601 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
602 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
603 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
604
605 uword
606 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
607 {
608   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
609   mfib_itf_attribute_t attr;
610
611   old = *iflags;
612   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613   {
614     if (unformat (input, mfib_itf_flag_long_names[attr]))
615       *iflags |= (1 << attr);
616   }
617   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
618   {
619     if (unformat (input, mfib_itf_flag_names[attr]))
620       *iflags |= (1 << attr);
621   }
622
623   return (old == *iflags ? 0 : 1);
624 }
625
626 uword
627 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
628 {
629   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
630   mfib_entry_attribute_t attr;
631
632   old = *eflags;
633   FOR_EACH_MFIB_ATTRIBUTE (attr)
634   {
635     if (unformat (input, mfib_flag_long_names[attr]))
636       *eflags |= (1 << attr);
637   }
638   FOR_EACH_MFIB_ATTRIBUTE (attr)
639   {
640     if (unformat (input, mfib_flag_names[attr]))
641       *eflags |= (1 << attr);
642   }
643
644   return (old == *eflags ? 0 : 1);
645 }
646
647 u8 *
648 format_ip4_address (u8 * s, va_list * args)
649 {
650   u8 *a = va_arg (*args, u8 *);
651   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
652 }
653
654 u8 *
655 format_ip6_address (u8 * s, va_list * args)
656 {
657   ip6_address_t *a = va_arg (*args, ip6_address_t *);
658   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
659
660   i_max_n_zero = ARRAY_LEN (a->as_u16);
661   max_n_zeros = 0;
662   i_first_zero = i_max_n_zero;
663   n_zeros = 0;
664   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
665     {
666       u32 is_zero = a->as_u16[i] == 0;
667       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
668         {
669           i_first_zero = i;
670           n_zeros = 0;
671         }
672       n_zeros += is_zero;
673       if ((!is_zero && n_zeros > max_n_zeros)
674           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
675         {
676           i_max_n_zero = i_first_zero;
677           max_n_zeros = n_zeros;
678           i_first_zero = ARRAY_LEN (a->as_u16);
679           n_zeros = 0;
680         }
681     }
682
683   last_double_colon = 0;
684   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
685     {
686       if (i == i_max_n_zero && max_n_zeros > 1)
687         {
688           s = format (s, "::");
689           i += max_n_zeros - 1;
690           last_double_colon = 1;
691         }
692       else
693         {
694           s = format (s, "%s%x",
695                       (last_double_colon || i == 0) ? "" : ":",
696                       clib_net_to_host_u16 (a->as_u16[i]));
697           last_double_colon = 0;
698         }
699     }
700
701   return s;
702 }
703
704 /* Format an IP46 address. */
705 u8 *
706 format_ip46_address (u8 * s, va_list * args)
707 {
708   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
709   ip46_type_t type = va_arg (*args, ip46_type_t);
710   int is_ip4 = 1;
711
712   switch (type)
713     {
714     case IP46_TYPE_ANY:
715       is_ip4 = ip46_address_is_ip4 (ip46);
716       break;
717     case IP46_TYPE_IP4:
718       is_ip4 = 1;
719       break;
720     case IP46_TYPE_IP6:
721       is_ip4 = 0;
722       break;
723     }
724
725   return is_ip4 ?
726     format (s, "%U", format_ip4_address, &ip46->ip4) :
727     format (s, "%U", format_ip6_address, &ip46->ip6);
728 }
729
730 u8 *
731 format_ethernet_address (u8 * s, va_list * args)
732 {
733   u8 *a = va_arg (*args, u8 *);
734
735   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
736                  a[0], a[1], a[2], a[3], a[4], a[5]);
737 }
738 #endif
739
740 static void
741 increment_v4_address (vl_api_ip4_address_t * i)
742 {
743   ip4_address_t *a = (ip4_address_t *) i;
744   u32 v;
745
746   v = ntohl (a->as_u32) + 1;
747   a->as_u32 = ntohl (v);
748 }
749
750 static void
751 increment_v6_address (vl_api_ip6_address_t * i)
752 {
753   ip6_address_t *a = (ip6_address_t *) i;
754   u64 v0, v1;
755
756   v0 = clib_net_to_host_u64 (a->as_u64[0]);
757   v1 = clib_net_to_host_u64 (a->as_u64[1]);
758
759   v1 += 1;
760   if (v1 == 0)
761     v0 += 1;
762   a->as_u64[0] = clib_net_to_host_u64 (v0);
763   a->as_u64[1] = clib_net_to_host_u64 (v1);
764 }
765
766 static void
767 increment_address (vl_api_address_t * a)
768 {
769   if (a->af == ADDRESS_IP4)
770     increment_v4_address (&a->un.ip4);
771   else if (a->af == ADDRESS_IP6)
772     increment_v6_address (&a->un.ip6);
773 }
774
775 static void
776 set_ip4_address (vl_api_address_t * a, u32 v)
777 {
778   if (a->af == ADDRESS_IP4)
779     {
780       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
781       i->as_u32 = v;
782     }
783 }
784
785 void
786 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
787 {
788   if (is_ip4)
789     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
790   else
791     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
792                       sizeof (ip6_address_t));
793 }
794
795 static void
796 increment_mac_address (u8 * mac)
797 {
798   u64 tmp = *((u64 *) mac);
799   tmp = clib_net_to_host_u64 (tmp);
800   tmp += 1 << 16;               /* skip unused (least significant) octets */
801   tmp = clib_host_to_net_u64 (tmp);
802
803   clib_memcpy (mac, &tmp, 6);
804 }
805
806 static void
807 vat_json_object_add_address (vat_json_node_t * node,
808                              const char *str, const vl_api_address_t * addr)
809 {
810   if (ADDRESS_IP6 == addr->af)
811     {
812       struct in6_addr ip6;
813
814       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
815       vat_json_object_add_ip6 (node, str, ip6);
816     }
817   else
818     {
819       struct in_addr ip4;
820
821       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
822       vat_json_object_add_ip4 (node, str, ip4);
823     }
824 }
825
826 static void
827 vat_json_object_add_prefix (vat_json_node_t * node,
828                             const vl_api_prefix_t * prefix)
829 {
830   vat_json_object_add_uint (node, "len", prefix->len);
831   vat_json_object_add_address (node, "address", &prefix->address);
832 }
833
834 static void vl_api_create_loopback_reply_t_handler
835   (vl_api_create_loopback_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   i32 retval = ntohl (mp->retval);
839
840   vam->retval = retval;
841   vam->regenerate_interface_table = 1;
842   vam->sw_if_index = ntohl (mp->sw_if_index);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_loopback_reply_t_handler_json
847   (vl_api_create_loopback_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   vat_json_node_t node;
851
852   vat_json_init_object (&node);
853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
855
856   vat_json_print (vam->ofp, &node);
857   vat_json_free (&node);
858   vam->retval = ntohl (mp->retval);
859   vam->result_ready = 1;
860 }
861
862 static void vl_api_create_loopback_instance_reply_t_handler
863   (vl_api_create_loopback_instance_reply_t * mp)
864 {
865   vat_main_t *vam = &vat_main;
866   i32 retval = ntohl (mp->retval);
867
868   vam->retval = retval;
869   vam->regenerate_interface_table = 1;
870   vam->sw_if_index = ntohl (mp->sw_if_index);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_loopback_instance_reply_t_handler_json
875   (vl_api_create_loopback_instance_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   vat_json_node_t node;
879
880   vat_json_init_object (&node);
881   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
882   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
883
884   vat_json_print (vam->ofp, &node);
885   vat_json_free (&node);
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void vl_api_af_packet_create_reply_t_handler
891   (vl_api_af_packet_create_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->regenerate_interface_table = 1;
898   vam->sw_if_index = ntohl (mp->sw_if_index);
899   vam->result_ready = 1;
900 }
901
902 static void vl_api_af_packet_create_reply_t_handler_json
903   (vl_api_af_packet_create_reply_t * mp)
904 {
905   vat_main_t *vam = &vat_main;
906   vat_json_node_t node;
907
908   vat_json_init_object (&node);
909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
911
912   vat_json_print (vam->ofp, &node);
913   vat_json_free (&node);
914
915   vam->retval = ntohl (mp->retval);
916   vam->result_ready = 1;
917 }
918
919 static void vl_api_create_vlan_subif_reply_t_handler
920   (vl_api_create_vlan_subif_reply_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   i32 retval = ntohl (mp->retval);
924
925   vam->retval = retval;
926   vam->regenerate_interface_table = 1;
927   vam->sw_if_index = ntohl (mp->sw_if_index);
928   vam->result_ready = 1;
929 }
930
931 static void vl_api_create_vlan_subif_reply_t_handler_json
932   (vl_api_create_vlan_subif_reply_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   vat_json_node_t node;
936
937   vat_json_init_object (&node);
938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
939   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
940
941   vat_json_print (vam->ofp, &node);
942   vat_json_free (&node);
943
944   vam->retval = ntohl (mp->retval);
945   vam->result_ready = 1;
946 }
947
948 static void vl_api_create_subif_reply_t_handler
949   (vl_api_create_subif_reply_t * mp)
950 {
951   vat_main_t *vam = &vat_main;
952   i32 retval = ntohl (mp->retval);
953
954   vam->retval = retval;
955   vam->regenerate_interface_table = 1;
956   vam->sw_if_index = ntohl (mp->sw_if_index);
957   vam->result_ready = 1;
958 }
959
960 static void vl_api_create_subif_reply_t_handler_json
961   (vl_api_create_subif_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965
966   vat_json_init_object (&node);
967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
968   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void vl_api_interface_name_renumber_reply_t_handler
978   (vl_api_interface_name_renumber_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->regenerate_interface_table = 1;
985   vam->result_ready = 1;
986 }
987
988 static void vl_api_interface_name_renumber_reply_t_handler_json
989   (vl_api_interface_name_renumber_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996
997   vat_json_print (vam->ofp, &node);
998   vat_json_free (&node);
999
1000   vam->retval = ntohl (mp->retval);
1001   vam->result_ready = 1;
1002 }
1003
1004 /*
1005  * Special-case: build the interface table, maintain
1006  * the next loopback sw_if_index vbl.
1007  */
1008 static void vl_api_sw_interface_details_t_handler
1009   (vl_api_sw_interface_details_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1013
1014   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1015                 ntohl (mp->sw_if_index));
1016
1017   /* In sub interface case, fill the sub interface table entry */
1018   if (mp->sw_if_index != mp->sup_sw_if_index)
1019     {
1020       sw_interface_subif_t *sub = NULL;
1021
1022       vec_add2 (vam->sw_if_subif_table, sub, 1);
1023
1024       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1025       strncpy ((char *) sub->interface_name, (char *) s,
1026                vec_len (sub->interface_name));
1027       sub->sw_if_index = ntohl (mp->sw_if_index);
1028       sub->sub_id = ntohl (mp->sub_id);
1029
1030       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1031
1032       sub->sub_number_of_tags = mp->sub_number_of_tags;
1033       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1034       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1035
1036       /* vlan tag rewrite */
1037       sub->vtr_op = ntohl (mp->vtr_op);
1038       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1039       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1040       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1041     }
1042 }
1043
1044 static void vl_api_sw_interface_details_t_handler_json
1045   (vl_api_sw_interface_details_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t *node = NULL;
1049
1050   if (VAT_JSON_ARRAY != vam->json_tree.type)
1051     {
1052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1053       vat_json_init_array (&vam->json_tree);
1054     }
1055   node = vat_json_array_add (&vam->json_tree);
1056
1057   vat_json_init_object (node);
1058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1059   vat_json_object_add_uint (node, "sup_sw_if_index",
1060                             ntohl (mp->sup_sw_if_index));
1061   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1062                              sizeof (mp->l2_address));
1063   vat_json_object_add_string_copy (node, "interface_name",
1064                                    mp->interface_name);
1065   vat_json_object_add_string_copy (node, "interface_dev_type",
1066                                    mp->interface_dev_type);
1067   vat_json_object_add_uint (node, "flags", mp->flags);
1068   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1069   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1070   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1071   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1072   vat_json_object_add_uint (node, "sub_number_of_tags",
1073                             mp->sub_number_of_tags);
1074   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1075                             ntohs (mp->sub_outer_vlan_id));
1076   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1077                             ntohs (mp->sub_inner_vlan_id));
1078   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1079   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1080   vat_json_object_add_uint (node, "vtr_push_dot1q",
1081                             ntohl (mp->vtr_push_dot1q));
1082   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1083   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1084   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1085     {
1086       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_dmac));
1090       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1091                                        format (0, "%U",
1092                                                format_ethernet_address,
1093                                                &mp->b_smac));
1094       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1095       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1096     }
1097 }
1098
1099 #if VPP_API_TEST_BUILTIN == 0
1100 static void vl_api_sw_interface_event_t_handler
1101   (vl_api_sw_interface_event_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   if (vam->interface_event_display)
1105     errmsg ("interface flags: sw_if_index %d %s %s",
1106             ntohl (mp->sw_if_index),
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1108             "admin-up" : "admin-down",
1109             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1110             "link-up" : "link-down");
1111 }
1112 #endif
1113
1114 __clib_unused static void
1115 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1116 {
1117   /* JSON output not supported */
1118 }
1119
1120 static void
1121 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   i32 retval = ntohl (mp->retval);
1125
1126   vam->retval = retval;
1127   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136   void *oldheap;
1137   u8 *reply;
1138
1139   vat_json_init_object (&node);
1140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141   vat_json_object_add_uint (&node, "reply_in_shmem",
1142                             ntohl (mp->reply_in_shmem));
1143   /* Toss the shared-memory original... */
1144   oldheap = vl_msg_push_heap ();
1145
1146   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1147   vec_free (reply);
1148
1149   vl_msg_pop_heap (oldheap);
1150
1151   vat_json_print (vam->ofp, &node);
1152   vat_json_free (&node);
1153
1154   vam->retval = ntohl (mp->retval);
1155   vam->result_ready = 1;
1156 }
1157
1158 static void
1159 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   i32 retval = ntohl (mp->retval);
1163
1164   vec_reset_length (vam->cmd_reply);
1165
1166   vam->retval = retval;
1167   if (retval == 0)
1168     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void
1173 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177   u8 *reply = 0;                /* reply vector */
1178
1179   reply = vl_api_from_api_to_new_vec (&mp->reply);
1180   vec_reset_length (vam->cmd_reply);
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "reply", reply);
1185
1186   vat_json_print (vam->ofp, &node);
1187   vat_json_free (&node);
1188   vec_free (reply);
1189
1190   vam->retval = ntohl (mp->retval);
1191   vam->result_ready = 1;
1192 }
1193
1194 static void vl_api_classify_add_del_table_reply_t_handler
1195   (vl_api_classify_add_del_table_reply_t * mp)
1196 {
1197   vat_main_t *vam = &vat_main;
1198   i32 retval = ntohl (mp->retval);
1199   if (vam->async_mode)
1200     {
1201       vam->async_errors += (retval < 0);
1202     }
1203   else
1204     {
1205       vam->retval = retval;
1206       if (retval == 0 &&
1207           ((mp->new_table_index != 0xFFFFFFFF) ||
1208            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1209            (mp->match_n_vectors != 0xFFFFFFFF)))
1210         /*
1211          * Note: this is just barely thread-safe, depends on
1212          * the main thread spinning waiting for an answer...
1213          */
1214         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1215                 ntohl (mp->new_table_index),
1216                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_classify_add_del_table_reply_t_handler_json
1222   (vl_api_classify_add_del_table_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "new_table_index",
1230                             ntohl (mp->new_table_index));
1231   vat_json_object_add_uint (&node, "skip_n_vectors",
1232                             ntohl (mp->skip_n_vectors));
1233   vat_json_object_add_uint (&node, "match_n_vectors",
1234                             ntohl (mp->match_n_vectors));
1235
1236   vat_json_print (vam->ofp, &node);
1237   vat_json_free (&node);
1238
1239   vam->retval = ntohl (mp->retval);
1240   vam->result_ready = 1;
1241 }
1242
1243 static void vl_api_get_node_index_reply_t_handler
1244   (vl_api_get_node_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   i32 retval = ntohl (mp->retval);
1248   if (vam->async_mode)
1249     {
1250       vam->async_errors += (retval < 0);
1251     }
1252   else
1253     {
1254       vam->retval = retval;
1255       if (retval == 0)
1256         errmsg ("node index %d", ntohl (mp->node_index));
1257       vam->result_ready = 1;
1258     }
1259 }
1260
1261 static void vl_api_get_node_index_reply_t_handler_json
1262   (vl_api_get_node_index_reply_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t node;
1266
1267   vat_json_init_object (&node);
1268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1269   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1270
1271   vat_json_print (vam->ofp, &node);
1272   vat_json_free (&node);
1273
1274   vam->retval = ntohl (mp->retval);
1275   vam->result_ready = 1;
1276 }
1277
1278 static void vl_api_get_next_index_reply_t_handler
1279   (vl_api_get_next_index_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       if (retval == 0)
1291         errmsg ("next node index %d", ntohl (mp->next_index));
1292       vam->result_ready = 1;
1293     }
1294 }
1295
1296 static void vl_api_get_next_index_reply_t_handler_json
1297   (vl_api_get_next_index_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   vat_json_node_t node;
1301
1302   vat_json_init_object (&node);
1303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1304   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1305
1306   vat_json_print (vam->ofp, &node);
1307   vat_json_free (&node);
1308
1309   vam->retval = ntohl (mp->retval);
1310   vam->result_ready = 1;
1311 }
1312
1313 static void vl_api_add_node_next_reply_t_handler
1314   (vl_api_add_node_next_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       if (retval == 0)
1326         errmsg ("next index %d", ntohl (mp->next_index));
1327       vam->result_ready = 1;
1328     }
1329 }
1330
1331 static void vl_api_add_node_next_reply_t_handler_json
1332   (vl_api_add_node_next_reply_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t node;
1336
1337   vat_json_init_object (&node);
1338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1340
1341   vat_json_print (vam->ofp, &node);
1342   vat_json_free (&node);
1343
1344   vam->retval = ntohl (mp->retval);
1345   vam->result_ready = 1;
1346 }
1347
1348 static void vl_api_show_version_reply_t_handler
1349   (vl_api_show_version_reply_t * mp)
1350 {
1351   vat_main_t *vam = &vat_main;
1352   i32 retval = ntohl (mp->retval);
1353
1354   if (retval >= 0)
1355     {
1356       errmsg ("        program: %s", mp->program);
1357       errmsg ("        version: %s", mp->version);
1358       errmsg ("     build date: %s", mp->build_date);
1359       errmsg ("build directory: %s", mp->build_directory);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   vat_json_object_add_string_copy (&node, "program", mp->program);
1374   vat_json_object_add_string_copy (&node, "version", mp->version);
1375   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1376   vat_json_object_add_string_copy (&node, "build_directory",
1377                                    mp->build_directory);
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   int i, count = 0;
1392
1393   if (retval >= 0)
1394     count = ntohl (mp->count);
1395
1396   for (i = 0; i < count; i++)
1397     print (vam->ofp,
1398            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1399            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1400            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1401            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1402            ntohl (mp->thread_data[i].cpu_socket));
1403
1404   vam->retval = retval;
1405   vam->result_ready = 1;
1406 }
1407
1408 static void vl_api_show_threads_reply_t_handler_json
1409   (vl_api_show_threads_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t node;
1413   vl_api_thread_data_t *td;
1414   i32 retval = ntohl (mp->retval);
1415   int i, count = 0;
1416
1417   if (retval >= 0)
1418     count = ntohl (mp->count);
1419
1420   vat_json_init_object (&node);
1421   vat_json_object_add_int (&node, "retval", retval);
1422   vat_json_object_add_uint (&node, "count", count);
1423
1424   for (i = 0; i < count; i++)
1425     {
1426       td = &mp->thread_data[i];
1427       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1428       vat_json_object_add_string_copy (&node, "name", td->name);
1429       vat_json_object_add_string_copy (&node, "type", td->type);
1430       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1431       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1432       vat_json_object_add_int (&node, "core", ntohl (td->id));
1433       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1434     }
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = retval;
1440   vam->result_ready = 1;
1441 }
1442
1443 static int
1444 api_show_threads (vat_main_t * vam)
1445 {
1446   vl_api_show_threads_t *mp;
1447   int ret;
1448
1449   print (vam->ofp,
1450          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1451          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1452
1453   M (SHOW_THREADS, mp);
1454
1455   S (mp);
1456   W (ret);
1457   return ret;
1458 }
1459
1460 static void
1461 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462 {
1463   u32 n_macs = ntohl (mp->n_macs);
1464   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465           ntohl (mp->pid), mp->client_index, n_macs);
1466   int i;
1467   for (i = 0; i < n_macs; i++)
1468     {
1469       vl_api_mac_entry_t *mac = &mp->mac[i];
1470       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471               i + 1, ntohl (mac->sw_if_index),
1472               format_ethernet_address, mac->mac_addr, mac->action);
1473       if (i == 1000)
1474         break;
1475     }
1476 }
1477
1478 static void
1479 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487 /*
1488  * Special-case: build the bridge domain table, maintain
1489  * the next bd id vbl.
1490  */
1491 static void vl_api_bridge_domain_details_t_handler
1492   (vl_api_bridge_domain_details_t * mp)
1493 {
1494   vat_main_t *vam = &vat_main;
1495   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496   int i;
1497
1498   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502          ntohl (mp->bd_id), mp->learn, mp->forward,
1503          mp->flood, ntohl (mp->bvi_sw_if_index),
1504          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506   if (n_sw_ifs)
1507     {
1508       vl_api_bridge_domain_sw_if_t *sw_ifs;
1509       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510              "Interface Name");
1511
1512       sw_ifs = mp->sw_if_details;
1513       for (i = 0; i < n_sw_ifs; i++)
1514         {
1515           u8 *sw_if_name = 0;
1516           u32 sw_if_index;
1517           hash_pair_t *p;
1518
1519           sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521           /* *INDENT-OFF* */
1522           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523                              ({
1524                                if ((u32) p->value[0] == sw_if_index)
1525                                  {
1526                                    sw_if_name = (u8 *)(p->key);
1527                                    break;
1528                                  }
1529                              }));
1530           /* *INDENT-ON* */
1531           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533                  "sw_if_index not found!");
1534
1535           sw_ifs++;
1536         }
1537     }
1538 }
1539
1540 static void vl_api_bridge_domain_details_t_handler_json
1541   (vl_api_bridge_domain_details_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t *node, *array = NULL;
1545   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547   if (VAT_JSON_ARRAY != vam->json_tree.type)
1548     {
1549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550       vat_json_init_array (&vam->json_tree);
1551     }
1552   node = vat_json_array_add (&vam->json_tree);
1553
1554   vat_json_init_object (node);
1555   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556   vat_json_object_add_uint (node, "flood", mp->flood);
1557   vat_json_object_add_uint (node, "forward", mp->forward);
1558   vat_json_object_add_uint (node, "learn", mp->learn);
1559   vat_json_object_add_uint (node, "bvi_sw_if_index",
1560                             ntohl (mp->bvi_sw_if_index));
1561   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562   array = vat_json_object_add (node, "sw_if");
1563   vat_json_init_array (array);
1564
1565
1566
1567   if (n_sw_ifs)
1568     {
1569       vl_api_bridge_domain_sw_if_t *sw_ifs;
1570       int i;
1571
1572       sw_ifs = mp->sw_if_details;
1573       for (i = 0; i < n_sw_ifs; i++)
1574         {
1575           node = vat_json_array_add (array);
1576           vat_json_init_object (node);
1577           vat_json_object_add_uint (node, "sw_if_index",
1578                                     ntohl (sw_ifs->sw_if_index));
1579           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580           sw_ifs++;
1581         }
1582     }
1583 }
1584
1585 static void vl_api_control_ping_reply_t_handler
1586   (vl_api_control_ping_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->result_ready = 1;
1598     }
1599   if (vam->socket_client_main)
1600     vam->socket_client_main->control_pings_outstanding--;
1601 }
1602
1603 static void vl_api_control_ping_reply_t_handler_json
1604   (vl_api_control_ping_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608
1609   if (VAT_JSON_NONE != vam->json_tree.type)
1610     {
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vat_json_free (&vam->json_tree);
1613       vam->json_tree.type = VAT_JSON_NONE;
1614     }
1615   else
1616     {
1617       /* just print [] */
1618       vat_json_init_array (&vam->json_tree);
1619       vat_json_print (vam->ofp, &vam->json_tree);
1620       vam->json_tree.type = VAT_JSON_NONE;
1621     }
1622
1623   vam->retval = retval;
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628   vl_api_bridge_domain_set_mac_age_reply_t_handler
1629   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void
1661 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_l2_flags_reply_t_handler_json
1677   (vl_api_l2_flags_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685                             ntohl (mp->resulting_feature_bitmap));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_bridge_flags_reply_t_handler
1695   (vl_api_bridge_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_bridge_flags_reply_t_handler_json
1711   (vl_api_bridge_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void
1729 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743
1744 }
1745
1746 static void vl_api_tap_create_v2_reply_t_handler_json
1747   (vl_api_tap_create_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761
1762 }
1763
1764 static void
1765 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_tap_delete_v2_reply_t_handler_json
1781   (vl_api_tap_delete_v2_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788
1789   vat_json_print (vam->ofp, &node);
1790   vat_json_free (&node);
1791
1792   vam->retval = ntohl (mp->retval);
1793   vam->result_ready = 1;
1794 }
1795
1796 static void
1797 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1798                                           mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   i32 retval = ntohl (mp->retval);
1802   if (vam->async_mode)
1803     {
1804       vam->async_errors += (retval < 0);
1805     }
1806   else
1807     {
1808       vam->retval = retval;
1809       vam->sw_if_index = ntohl (mp->sw_if_index);
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_virtio_pci_create_reply_t_handler_json
1815   (vl_api_virtio_pci_create_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1823
1824   vat_json_print (vam->ofp, &node);
1825   vat_json_free (&node);
1826
1827   vam->retval = ntohl (mp->retval);
1828   vam->result_ready = 1;
1829
1830 }
1831
1832 static void
1833 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1834                                           mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_delete_reply_t_handler_json
1850   (vl_api_virtio_pci_delete_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863 }
1864
1865 static void
1866 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   i32 retval = ntohl (mp->retval);
1870
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_bond_create_reply_t_handler_json
1884   (vl_api_bond_create_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void
1901 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   i32 retval = ntohl (mp->retval);
1905
1906   if (vam->async_mode)
1907     {
1908       vam->async_errors += (retval < 0);
1909     }
1910   else
1911     {
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_delete_reply_t_handler_json
1918   (vl_api_bond_delete_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_enslave_reply_t_handler_json
1951   (vl_api_bond_enslave_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1968                                           mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_detach_slave_reply_t_handler_json
1985   (vl_api_bond_detach_slave_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static int
2001 api_sw_interface_set_bond_weight (vat_main_t * vam)
2002 {
2003   unformat_input_t *i = vam->input;
2004   vl_api_sw_interface_set_bond_weight_t *mp;
2005   u32 sw_if_index = ~0;
2006   u32 weight = 0;
2007   u8 weight_enter = 0;
2008   int ret;
2009
2010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2011     {
2012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2013         ;
2014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2015         ;
2016       else if (unformat (i, "weight %u", &weight))
2017         weight_enter = 1;
2018       else
2019         break;
2020     }
2021
2022   if (sw_if_index == ~0)
2023     {
2024       errmsg ("missing interface name or sw_if_index");
2025       return -99;
2026     }
2027   if (weight_enter == 0)
2028     {
2029       errmsg ("missing valid weight");
2030       return -99;
2031     }
2032
2033   /* Construct the API message */
2034   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2035   mp->sw_if_index = ntohl (sw_if_index);
2036   mp->weight = ntohl (weight);
2037
2038   S (mp);
2039   W (ret);
2040   return ret;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2052          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2073   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2110          ntohl (mp->weight), mp->is_local_numa);
2111 }
2112
2113 static void vl_api_sw_interface_slave_details_t_handler_json
2114   (vl_api_sw_interface_slave_details_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vat_json_node_t *node = NULL;
2118
2119   if (VAT_JSON_ARRAY != vam->json_tree.type)
2120     {
2121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122       vat_json_init_array (&vam->json_tree);
2123     }
2124   node = vat_json_array_add (&vam->json_tree);
2125
2126   vat_json_init_object (node);
2127   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128   vat_json_object_add_string_copy (node, "interface_name",
2129                                    mp->interface_name);
2130   vat_json_object_add_uint (node, "passive", mp->is_passive);
2131   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2132   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2133   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2134 }
2135
2136 static int
2137 api_sw_interface_slave_dump (vat_main_t * vam)
2138 {
2139   unformat_input_t *i = vam->input;
2140   vl_api_sw_interface_slave_dump_t *mp;
2141   vl_api_control_ping_t *mp_ping;
2142   u32 sw_if_index = ~0;
2143   u8 sw_if_index_set = 0;
2144   int ret;
2145
2146   /* Parse args required to build the message */
2147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2148     {
2149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2150         sw_if_index_set = 1;
2151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2152         sw_if_index_set = 1;
2153       else
2154         break;
2155     }
2156
2157   if (sw_if_index_set == 0)
2158     {
2159       errmsg ("missing vpp interface name. ");
2160       return -99;
2161     }
2162
2163   print (vam->ofp,
2164          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2165          "slave interface name", "sw_if_index", "passive", "long_timeout",
2166          "weight", "local numa");
2167
2168   /* Get list of bond interfaces */
2169   M (SW_INTERFACE_SLAVE_DUMP, mp);
2170   mp->sw_if_index = ntohl (sw_if_index);
2171   S (mp);
2172
2173   /* Use a control ping for synchronization */
2174   MPING (CONTROL_PING, mp_ping);
2175   S (mp_ping);
2176
2177   W (ret);
2178   return ret;
2179 }
2180
2181 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2182   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->sw_if_index = ntohl (mp->sw_if_index);
2194       vam->result_ready = 1;
2195     }
2196   vam->regenerate_interface_table = 1;
2197 }
2198
2199 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2200   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2208                             ntohl (mp->sw_if_index));
2209
2210   vat_json_print (vam->ofp, &node);
2211   vat_json_free (&node);
2212
2213   vam->retval = ntohl (mp->retval);
2214   vam->result_ready = 1;
2215 }
2216
2217 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2218   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2219 {
2220   vat_main_t *vam = &vat_main;
2221   i32 retval = ntohl (mp->retval);
2222   if (vam->async_mode)
2223     {
2224       vam->async_errors += (retval < 0);
2225     }
2226   else
2227     {
2228       vam->retval = retval;
2229       vam->sw_if_index = ntohl (mp->sw_if_index);
2230       vam->result_ready = 1;
2231     }
2232 }
2233
2234 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2235   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2236 {
2237   vat_main_t *vam = &vat_main;
2238   vat_json_node_t node;
2239
2240   vat_json_init_object (&node);
2241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2252   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   i32 retval = ntohl (mp->retval);
2256   if (vam->async_mode)
2257     {
2258       vam->async_errors += (retval < 0);
2259     }
2260   else
2261     {
2262       vam->retval = retval;
2263       vam->result_ready = 1;
2264     }
2265 }
2266
2267 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2268   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   vat_json_node_t node;
2272
2273   vat_json_init_object (&node);
2274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2275   vat_json_object_add_uint (&node, "fwd_entry_index",
2276                             clib_net_to_host_u32 (mp->fwd_entry_index));
2277
2278   vat_json_print (vam->ofp, &node);
2279   vat_json_free (&node);
2280
2281   vam->retval = ntohl (mp->retval);
2282   vam->result_ready = 1;
2283 }
2284
2285 u8 *
2286 format_lisp_transport_protocol (u8 * s, va_list * args)
2287 {
2288   u32 proto = va_arg (*args, u32);
2289
2290   switch (proto)
2291     {
2292     case 1:
2293       return format (s, "udp");
2294     case 2:
2295       return format (s, "api");
2296     default:
2297       return 0;
2298     }
2299   return 0;
2300 }
2301
2302 static void vl_api_one_get_transport_protocol_reply_t_handler
2303   (vl_api_one_get_transport_protocol_reply_t * mp)
2304 {
2305   vat_main_t *vam = &vat_main;
2306   i32 retval = ntohl (mp->retval);
2307   if (vam->async_mode)
2308     {
2309       vam->async_errors += (retval < 0);
2310     }
2311   else
2312     {
2313       u32 proto = mp->protocol;
2314       print (vam->ofp, "Transport protocol: %U",
2315              format_lisp_transport_protocol, proto);
2316       vam->retval = retval;
2317       vam->result_ready = 1;
2318     }
2319 }
2320
2321 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2322   (vl_api_one_get_transport_protocol_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t node;
2326   u8 *s;
2327
2328   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2329   vec_add1 (s, 0);
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2334
2335   vec_free (s);
2336   vat_json_print (vam->ofp, &node);
2337   vat_json_free (&node);
2338
2339   vam->retval = ntohl (mp->retval);
2340   vam->result_ready = 1;
2341 }
2342
2343 static void vl_api_one_add_del_locator_set_reply_t_handler
2344   (vl_api_one_add_del_locator_set_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   i32 retval = ntohl (mp->retval);
2348   if (vam->async_mode)
2349     {
2350       vam->async_errors += (retval < 0);
2351     }
2352   else
2353     {
2354       vam->retval = retval;
2355       vam->result_ready = 1;
2356     }
2357 }
2358
2359 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2360   (vl_api_one_add_del_locator_set_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2377   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->sw_if_index = ntohl (mp->sw_if_index);
2389       vam->result_ready = 1;
2390     }
2391   vam->regenerate_interface_table = 1;
2392 }
2393
2394 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2395   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   vat_json_node_t node;
2399
2400   vat_json_init_object (&node);
2401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2403
2404   vat_json_print (vam->ofp, &node);
2405   vat_json_free (&node);
2406
2407   vam->retval = ntohl (mp->retval);
2408   vam->result_ready = 1;
2409 }
2410
2411 static void vl_api_vxlan_offload_rx_reply_t_handler
2412   (vl_api_vxlan_offload_rx_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416   if (vam->async_mode)
2417     {
2418       vam->async_errors += (retval < 0);
2419     }
2420   else
2421     {
2422       vam->retval = retval;
2423       vam->result_ready = 1;
2424     }
2425 }
2426
2427 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2428   (vl_api_vxlan_offload_rx_reply_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t node;
2432
2433   vat_json_init_object (&node);
2434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435
2436   vat_json_print (vam->ofp, &node);
2437   vat_json_free (&node);
2438
2439   vam->retval = ntohl (mp->retval);
2440   vam->result_ready = 1;
2441 }
2442
2443 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2444   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   i32 retval = ntohl (mp->retval);
2448   if (vam->async_mode)
2449     {
2450       vam->async_errors += (retval < 0);
2451     }
2452   else
2453     {
2454       vam->retval = retval;
2455       vam->sw_if_index = ntohl (mp->sw_if_index);
2456       vam->result_ready = 1;
2457     }
2458 }
2459
2460 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2461   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2478   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492   vam->regenerate_interface_table = 1;
2493 }
2494
2495 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2496   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t node;
2500
2501   vat_json_init_object (&node);
2502   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505   vat_json_print (vam->ofp, &node);
2506   vat_json_free (&node);
2507
2508   vam->retval = ntohl (mp->retval);
2509   vam->result_ready = 1;
2510 }
2511
2512 static void vl_api_gre_tunnel_add_del_reply_t_handler
2513   (vl_api_gre_tunnel_add_del_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   i32 retval = ntohl (mp->retval);
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->sw_if_index = ntohl (mp->sw_if_index);
2525       vam->result_ready = 1;
2526     }
2527 }
2528
2529 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2530   (vl_api_gre_tunnel_add_del_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_create_vhost_user_if_reply_t_handler
2547   (vl_api_create_vhost_user_if_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->sw_if_index = ntohl (mp->sw_if_index);
2559       vam->result_ready = 1;
2560     }
2561   vam->regenerate_interface_table = 1;
2562 }
2563
2564 static void vl_api_create_vhost_user_if_reply_t_handler_json
2565   (vl_api_create_vhost_user_if_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t node;
2569
2570   vat_json_init_object (&node);
2571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2573
2574   vat_json_print (vam->ofp, &node);
2575   vat_json_free (&node);
2576
2577   vam->retval = ntohl (mp->retval);
2578   vam->result_ready = 1;
2579 }
2580
2581 static void vl_api_ip_address_details_t_handler
2582   (vl_api_ip_address_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   static ip_address_details_t empty_ip_address_details = { {0} };
2586   ip_address_details_t *address = NULL;
2587   ip_details_t *current_ip_details = NULL;
2588   ip_details_t *details = NULL;
2589
2590   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2591
2592   if (!details || vam->current_sw_if_index >= vec_len (details)
2593       || !details[vam->current_sw_if_index].present)
2594     {
2595       errmsg ("ip address details arrived but not stored");
2596       errmsg ("ip_dump should be called first");
2597       return;
2598     }
2599
2600   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2601
2602 #define addresses (current_ip_details->addr)
2603
2604   vec_validate_init_empty (addresses, vec_len (addresses),
2605                            empty_ip_address_details);
2606
2607   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2608
2609   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2610   address->prefix_length = mp->prefix.len;
2611 #undef addresses
2612 }
2613
2614 static void vl_api_ip_address_details_t_handler_json
2615   (vl_api_ip_address_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   vat_json_node_t *node = NULL;
2619
2620   if (VAT_JSON_ARRAY != vam->json_tree.type)
2621     {
2622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2623       vat_json_init_array (&vam->json_tree);
2624     }
2625   node = vat_json_array_add (&vam->json_tree);
2626
2627   vat_json_init_object (node);
2628   vat_json_object_add_prefix (node, &mp->prefix);
2629 }
2630
2631 static void
2632 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   static ip_details_t empty_ip_details = { 0 };
2636   ip_details_t *ip = NULL;
2637   u32 sw_if_index = ~0;
2638
2639   sw_if_index = ntohl (mp->sw_if_index);
2640
2641   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642                            sw_if_index, empty_ip_details);
2643
2644   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                          sw_if_index);
2646
2647   ip->present = 1;
2648 }
2649
2650 static void
2651 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654
2655   if (VAT_JSON_ARRAY != vam->json_tree.type)
2656     {
2657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2658       vat_json_init_array (&vam->json_tree);
2659     }
2660   vat_json_array_add_uint (&vam->json_tree,
2661                            clib_net_to_host_u32 (mp->sw_if_index));
2662 }
2663
2664 static void vl_api_get_first_msg_id_reply_t_handler
2665   (vl_api_get_first_msg_id_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   i32 retval = ntohl (mp->retval);
2669
2670   if (vam->async_mode)
2671     {
2672       vam->async_errors += (retval < 0);
2673     }
2674   else
2675     {
2676       vam->retval = retval;
2677       vam->result_ready = 1;
2678     }
2679   if (retval >= 0)
2680     {
2681       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2682     }
2683 }
2684
2685 static void vl_api_get_first_msg_id_reply_t_handler_json
2686   (vl_api_get_first_msg_id_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   vat_json_node_t node;
2690
2691   vat_json_init_object (&node);
2692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2693   vat_json_object_add_uint (&node, "first_msg_id",
2694                             (uint) ntohs (mp->first_msg_id));
2695
2696   vat_json_print (vam->ofp, &node);
2697   vat_json_free (&node);
2698
2699   vam->retval = ntohl (mp->retval);
2700   vam->result_ready = 1;
2701 }
2702
2703 static void vl_api_get_node_graph_reply_t_handler
2704   (vl_api_get_node_graph_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708   u8 *pvt_copy, *reply;
2709   void *oldheap;
2710   vlib_node_t *node;
2711   int i;
2712
2713   if (vam->async_mode)
2714     {
2715       vam->async_errors += (retval < 0);
2716     }
2717   else
2718     {
2719       vam->retval = retval;
2720       vam->result_ready = 1;
2721     }
2722
2723   /* "Should never happen..." */
2724   if (retval != 0)
2725     return;
2726
2727   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2728   pvt_copy = vec_dup (reply);
2729
2730   /* Toss the shared-memory original... */
2731   oldheap = vl_msg_push_heap ();
2732
2733   vec_free (reply);
2734
2735   vl_msg_pop_heap (oldheap);
2736
2737   if (vam->graph_nodes)
2738     {
2739       hash_free (vam->graph_node_index_by_name);
2740
2741       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2742         {
2743           node = vam->graph_nodes[0][i];
2744           vec_free (node->name);
2745           vec_free (node->next_nodes);
2746           vec_free (node);
2747         }
2748       vec_free (vam->graph_nodes[0]);
2749       vec_free (vam->graph_nodes);
2750     }
2751
2752   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2753   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2754   vec_free (pvt_copy);
2755
2756   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2757     {
2758       node = vam->graph_nodes[0][i];
2759       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2760     }
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler_json
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   void *oldheap;
2768   vat_json_node_t node;
2769   u8 *reply;
2770
2771   /* $$$$ make this real? */
2772   vat_json_init_object (&node);
2773   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2774   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2775
2776   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   vat_json_print (vam->ofp, &node);
2786   vat_json_free (&node);
2787
2788   vam->retval = ntohl (mp->retval);
2789   vam->result_ready = 1;
2790 }
2791
2792 static void
2793 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   u8 *s = 0;
2797
2798   if (mp->local)
2799     {
2800       s = format (s, "%=16d%=16d%=16d",
2801                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2802     }
2803   else
2804     {
2805       s = format (s, "%=16U%=16d%=16d",
2806                   mp->is_ipv6 ? format_ip6_address :
2807                   format_ip4_address,
2808                   mp->ip_address, mp->priority, mp->weight);
2809     }
2810
2811   print (vam->ofp, "%v", s);
2812   vec_free (s);
2813 }
2814
2815 static void
2816 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t *node = NULL;
2820   struct in6_addr ip6;
2821   struct in_addr ip4;
2822
2823   if (VAT_JSON_ARRAY != vam->json_tree.type)
2824     {
2825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826       vat_json_init_array (&vam->json_tree);
2827     }
2828   node = vat_json_array_add (&vam->json_tree);
2829   vat_json_init_object (node);
2830
2831   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2832   vat_json_object_add_uint (node, "priority", mp->priority);
2833   vat_json_object_add_uint (node, "weight", mp->weight);
2834
2835   if (mp->local)
2836     vat_json_object_add_uint (node, "sw_if_index",
2837                               clib_net_to_host_u32 (mp->sw_if_index));
2838   else
2839     {
2840       if (mp->is_ipv6)
2841         {
2842           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2843           vat_json_object_add_ip6 (node, "address", ip6);
2844         }
2845       else
2846         {
2847           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2848           vat_json_object_add_ip4 (node, "address", ip4);
2849         }
2850     }
2851 }
2852
2853 static void
2854 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2855                                           mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   u8 *ls_name = 0;
2859
2860   ls_name = format (0, "%s", mp->ls_name);
2861
2862   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2863          ls_name);
2864   vec_free (ls_name);
2865 }
2866
2867 static void
2868   vl_api_one_locator_set_details_t_handler_json
2869   (vl_api_one_locator_set_details_t * mp)
2870 {
2871   vat_main_t *vam = &vat_main;
2872   vat_json_node_t *node = 0;
2873   u8 *ls_name = 0;
2874
2875   ls_name = format (0, "%s", mp->ls_name);
2876   vec_add1 (ls_name, 0);
2877
2878   if (VAT_JSON_ARRAY != vam->json_tree.type)
2879     {
2880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2881       vat_json_init_array (&vam->json_tree);
2882     }
2883   node = vat_json_array_add (&vam->json_tree);
2884
2885   vat_json_init_object (node);
2886   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2887   vat_json_object_add_uint (node, "ls_index",
2888                             clib_net_to_host_u32 (mp->ls_index));
2889   vec_free (ls_name);
2890 }
2891
2892 typedef struct
2893 {
2894   u32 spi;
2895   u8 si;
2896 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2897
2898 uword
2899 unformat_nsh_address (unformat_input_t * input, va_list * args)
2900 {
2901   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2902   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2903 }
2904
2905 u8 *
2906 format_nsh_address_vat (u8 * s, va_list * args)
2907 {
2908   nsh_t *a = va_arg (*args, nsh_t *);
2909   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2910 }
2911
2912 static u8 *
2913 format_lisp_flat_eid (u8 * s, va_list * args)
2914 {
2915   u32 type = va_arg (*args, u32);
2916   u8 *eid = va_arg (*args, u8 *);
2917   u32 eid_len = va_arg (*args, u32);
2918
2919   switch (type)
2920     {
2921     case 0:
2922       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2923     case 1:
2924       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2925     case 2:
2926       return format (s, "%U", format_ethernet_address, eid);
2927     case 3:
2928       return format (s, "%U", format_nsh_address_vat, eid);
2929     }
2930   return 0;
2931 }
2932
2933 static u8 *
2934 format_lisp_eid_vat (u8 * s, va_list * args)
2935 {
2936   u32 type = va_arg (*args, u32);
2937   u8 *eid = va_arg (*args, u8 *);
2938   u32 eid_len = va_arg (*args, u32);
2939   u8 *seid = va_arg (*args, u8 *);
2940   u32 seid_len = va_arg (*args, u32);
2941   u32 is_src_dst = va_arg (*args, u32);
2942
2943   if (is_src_dst)
2944     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2945
2946   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2947
2948   return s;
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2953 {
2954   vat_main_t *vam = &vat_main;
2955   u8 *s = 0, *eid = 0;
2956
2957   if (~0 == mp->locator_set_index)
2958     s = format (0, "action: %d", mp->action);
2959   else
2960     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2961
2962   eid = format (0, "%U", format_lisp_eid_vat,
2963                 mp->eid_type,
2964                 mp->eid,
2965                 mp->eid_prefix_len,
2966                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2967   vec_add1 (eid, 0);
2968
2969   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2970          clib_net_to_host_u32 (mp->vni),
2971          eid,
2972          mp->is_local ? "local" : "remote",
2973          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2974          clib_net_to_host_u16 (mp->key_id), mp->key);
2975
2976   vec_free (s);
2977   vec_free (eid);
2978 }
2979
2980 static void
2981 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2982                                              * mp)
2983 {
2984   vat_main_t *vam = &vat_main;
2985   vat_json_node_t *node = 0;
2986   u8 *eid = 0;
2987
2988   if (VAT_JSON_ARRAY != vam->json_tree.type)
2989     {
2990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2991       vat_json_init_array (&vam->json_tree);
2992     }
2993   node = vat_json_array_add (&vam->json_tree);
2994
2995   vat_json_init_object (node);
2996   if (~0 == mp->locator_set_index)
2997     vat_json_object_add_uint (node, "action", mp->action);
2998   else
2999     vat_json_object_add_uint (node, "locator_set_index",
3000                               clib_net_to_host_u32 (mp->locator_set_index));
3001
3002   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3003   if (mp->eid_type == 3)
3004     {
3005       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3006       vat_json_init_object (nsh_json);
3007       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3008       vat_json_object_add_uint (nsh_json, "spi",
3009                                 clib_net_to_host_u32 (nsh->spi));
3010       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3011     }
3012   else
3013     {
3014       eid = format (0, "%U", format_lisp_eid_vat,
3015                     mp->eid_type,
3016                     mp->eid,
3017                     mp->eid_prefix_len,
3018                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3019       vec_add1 (eid, 0);
3020       vat_json_object_add_string_copy (node, "eid", eid);
3021       vec_free (eid);
3022     }
3023   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3024   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3025   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3026
3027   if (mp->key_id)
3028     {
3029       vat_json_object_add_uint (node, "key_id",
3030                                 clib_net_to_host_u16 (mp->key_id));
3031       vat_json_object_add_string_copy (node, "key", mp->key);
3032     }
3033 }
3034
3035 static void
3036 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3037 {
3038   vat_main_t *vam = &vat_main;
3039   u8 *seid = 0, *deid = 0;
3040   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3041
3042   deid = format (0, "%U", format_lisp_eid_vat,
3043                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3044
3045   seid = format (0, "%U", format_lisp_eid_vat,
3046                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3047
3048   vec_add1 (deid, 0);
3049   vec_add1 (seid, 0);
3050
3051   if (mp->is_ip4)
3052     format_ip_address_fcn = format_ip4_address;
3053   else
3054     format_ip_address_fcn = format_ip6_address;
3055
3056
3057   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3058          clib_net_to_host_u32 (mp->vni),
3059          seid, deid,
3060          format_ip_address_fcn, mp->lloc,
3061          format_ip_address_fcn, mp->rloc,
3062          clib_net_to_host_u32 (mp->pkt_count),
3063          clib_net_to_host_u32 (mp->bytes));
3064
3065   vec_free (deid);
3066   vec_free (seid);
3067 }
3068
3069 static void
3070 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3071 {
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074   vat_main_t *vam = &vat_main;
3075   vat_json_node_t *node = 0;
3076   u8 *deid = 0, *seid = 0;
3077
3078   if (VAT_JSON_ARRAY != vam->json_tree.type)
3079     {
3080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3081       vat_json_init_array (&vam->json_tree);
3082     }
3083   node = vat_json_array_add (&vam->json_tree);
3084
3085   vat_json_init_object (node);
3086   deid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3088
3089   seid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3091
3092   vec_add1 (deid, 0);
3093   vec_add1 (seid, 0);
3094
3095   vat_json_object_add_string_copy (node, "seid", seid);
3096   vat_json_object_add_string_copy (node, "deid", deid);
3097   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3098
3099   if (mp->is_ip4)
3100     {
3101       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3102       vat_json_object_add_ip4 (node, "lloc", ip4);
3103       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "rloc", ip4);
3105     }
3106   else
3107     {
3108       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112     }
3113   vat_json_object_add_uint (node, "pkt_count",
3114                             clib_net_to_host_u32 (mp->pkt_count));
3115   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3116
3117   vec_free (deid);
3118   vec_free (seid);
3119 }
3120
3121 static void
3122   vl_api_one_eid_table_map_details_t_handler
3123   (vl_api_one_eid_table_map_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126
3127   u8 *line = format (0, "%=10d%=10d",
3128                      clib_net_to_host_u32 (mp->vni),
3129                      clib_net_to_host_u32 (mp->dp_table));
3130   print (vam->ofp, "%v", line);
3131   vec_free (line);
3132 }
3133
3134 static void
3135   vl_api_one_eid_table_map_details_t_handler_json
3136   (vl_api_one_eid_table_map_details_t * mp)
3137 {
3138   vat_main_t *vam = &vat_main;
3139   vat_json_node_t *node = NULL;
3140
3141   if (VAT_JSON_ARRAY != vam->json_tree.type)
3142     {
3143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3144       vat_json_init_array (&vam->json_tree);
3145     }
3146   node = vat_json_array_add (&vam->json_tree);
3147   vat_json_init_object (node);
3148   vat_json_object_add_uint (node, "dp_table",
3149                             clib_net_to_host_u32 (mp->dp_table));
3150   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3151 }
3152
3153 static void
3154   vl_api_one_eid_table_vni_details_t_handler
3155   (vl_api_one_eid_table_vni_details_t * mp)
3156 {
3157   vat_main_t *vam = &vat_main;
3158
3159   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3160   print (vam->ofp, "%v", line);
3161   vec_free (line);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_vni_details_t_handler_json
3166   (vl_api_one_eid_table_vni_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t *node = NULL;
3170
3171   if (VAT_JSON_ARRAY != vam->json_tree.type)
3172     {
3173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3174       vat_json_init_array (&vam->json_tree);
3175     }
3176   node = vat_json_array_add (&vam->json_tree);
3177   vat_json_init_object (node);
3178   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3179 }
3180
3181 static void
3182   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3183   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   int retval = clib_net_to_host_u32 (mp->retval);
3187
3188   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3189   print (vam->ofp, "fallback threshold value: %d", mp->value);
3190
3191   vam->retval = retval;
3192   vam->result_ready = 1;
3193 }
3194
3195 static void
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3197   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t _node, *node = &_node;
3201   int retval = clib_net_to_host_u32 (mp->retval);
3202
3203   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3204   vat_json_init_object (node);
3205   vat_json_object_add_uint (node, "value", mp->value);
3206
3207   vat_json_print (vam->ofp, node);
3208   vat_json_free (node);
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_register_state_reply_t_handler
3216   (vl_api_show_one_map_register_state_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   int retval = clib_net_to_host_u32 (mp->retval);
3220
3221   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3222
3223   vam->retval = retval;
3224   vam->result_ready = 1;
3225 }
3226
3227 static void
3228   vl_api_show_one_map_register_state_reply_t_handler_json
3229   (vl_api_show_one_map_register_state_reply_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t _node, *node = &_node;
3233   int retval = clib_net_to_host_u32 (mp->retval);
3234
3235   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3236
3237   vat_json_init_object (node);
3238   vat_json_object_add_string_copy (node, "state", s);
3239
3240   vat_json_print (vam->ofp, node);
3241   vat_json_free (node);
3242
3243   vam->retval = retval;
3244   vam->result_ready = 1;
3245   vec_free (s);
3246 }
3247
3248 static void
3249   vl_api_show_one_rloc_probe_state_reply_t_handler
3250   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   int retval = clib_net_to_host_u32 (mp->retval);
3254
3255   if (retval)
3256     goto end;
3257
3258   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3259 end:
3260   vam->retval = retval;
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3266   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   vat_json_node_t _node, *node = &_node;
3270   int retval = clib_net_to_host_u32 (mp->retval);
3271
3272   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3273   vat_json_init_object (node);
3274   vat_json_object_add_string_copy (node, "state", s);
3275
3276   vat_json_print (vam->ofp, node);
3277   vat_json_free (node);
3278
3279   vam->retval = retval;
3280   vam->result_ready = 1;
3281   vec_free (s);
3282 }
3283
3284 static void
3285   vl_api_show_one_stats_enable_disable_reply_t_handler
3286   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   int retval = clib_net_to_host_u32 (mp->retval);
3290
3291   if (retval)
3292     goto end;
3293
3294   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3295 end:
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3302   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3309   vat_json_init_object (node);
3310   vat_json_object_add_string_copy (node, "state", s);
3311
3312   vat_json_print (vam->ofp, node);
3313   vat_json_free (node);
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317   vec_free (s);
3318 }
3319
3320 static void
3321 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3322 {
3323   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3324   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3325   e->vni = clib_net_to_host_u32 (e->vni);
3326 }
3327
3328 static void
3329   gpe_fwd_entries_get_reply_t_net_to_host
3330   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3331 {
3332   u32 i;
3333
3334   mp->count = clib_net_to_host_u32 (mp->count);
3335   for (i = 0; i < mp->count; i++)
3336     {
3337       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3338     }
3339 }
3340
3341 static u8 *
3342 format_gpe_encap_mode (u8 * s, va_list * args)
3343 {
3344   u32 mode = va_arg (*args, u32);
3345
3346   switch (mode)
3347     {
3348     case 0:
3349       return format (s, "lisp");
3350     case 1:
3351       return format (s, "vxlan");
3352     }
3353   return 0;
3354 }
3355
3356 static void
3357   vl_api_gpe_get_encap_mode_reply_t_handler
3358   (vl_api_gpe_get_encap_mode_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361
3362   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3363   vam->retval = ntohl (mp->retval);
3364   vam->result_ready = 1;
3365 }
3366
3367 static void
3368   vl_api_gpe_get_encap_mode_reply_t_handler_json
3369   (vl_api_gpe_get_encap_mode_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372   vat_json_node_t node;
3373
3374   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3375   vec_add1 (encap_mode, 0);
3376
3377   vat_json_init_object (&node);
3378   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3379
3380   vec_free (encap_mode);
3381   vat_json_print (vam->ofp, &node);
3382   vat_json_free (&node);
3383
3384   vam->retval = ntohl (mp->retval);
3385   vam->result_ready = 1;
3386 }
3387
3388 static void
3389   vl_api_gpe_fwd_entry_path_details_t_handler
3390   (vl_api_gpe_fwd_entry_path_details_t * mp)
3391 {
3392   vat_main_t *vam = &vat_main;
3393   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3394
3395   if (mp->lcl_loc.is_ip4)
3396     format_ip_address_fcn = format_ip4_address;
3397   else
3398     format_ip_address_fcn = format_ip6_address;
3399
3400   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3401          format_ip_address_fcn, &mp->lcl_loc,
3402          format_ip_address_fcn, &mp->rmt_loc);
3403 }
3404
3405 static void
3406 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3407 {
3408   struct in6_addr ip6;
3409   struct in_addr ip4;
3410
3411   if (loc->is_ip4)
3412     {
3413       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   else
3417     {
3418       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3419       vat_json_object_add_ip6 (n, "address", ip6);
3420     }
3421   vat_json_object_add_uint (n, "weight", loc->weight);
3422 }
3423
3424 static void
3425   vl_api_gpe_fwd_entry_path_details_t_handler_json
3426   (vl_api_gpe_fwd_entry_path_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   vat_json_node_t *node = NULL;
3430   vat_json_node_t *loc_node;
3431
3432   if (VAT_JSON_ARRAY != vam->json_tree.type)
3433     {
3434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3435       vat_json_init_array (&vam->json_tree);
3436     }
3437   node = vat_json_array_add (&vam->json_tree);
3438   vat_json_init_object (node);
3439
3440   loc_node = vat_json_object_add (node, "local_locator");
3441   vat_json_init_object (loc_node);
3442   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3443
3444   loc_node = vat_json_object_add (node, "remote_locator");
3445   vat_json_init_object (loc_node);
3446   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3447 }
3448
3449 static void
3450   vl_api_gpe_fwd_entries_get_reply_t_handler
3451   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3452 {
3453   vat_main_t *vam = &vat_main;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *e;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462
3463   for (i = 0; i < mp->count; i++)
3464     {
3465       e = &mp->entries[i];
3466       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3467              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3468              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3469     }
3470
3471 end:
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474 }
3475
3476 static void
3477   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3478   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3479 {
3480   u8 *s = 0;
3481   vat_main_t *vam = &vat_main;
3482   vat_json_node_t *e = 0, root;
3483   u32 i;
3484   int retval = clib_net_to_host_u32 (mp->retval);
3485   vl_api_gpe_fwd_entry_t *fwd;
3486
3487   if (retval)
3488     goto end;
3489
3490   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3491   vat_json_init_array (&root);
3492
3493   for (i = 0; i < mp->count; i++)
3494     {
3495       e = vat_json_array_add (&root);
3496       fwd = &mp->entries[i];
3497
3498       vat_json_init_object (e);
3499       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3500       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3501       vat_json_object_add_int (e, "vni", fwd->vni);
3502       vat_json_object_add_int (e, "action", fwd->action);
3503
3504       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3505                   fwd->leid_prefix_len);
3506       vec_add1 (s, 0);
3507       vat_json_object_add_string_copy (e, "leid", s);
3508       vec_free (s);
3509
3510       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3511                   fwd->reid_prefix_len);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "reid", s);
3514       vec_free (s);
3515     }
3516
3517   vat_json_print (vam->ofp, &root);
3518   vat_json_free (&root);
3519
3520 end:
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3527   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533
3534   if (retval)
3535     goto end;
3536
3537   n = clib_net_to_host_u32 (mp->count);
3538
3539   for (i = 0; i < n; i++)
3540     {
3541       r = &mp->entries[i];
3542       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3543              clib_net_to_host_u32 (r->fib_index),
3544              clib_net_to_host_u32 (r->nh_sw_if_index),
3545              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3546     }
3547
3548 end:
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3555   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3556 {
3557   vat_main_t *vam = &vat_main;
3558   vat_json_node_t root, *e;
3559   u32 i, n;
3560   int retval = clib_net_to_host_u32 (mp->retval);
3561   vl_api_gpe_native_fwd_rpath_t *r;
3562   u8 *s;
3563
3564   if (retval)
3565     goto end;
3566
3567   n = clib_net_to_host_u32 (mp->count);
3568   vat_json_init_array (&root);
3569
3570   for (i = 0; i < n; i++)
3571     {
3572       e = vat_json_array_add (&root);
3573       vat_json_init_object (e);
3574       r = &mp->entries[i];
3575       s =
3576         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3577                 r->nh_addr);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "ip4", s);
3580       vec_free (s);
3581
3582       vat_json_object_add_uint (e, "fib_index",
3583                                 clib_net_to_host_u32 (r->fib_index));
3584       vat_json_object_add_uint (e, "nh_sw_if_index",
3585                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3586     }
3587
3588   vat_json_print (vam->ofp, &root);
3589   vat_json_free (&root);
3590
3591 end:
3592   vam->retval = retval;
3593   vam->result_ready = 1;
3594 }
3595
3596 static void
3597   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3598   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3599 {
3600   vat_main_t *vam = &vat_main;
3601   u32 i, n;
3602   int retval = clib_net_to_host_u32 (mp->retval);
3603
3604   if (retval)
3605     goto end;
3606
3607   n = clib_net_to_host_u32 (mp->count);
3608
3609   for (i = 0; i < n; i++)
3610     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3619   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   vat_json_node_t root;
3623   u32 i, n;
3624   int retval = clib_net_to_host_u32 (mp->retval);
3625
3626   if (retval)
3627     goto end;
3628
3629   n = clib_net_to_host_u32 (mp->count);
3630   vat_json_init_array (&root);
3631
3632   for (i = 0; i < n; i++)
3633     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3634
3635   vat_json_print (vam->ofp, &root);
3636   vat_json_free (&root);
3637
3638 end:
3639   vam->retval = retval;
3640   vam->result_ready = 1;
3641 }
3642
3643 static void
3644   vl_api_one_ndp_entries_get_reply_t_handler
3645   (vl_api_one_ndp_entries_get_reply_t * mp)
3646 {
3647   vat_main_t *vam = &vat_main;
3648   u32 i, n;
3649   int retval = clib_net_to_host_u32 (mp->retval);
3650
3651   if (retval)
3652     goto end;
3653
3654   n = clib_net_to_host_u32 (mp->count);
3655
3656   for (i = 0; i < n; i++)
3657     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3658            format_ethernet_address, mp->entries[i].mac);
3659
3660 end:
3661   vam->retval = retval;
3662   vam->result_ready = 1;
3663 }
3664
3665 static void
3666   vl_api_one_ndp_entries_get_reply_t_handler_json
3667   (vl_api_one_ndp_entries_get_reply_t * mp)
3668 {
3669   u8 *s = 0;
3670   vat_main_t *vam = &vat_main;
3671   vat_json_node_t *e = 0, root;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_one_ndp_entry_t *arp_entry;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680   vat_json_init_array (&root);
3681
3682   for (i = 0; i < n; i++)
3683     {
3684       e = vat_json_array_add (&root);
3685       arp_entry = &mp->entries[i];
3686
3687       vat_json_init_object (e);
3688       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3689       vec_add1 (s, 0);
3690
3691       vat_json_object_add_string_copy (e, "mac", s);
3692       vec_free (s);
3693
3694       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3695       vec_add1 (s, 0);
3696       vat_json_object_add_string_copy (e, "ip6", s);
3697       vec_free (s);
3698     }
3699
3700   vat_json_print (vam->ofp, &root);
3701   vat_json_free (&root);
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_l2_arp_entries_get_reply_t_handler
3710   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715
3716   if (retval)
3717     goto end;
3718
3719   n = clib_net_to_host_u32 (mp->count);
3720
3721   for (i = 0; i < n; i++)
3722     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3723            format_ethernet_address, mp->entries[i].mac);
3724
3725 end:
3726   vam->retval = retval;
3727   vam->result_ready = 1;
3728 }
3729
3730 static void
3731   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3732   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3733 {
3734   u8 *s = 0;
3735   vat_main_t *vam = &vat_main;
3736   vat_json_node_t *e = 0, root;
3737   u32 i, n;
3738   int retval = clib_net_to_host_u32 (mp->retval);
3739   vl_api_one_l2_arp_entry_t *arp_entry;
3740
3741   if (retval)
3742     goto end;
3743
3744   n = clib_net_to_host_u32 (mp->count);
3745   vat_json_init_array (&root);
3746
3747   for (i = 0; i < n; i++)
3748     {
3749       e = vat_json_array_add (&root);
3750       arp_entry = &mp->entries[i];
3751
3752       vat_json_init_object (e);
3753       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3754       vec_add1 (s, 0);
3755
3756       vat_json_object_add_string_copy (e, "mac", s);
3757       vec_free (s);
3758
3759       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3760       vec_add1 (s, 0);
3761       vat_json_object_add_string_copy (e, "ip4", s);
3762       vec_free (s);
3763     }
3764
3765   vat_json_print (vam->ofp, &root);
3766   vat_json_free (&root);
3767
3768 end:
3769   vam->retval = retval;
3770   vam->result_ready = 1;
3771 }
3772
3773 static void
3774 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777   u32 i, n;
3778   int retval = clib_net_to_host_u32 (mp->retval);
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784
3785   for (i = 0; i < n; i++)
3786     {
3787       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3788     }
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_ndp_bd_get_reply_t_handler_json
3797   (vl_api_one_ndp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   vat_json_node_t root;
3801   u32 i, n;
3802   int retval = clib_net_to_host_u32 (mp->retval);
3803
3804   if (retval)
3805     goto end;
3806
3807   n = clib_net_to_host_u32 (mp->count);
3808   vat_json_init_array (&root);
3809
3810   for (i = 0; i < n; i++)
3811     {
3812       vat_json_array_add_uint (&root,
3813                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3814     }
3815
3816   vat_json_print (vam->ofp, &root);
3817   vat_json_free (&root);
3818
3819 end:
3820   vam->retval = retval;
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_l2_arp_bd_get_reply_t_handler
3826   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3827 {
3828   vat_main_t *vam = &vat_main;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3840     }
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3849   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t root;
3853   u32 i, n;
3854   int retval = clib_net_to_host_u32 (mp->retval);
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860   vat_json_init_array (&root);
3861
3862   for (i = 0; i < n; i++)
3863     {
3864       vat_json_array_add_uint (&root,
3865                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3866     }
3867
3868   vat_json_print (vam->ofp, &root);
3869   vat_json_free (&root);
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_one_adjacencies_get_reply_t_handler
3878   (vl_api_one_adjacencies_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889
3890   for (i = 0; i < n; i++)
3891     {
3892       a = &mp->adjacencies[i];
3893       print (vam->ofp, "%U %40U",
3894              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3895              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3896     }
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_one_adjacencies_get_reply_t_handler_json
3905   (vl_api_one_adjacencies_get_reply_t * mp)
3906 {
3907   u8 *s = 0;
3908   vat_main_t *vam = &vat_main;
3909   vat_json_node_t *e = 0, root;
3910   u32 i, n;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912   vl_api_one_adjacency_t *a;
3913
3914   if (retval)
3915     goto end;
3916
3917   n = clib_net_to_host_u32 (mp->count);
3918   vat_json_init_array (&root);
3919
3920   for (i = 0; i < n; i++)
3921     {
3922       e = vat_json_array_add (&root);
3923       a = &mp->adjacencies[i];
3924
3925       vat_json_init_object (e);
3926       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3927                   a->leid_prefix_len);
3928       vec_add1 (s, 0);
3929       vat_json_object_add_string_copy (e, "leid", s);
3930       vec_free (s);
3931
3932       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3933                   a->reid_prefix_len);
3934       vec_add1 (s, 0);
3935       vat_json_object_add_string_copy (e, "reid", s);
3936       vec_free (s);
3937     }
3938
3939   vat_json_print (vam->ofp, &root);
3940   vat_json_free (&root);
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951
3952   print (vam->ofp, "%=20U",
3953          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3954          mp->ip_address);
3955 }
3956
3957 static void
3958   vl_api_one_map_server_details_t_handler_json
3959   (vl_api_one_map_server_details_t * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962   vat_json_node_t *node = NULL;
3963   struct in6_addr ip6;
3964   struct in_addr ip4;
3965
3966   if (VAT_JSON_ARRAY != vam->json_tree.type)
3967     {
3968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3969       vat_json_init_array (&vam->json_tree);
3970     }
3971   node = vat_json_array_add (&vam->json_tree);
3972
3973   vat_json_init_object (node);
3974   if (mp->is_ipv6)
3975     {
3976       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3977       vat_json_object_add_ip6 (node, "map-server", ip6);
3978     }
3979   else
3980     {
3981       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3982       vat_json_object_add_ip4 (node, "map-server", ip4);
3983     }
3984 }
3985
3986 static void
3987 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3988                                            * mp)
3989 {
3990   vat_main_t *vam = &vat_main;
3991
3992   print (vam->ofp, "%=20U",
3993          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3994          mp->ip_address);
3995 }
3996
3997 static void
3998   vl_api_one_map_resolver_details_t_handler_json
3999   (vl_api_one_map_resolver_details_t * mp)
4000 {
4001   vat_main_t *vam = &vat_main;
4002   vat_json_node_t *node = NULL;
4003   struct in6_addr ip6;
4004   struct in_addr ip4;
4005
4006   if (VAT_JSON_ARRAY != vam->json_tree.type)
4007     {
4008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4009       vat_json_init_array (&vam->json_tree);
4010     }
4011   node = vat_json_array_add (&vam->json_tree);
4012
4013   vat_json_init_object (node);
4014   if (mp->is_ipv6)
4015     {
4016       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4017       vat_json_object_add_ip6 (node, "map resolver", ip6);
4018     }
4019   else
4020     {
4021       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4022       vat_json_object_add_ip4 (node, "map resolver", ip4);
4023     }
4024 }
4025
4026 static void
4027 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030   i32 retval = ntohl (mp->retval);
4031
4032   if (0 <= retval)
4033     {
4034       print (vam->ofp, "feature: %s\ngpe: %s",
4035              mp->feature_status ? "enabled" : "disabled",
4036              mp->gpe_status ? "enabled" : "disabled");
4037     }
4038
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_show_one_status_reply_t_handler_json
4045   (vl_api_show_one_status_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t node;
4049   u8 *gpe_status = NULL;
4050   u8 *feature_status = NULL;
4051
4052   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4053   feature_status = format (0, "%s",
4054                            mp->feature_status ? "enabled" : "disabled");
4055   vec_add1 (gpe_status, 0);
4056   vec_add1 (feature_status, 0);
4057
4058   vat_json_init_object (&node);
4059   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4060   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4061
4062   vec_free (gpe_status);
4063   vec_free (feature_status);
4064
4065   vat_json_print (vam->ofp, &node);
4066   vat_json_free (&node);
4067
4068   vam->retval = ntohl (mp->retval);
4069   vam->result_ready = 1;
4070 }
4071
4072 static void
4073   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4074   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4075 {
4076   vat_main_t *vam = &vat_main;
4077   i32 retval = ntohl (mp->retval);
4078
4079   if (retval >= 0)
4080     {
4081       print (vam->ofp, "%=20s", mp->locator_set_name);
4082     }
4083
4084   vam->retval = retval;
4085   vam->result_ready = 1;
4086 }
4087
4088 static void
4089   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4090   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   vat_json_node_t *node = NULL;
4094
4095   if (VAT_JSON_ARRAY != vam->json_tree.type)
4096     {
4097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4098       vat_json_init_array (&vam->json_tree);
4099     }
4100   node = vat_json_array_add (&vam->json_tree);
4101
4102   vat_json_init_object (node);
4103   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4104
4105   vat_json_print (vam->ofp, node);
4106   vat_json_free (node);
4107
4108   vam->retval = ntohl (mp->retval);
4109   vam->result_ready = 1;
4110 }
4111
4112 static u8 *
4113 format_lisp_map_request_mode (u8 * s, va_list * args)
4114 {
4115   u32 mode = va_arg (*args, u32);
4116
4117   switch (mode)
4118     {
4119     case 0:
4120       return format (0, "dst-only");
4121     case 1:
4122       return format (0, "src-dst");
4123     }
4124   return 0;
4125 }
4126
4127 static void
4128   vl_api_show_one_map_request_mode_reply_t_handler
4129   (vl_api_show_one_map_request_mode_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   i32 retval = ntohl (mp->retval);
4133
4134   if (0 <= retval)
4135     {
4136       u32 mode = mp->mode;
4137       print (vam->ofp, "map_request_mode: %U",
4138              format_lisp_map_request_mode, mode);
4139     }
4140
4141   vam->retval = retval;
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_show_one_map_request_mode_reply_t_handler_json
4147   (vl_api_show_one_map_request_mode_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   vat_json_node_t node;
4151   u8 *s = 0;
4152   u32 mode;
4153
4154   mode = mp->mode;
4155   s = format (0, "%U", format_lisp_map_request_mode, mode);
4156   vec_add1 (s, 0);
4157
4158   vat_json_init_object (&node);
4159   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4160   vat_json_print (vam->ofp, &node);
4161   vat_json_free (&node);
4162
4163   vec_free (s);
4164   vam->retval = ntohl (mp->retval);
4165   vam->result_ready = 1;
4166 }
4167
4168 static void
4169   vl_api_one_show_xtr_mode_reply_t_handler
4170   (vl_api_one_show_xtr_mode_reply_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   i32 retval = ntohl (mp->retval);
4174
4175   if (0 <= retval)
4176     {
4177       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_show_xtr_mode_reply_t_handler_json
4186   (vl_api_one_show_xtr_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *status = 0;
4191
4192   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4193   vec_add1 (status, 0);
4194
4195   vat_json_init_object (&node);
4196   vat_json_object_add_string_copy (&node, "status", status);
4197
4198   vec_free (status);
4199
4200   vat_json_print (vam->ofp, &node);
4201   vat_json_free (&node);
4202
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_pitr_mode_reply_t_handler
4209   (vl_api_one_show_pitr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_pitr_mode_reply_t_handler_json
4225   (vl_api_one_show_pitr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_petr_mode_reply_t_handler
4248   (vl_api_one_show_petr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_petr_mode_reply_t_handler_json
4264   (vl_api_one_show_petr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_show_one_use_petr_reply_t_handler
4287   (vl_api_show_one_use_petr_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4295       if (mp->status)
4296         {
4297           print (vam->ofp, "Proxy-ETR address; %U",
4298                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4299                  mp->address);
4300         }
4301     }
4302
4303   vam->retval = retval;
4304   vam->result_ready = 1;
4305 }
4306
4307 static void
4308   vl_api_show_one_use_petr_reply_t_handler_json
4309   (vl_api_show_one_use_petr_reply_t * mp)
4310 {
4311   vat_main_t *vam = &vat_main;
4312   vat_json_node_t node;
4313   u8 *status = 0;
4314   struct in_addr ip4;
4315   struct in6_addr ip6;
4316
4317   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4318   vec_add1 (status, 0);
4319
4320   vat_json_init_object (&node);
4321   vat_json_object_add_string_copy (&node, "status", status);
4322   if (mp->status)
4323     {
4324       if (mp->is_ip4)
4325         {
4326           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4327           vat_json_object_add_ip6 (&node, "address", ip6);
4328         }
4329       else
4330         {
4331           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4332           vat_json_object_add_ip4 (&node, "address", ip4);
4333         }
4334     }
4335
4336   vec_free (status);
4337
4338   vat_json_print (vam->ofp, &node);
4339   vat_json_free (&node);
4340
4341   vam->retval = ntohl (mp->retval);
4342   vam->result_ready = 1;
4343 }
4344
4345 static void
4346   vl_api_show_one_nsh_mapping_reply_t_handler
4347   (vl_api_show_one_nsh_mapping_reply_t * mp)
4348 {
4349   vat_main_t *vam = &vat_main;
4350   i32 retval = ntohl (mp->retval);
4351
4352   if (0 <= retval)
4353     {
4354       print (vam->ofp, "%-20s%-16s",
4355              mp->is_set ? "set" : "not-set",
4356              mp->is_set ? (char *) mp->locator_set_name : "");
4357     }
4358
4359   vam->retval = retval;
4360   vam->result_ready = 1;
4361 }
4362
4363 static void
4364   vl_api_show_one_nsh_mapping_reply_t_handler_json
4365   (vl_api_show_one_nsh_mapping_reply_t * mp)
4366 {
4367   vat_main_t *vam = &vat_main;
4368   vat_json_node_t node;
4369   u8 *status = 0;
4370
4371   status = format (0, "%s", mp->is_set ? "yes" : "no");
4372   vec_add1 (status, 0);
4373
4374   vat_json_init_object (&node);
4375   vat_json_object_add_string_copy (&node, "is_set", status);
4376   if (mp->is_set)
4377     {
4378       vat_json_object_add_string_copy (&node, "locator_set",
4379                                        mp->locator_set_name);
4380     }
4381
4382   vec_free (status);
4383
4384   vat_json_print (vam->ofp, &node);
4385   vat_json_free (&node);
4386
4387   vam->retval = ntohl (mp->retval);
4388   vam->result_ready = 1;
4389 }
4390
4391 static void
4392   vl_api_show_one_map_register_ttl_reply_t_handler
4393   (vl_api_show_one_map_register_ttl_reply_t * mp)
4394 {
4395   vat_main_t *vam = &vat_main;
4396   i32 retval = ntohl (mp->retval);
4397
4398   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4399
4400   if (0 <= retval)
4401     {
4402       print (vam->ofp, "ttl: %u", mp->ttl);
4403     }
4404
4405   vam->retval = retval;
4406   vam->result_ready = 1;
4407 }
4408
4409 static void
4410   vl_api_show_one_map_register_ttl_reply_t_handler_json
4411   (vl_api_show_one_map_register_ttl_reply_t * mp)
4412 {
4413   vat_main_t *vam = &vat_main;
4414   vat_json_node_t node;
4415
4416   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4417   vat_json_init_object (&node);
4418   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4429 {
4430   vat_main_t *vam = &vat_main;
4431   i32 retval = ntohl (mp->retval);
4432
4433   if (0 <= retval)
4434     {
4435       print (vam->ofp, "%-20s%-16s",
4436              mp->status ? "enabled" : "disabled",
4437              mp->status ? (char *) mp->locator_set_name : "");
4438     }
4439
4440   vam->retval = retval;
4441   vam->result_ready = 1;
4442 }
4443
4444 static void
4445 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456   if (mp->status)
4457     {
4458       vat_json_object_add_string_copy (&node, "locator_set",
4459                                        mp->locator_set_name);
4460     }
4461
4462   vec_free (status);
4463
4464   vat_json_print (vam->ofp, &node);
4465   vat_json_free (&node);
4466
4467   vam->retval = ntohl (mp->retval);
4468   vam->result_ready = 1;
4469 }
4470
4471 static u8 *
4472 format_policer_type (u8 * s, va_list * va)
4473 {
4474   u32 i = va_arg (*va, u32);
4475
4476   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4477     s = format (s, "1r2c");
4478   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4479     s = format (s, "1r3c");
4480   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4481     s = format (s, "2r3c-2698");
4482   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4483     s = format (s, "2r3c-4115");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4485     s = format (s, "2r3c-mef5cf1");
4486   else
4487     s = format (s, "ILLEGAL");
4488   return s;
4489 }
4490
4491 static u8 *
4492 format_policer_rate_type (u8 * s, va_list * va)
4493 {
4494   u32 i = va_arg (*va, u32);
4495
4496   if (i == SSE2_QOS_RATE_KBPS)
4497     s = format (s, "kbps");
4498   else if (i == SSE2_QOS_RATE_PPS)
4499     s = format (s, "pps");
4500   else
4501     s = format (s, "ILLEGAL");
4502   return s;
4503 }
4504
4505 static u8 *
4506 format_policer_round_type (u8 * s, va_list * va)
4507 {
4508   u32 i = va_arg (*va, u32);
4509
4510   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4511     s = format (s, "closest");
4512   else if (i == SSE2_QOS_ROUND_TO_UP)
4513     s = format (s, "up");
4514   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4515     s = format (s, "down");
4516   else
4517     s = format (s, "ILLEGAL");
4518   return s;
4519 }
4520
4521 static u8 *
4522 format_policer_action_type (u8 * s, va_list * va)
4523 {
4524   u32 i = va_arg (*va, u32);
4525
4526   if (i == SSE2_QOS_ACTION_DROP)
4527     s = format (s, "drop");
4528   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4529     s = format (s, "transmit");
4530   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4531     s = format (s, "mark-and-transmit");
4532   else
4533     s = format (s, "ILLEGAL");
4534   return s;
4535 }
4536
4537 static u8 *
4538 format_dscp (u8 * s, va_list * va)
4539 {
4540   u32 i = va_arg (*va, u32);
4541   char *t = 0;
4542
4543   switch (i)
4544     {
4545 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4546       foreach_vnet_dscp
4547 #undef _
4548     default:
4549       return format (s, "ILLEGAL");
4550     }
4551   s = format (s, "%s", t);
4552   return s;
4553 }
4554
4555 static void
4556 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4560
4561   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4562     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4563   else
4564     conform_dscp_str = format (0, "");
4565
4566   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4567     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4568   else
4569     exceed_dscp_str = format (0, "");
4570
4571   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4572     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4573   else
4574     violate_dscp_str = format (0, "");
4575
4576   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4577          "rate type %U, round type %U, %s rate, %s color-aware, "
4578          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4579          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4580          "conform action %U%s, exceed action %U%s, violate action %U%s",
4581          mp->name,
4582          format_policer_type, mp->type,
4583          ntohl (mp->cir),
4584          ntohl (mp->eir),
4585          clib_net_to_host_u64 (mp->cb),
4586          clib_net_to_host_u64 (mp->eb),
4587          format_policer_rate_type, mp->rate_type,
4588          format_policer_round_type, mp->round_type,
4589          mp->single_rate ? "single" : "dual",
4590          mp->color_aware ? "is" : "not",
4591          ntohl (mp->cir_tokens_per_period),
4592          ntohl (mp->pir_tokens_per_period),
4593          ntohl (mp->scale),
4594          ntohl (mp->current_limit),
4595          ntohl (mp->current_bucket),
4596          ntohl (mp->extended_limit),
4597          ntohl (mp->extended_bucket),
4598          clib_net_to_host_u64 (mp->last_update_time),
4599          format_policer_action_type, mp->conform_action.type,
4600          conform_dscp_str,
4601          format_policer_action_type, mp->exceed_action.type,
4602          exceed_dscp_str,
4603          format_policer_action_type, mp->violate_action.type,
4604          violate_dscp_str);
4605
4606   vec_free (conform_dscp_str);
4607   vec_free (exceed_dscp_str);
4608   vec_free (violate_dscp_str);
4609 }
4610
4611 static void vl_api_policer_details_t_handler_json
4612   (vl_api_policer_details_t * mp)
4613 {
4614   vat_main_t *vam = &vat_main;
4615   vat_json_node_t *node;
4616   u8 *rate_type_str, *round_type_str, *type_str;
4617   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4618
4619   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4620   round_type_str =
4621     format (0, "%U", format_policer_round_type, mp->round_type);
4622   type_str = format (0, "%U", format_policer_type, mp->type);
4623   conform_action_str = format (0, "%U", format_policer_action_type,
4624                                mp->conform_action.type);
4625   exceed_action_str = format (0, "%U", format_policer_action_type,
4626                               mp->exceed_action.type);
4627   violate_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->violate_action.type);
4629
4630   if (VAT_JSON_ARRAY != vam->json_tree.type)
4631     {
4632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4633       vat_json_init_array (&vam->json_tree);
4634     }
4635   node = vat_json_array_add (&vam->json_tree);
4636
4637   vat_json_init_object (node);
4638   vat_json_object_add_string_copy (node, "name", mp->name);
4639   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4640   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4641   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4642   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4643   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4644   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4645   vat_json_object_add_string_copy (node, "type", type_str);
4646   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4647   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4648   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4649   vat_json_object_add_uint (node, "cir_tokens_per_period",
4650                             ntohl (mp->cir_tokens_per_period));
4651   vat_json_object_add_uint (node, "eir_tokens_per_period",
4652                             ntohl (mp->pir_tokens_per_period));
4653   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4654   vat_json_object_add_uint (node, "current_bucket",
4655                             ntohl (mp->current_bucket));
4656   vat_json_object_add_uint (node, "extended_limit",
4657                             ntohl (mp->extended_limit));
4658   vat_json_object_add_uint (node, "extended_bucket",
4659                             ntohl (mp->extended_bucket));
4660   vat_json_object_add_uint (node, "last_update_time",
4661                             ntohl (mp->last_update_time));
4662   vat_json_object_add_string_copy (node, "conform_action",
4663                                    conform_action_str);
4664   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4665     {
4666       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4667       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4668       vec_free (dscp_str);
4669     }
4670   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4671   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4672     {
4673       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4674       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4675       vec_free (dscp_str);
4676     }
4677   vat_json_object_add_string_copy (node, "violate_action",
4678                                    violate_action_str);
4679   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4680     {
4681       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4682       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4683       vec_free (dscp_str);
4684     }
4685
4686   vec_free (rate_type_str);
4687   vec_free (round_type_str);
4688   vec_free (type_str);
4689   vec_free (conform_action_str);
4690   vec_free (exceed_action_str);
4691   vec_free (violate_action_str);
4692 }
4693
4694 static void
4695 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4696                                            mp)
4697 {
4698   vat_main_t *vam = &vat_main;
4699   int i, count = ntohl (mp->count);
4700
4701   if (count > 0)
4702     print (vam->ofp, "classify table ids (%d) : ", count);
4703   for (i = 0; i < count; i++)
4704     {
4705       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4706       print (vam->ofp, (i < count - 1) ? "," : "");
4707     }
4708   vam->retval = ntohl (mp->retval);
4709   vam->result_ready = 1;
4710 }
4711
4712 static void
4713   vl_api_classify_table_ids_reply_t_handler_json
4714   (vl_api_classify_table_ids_reply_t * mp)
4715 {
4716   vat_main_t *vam = &vat_main;
4717   int i, count = ntohl (mp->count);
4718
4719   if (count > 0)
4720     {
4721       vat_json_node_t node;
4722
4723       vat_json_init_object (&node);
4724       for (i = 0; i < count; i++)
4725         {
4726           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4727         }
4728       vat_json_print (vam->ofp, &node);
4729       vat_json_free (&node);
4730     }
4731   vam->retval = ntohl (mp->retval);
4732   vam->result_ready = 1;
4733 }
4734
4735 static void
4736   vl_api_classify_table_by_interface_reply_t_handler
4737   (vl_api_classify_table_by_interface_reply_t * mp)
4738 {
4739   vat_main_t *vam = &vat_main;
4740   u32 table_id;
4741
4742   table_id = ntohl (mp->l2_table_id);
4743   if (table_id != ~0)
4744     print (vam->ofp, "l2 table id : %d", table_id);
4745   else
4746     print (vam->ofp, "l2 table id : No input ACL tables configured");
4747   table_id = ntohl (mp->ip4_table_id);
4748   if (table_id != ~0)
4749     print (vam->ofp, "ip4 table id : %d", table_id);
4750   else
4751     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4752   table_id = ntohl (mp->ip6_table_id);
4753   if (table_id != ~0)
4754     print (vam->ofp, "ip6 table id : %d", table_id);
4755   else
4756     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4757   vam->retval = ntohl (mp->retval);
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762   vl_api_classify_table_by_interface_reply_t_handler_json
4763   (vl_api_classify_table_by_interface_reply_t * mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   vat_json_node_t node;
4767
4768   vat_json_init_object (&node);
4769
4770   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4771   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4772   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4773
4774   vat_json_print (vam->ofp, &node);
4775   vat_json_free (&node);
4776
4777   vam->retval = ntohl (mp->retval);
4778   vam->result_ready = 1;
4779 }
4780
4781 static void vl_api_policer_add_del_reply_t_handler
4782   (vl_api_policer_add_del_reply_t * mp)
4783 {
4784   vat_main_t *vam = &vat_main;
4785   i32 retval = ntohl (mp->retval);
4786   if (vam->async_mode)
4787     {
4788       vam->async_errors += (retval < 0);
4789     }
4790   else
4791     {
4792       vam->retval = retval;
4793       vam->result_ready = 1;
4794       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4795         /*
4796          * Note: this is just barely thread-safe, depends on
4797          * the main thread spinning waiting for an answer...
4798          */
4799         errmsg ("policer index %d", ntohl (mp->policer_index));
4800     }
4801 }
4802
4803 static void vl_api_policer_add_del_reply_t_handler_json
4804   (vl_api_policer_add_del_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   vat_json_node_t node;
4808
4809   vat_json_init_object (&node);
4810   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4811   vat_json_object_add_uint (&node, "policer_index",
4812                             ntohl (mp->policer_index));
4813
4814   vat_json_print (vam->ofp, &node);
4815   vat_json_free (&node);
4816
4817   vam->retval = ntohl (mp->retval);
4818   vam->result_ready = 1;
4819 }
4820
4821 /* Format hex dump. */
4822 u8 *
4823 format_hex_bytes (u8 * s, va_list * va)
4824 {
4825   u8 *bytes = va_arg (*va, u8 *);
4826   int n_bytes = va_arg (*va, int);
4827   uword i;
4828
4829   /* Print short or long form depending on byte count. */
4830   uword short_form = n_bytes <= 32;
4831   u32 indent = format_get_indent (s);
4832
4833   if (n_bytes == 0)
4834     return s;
4835
4836   for (i = 0; i < n_bytes; i++)
4837     {
4838       if (!short_form && (i % 32) == 0)
4839         s = format (s, "%08x: ", i);
4840       s = format (s, "%02x", bytes[i]);
4841       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4842         s = format (s, "\n%U", format_white_space, indent);
4843     }
4844
4845   return s;
4846 }
4847
4848 static void
4849 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4850                                             * mp)
4851 {
4852   vat_main_t *vam = &vat_main;
4853   i32 retval = ntohl (mp->retval);
4854   if (retval == 0)
4855     {
4856       print (vam->ofp, "classify table info :");
4857       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4858              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4859              ntohl (mp->miss_next_index));
4860       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4861              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4862              ntohl (mp->match_n_vectors));
4863       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4864              ntohl (mp->mask_length));
4865     }
4866   vam->retval = retval;
4867   vam->result_ready = 1;
4868 }
4869
4870 static void
4871   vl_api_classify_table_info_reply_t_handler_json
4872   (vl_api_classify_table_info_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876
4877   i32 retval = ntohl (mp->retval);
4878   if (retval == 0)
4879     {
4880       vat_json_init_object (&node);
4881
4882       vat_json_object_add_int (&node, "sessions",
4883                                ntohl (mp->active_sessions));
4884       vat_json_object_add_int (&node, "nexttbl",
4885                                ntohl (mp->next_table_index));
4886       vat_json_object_add_int (&node, "nextnode",
4887                                ntohl (mp->miss_next_index));
4888       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4889       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4890       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4891       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4892                       ntohl (mp->mask_length), 0);
4893       vat_json_object_add_string_copy (&node, "mask", s);
4894
4895       vat_json_print (vam->ofp, &node);
4896       vat_json_free (&node);
4897     }
4898   vam->retval = ntohl (mp->retval);
4899   vam->result_ready = 1;
4900 }
4901
4902 static void
4903 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4904                                            mp)
4905 {
4906   vat_main_t *vam = &vat_main;
4907
4908   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4909          ntohl (mp->hit_next_index), ntohl (mp->advance),
4910          ntohl (mp->opaque_index));
4911   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4912          ntohl (mp->match_length));
4913 }
4914
4915 static void
4916   vl_api_classify_session_details_t_handler_json
4917   (vl_api_classify_session_details_t * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   vat_json_node_t *node = NULL;
4921
4922   if (VAT_JSON_ARRAY != vam->json_tree.type)
4923     {
4924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4925       vat_json_init_array (&vam->json_tree);
4926     }
4927   node = vat_json_array_add (&vam->json_tree);
4928
4929   vat_json_init_object (node);
4930   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4931   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4932   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4933   u8 *s =
4934     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4935             0);
4936   vat_json_object_add_string_copy (node, "match", s);
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   vam->retval = ntohl (mp->retval);
4945   vam->result_ready = 1;
4946 }
4947
4948 static void vl_api_pg_create_interface_reply_t_handler_json
4949   (vl_api_pg_create_interface_reply_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t node;
4953
4954   i32 retval = ntohl (mp->retval);
4955   if (retval == 0)
4956     {
4957       vat_json_init_object (&node);
4958
4959       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4960
4961       vat_json_print (vam->ofp, &node);
4962       vat_json_free (&node);
4963     }
4964   vam->retval = ntohl (mp->retval);
4965   vam->result_ready = 1;
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972
4973   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4974          ntohl (mp->table_index));
4975 }
4976
4977 static void vl_api_policer_classify_details_t_handler_json
4978   (vl_api_policer_classify_details_t * mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981   vat_json_node_t *node;
4982
4983   if (VAT_JSON_ARRAY != vam->json_tree.type)
4984     {
4985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4986       vat_json_init_array (&vam->json_tree);
4987     }
4988   node = vat_json_array_add (&vam->json_tree);
4989
4990   vat_json_init_object (node);
4991   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4992   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999
5000   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5001          ntohl (mp->table_index));
5002 }
5003
5004 static void vl_api_flow_classify_details_t_handler_json
5005   (vl_api_flow_classify_details_t * mp)
5006 {
5007   vat_main_t *vam = &vat_main;
5008   vat_json_node_t *node;
5009
5010   if (VAT_JSON_ARRAY != vam->json_tree.type)
5011     {
5012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5013       vat_json_init_array (&vam->json_tree);
5014     }
5015   node = vat_json_array_add (&vam->json_tree);
5016
5017   vat_json_init_object (node);
5018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5019   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5020 }
5021
5022 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5023 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5024 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5025 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5029 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5030 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5032
5033 /*
5034  * Generate boilerplate reply handlers, which
5035  * dig the return value out of the xxx_reply_t API message,
5036  * stick it into vam->retval, and set vam->result_ready
5037  *
5038  * Could also do this by pointing N message decode slots at
5039  * a single function, but that could break in subtle ways.
5040  */
5041
5042 #define foreach_standard_reply_retval_handler           \
5043 _(sw_interface_set_flags_reply)                         \
5044 _(sw_interface_add_del_address_reply)                   \
5045 _(sw_interface_set_rx_mode_reply)                       \
5046 _(sw_interface_set_rx_placement_reply)                  \
5047 _(sw_interface_set_table_reply)                         \
5048 _(sw_interface_set_mpls_enable_reply)                   \
5049 _(sw_interface_set_vpath_reply)                         \
5050 _(sw_interface_set_vxlan_bypass_reply)                  \
5051 _(sw_interface_set_geneve_bypass_reply)                 \
5052 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5053 _(sw_interface_set_l2_bridge_reply)                     \
5054 _(sw_interface_set_bond_weight_reply)                   \
5055 _(bridge_domain_add_del_reply)                          \
5056 _(sw_interface_set_l2_xconnect_reply)                   \
5057 _(l2fib_add_del_reply)                                  \
5058 _(l2fib_flush_int_reply)                                \
5059 _(l2fib_flush_bd_reply)                                 \
5060 _(ip_route_add_del_reply)                               \
5061 _(ip_table_add_del_reply)                               \
5062 _(ip_table_replace_begin_reply)                         \
5063 _(ip_table_flush_reply)                                 \
5064 _(ip_table_replace_end_reply)                           \
5065 _(ip_mroute_add_del_reply)                              \
5066 _(mpls_route_add_del_reply)                             \
5067 _(mpls_table_add_del_reply)                             \
5068 _(mpls_ip_bind_unbind_reply)                            \
5069 _(bier_route_add_del_reply)                             \
5070 _(bier_table_add_del_reply)                             \
5071 _(sw_interface_set_unnumbered_reply)                    \
5072 _(set_ip_flow_hash_reply)                               \
5073 _(sw_interface_ip6_enable_disable_reply)                \
5074 _(l2_patch_add_del_reply)                               \
5075 _(sr_mpls_policy_add_reply)                             \
5076 _(sr_mpls_policy_mod_reply)                             \
5077 _(sr_mpls_policy_del_reply)                             \
5078 _(sr_policy_add_reply)                                  \
5079 _(sr_policy_mod_reply)                                  \
5080 _(sr_policy_del_reply)                                  \
5081 _(sr_localsid_add_del_reply)                            \
5082 _(sr_steering_add_del_reply)                            \
5083 _(classify_add_del_session_reply)                       \
5084 _(classify_set_interface_ip_table_reply)                \
5085 _(classify_set_interface_l2_tables_reply)               \
5086 _(l2tpv3_set_tunnel_cookies_reply)                      \
5087 _(l2tpv3_interface_enable_disable_reply)                \
5088 _(l2tpv3_set_lookup_key_reply)                          \
5089 _(l2_fib_clear_table_reply)                             \
5090 _(l2_interface_efp_filter_reply)                        \
5091 _(l2_interface_vlan_tag_rewrite_reply)                  \
5092 _(modify_vhost_user_if_reply)                           \
5093 _(delete_vhost_user_if_reply)                           \
5094 _(want_l2_macs_events_reply)                            \
5095 _(input_acl_set_interface_reply)                        \
5096 _(ipsec_spd_add_del_reply)                              \
5097 _(ipsec_interface_add_del_spd_reply)                    \
5098 _(ipsec_spd_entry_add_del_reply)                        \
5099 _(ipsec_sad_entry_add_del_reply)                        \
5100 _(ipsec_tunnel_if_add_del_reply)                        \
5101 _(ipsec_tunnel_if_set_sa_reply)                         \
5102 _(delete_loopback_reply)                                \
5103 _(bd_ip_mac_add_del_reply)                              \
5104 _(bd_ip_mac_flush_reply)                                \
5105 _(want_interface_events_reply)                          \
5106 _(cop_interface_enable_disable_reply)                   \
5107 _(cop_whitelist_enable_disable_reply)                   \
5108 _(sw_interface_clear_stats_reply)                       \
5109 _(ioam_enable_reply)                                    \
5110 _(ioam_disable_reply)                                   \
5111 _(one_add_del_locator_reply)                            \
5112 _(one_add_del_local_eid_reply)                          \
5113 _(one_add_del_remote_mapping_reply)                     \
5114 _(one_add_del_adjacency_reply)                          \
5115 _(one_add_del_map_resolver_reply)                       \
5116 _(one_add_del_map_server_reply)                         \
5117 _(one_enable_disable_reply)                             \
5118 _(one_rloc_probe_enable_disable_reply)                  \
5119 _(one_map_register_enable_disable_reply)                \
5120 _(one_map_register_set_ttl_reply)                       \
5121 _(one_set_transport_protocol_reply)                     \
5122 _(one_map_register_fallback_threshold_reply)            \
5123 _(one_pitr_set_locator_set_reply)                       \
5124 _(one_map_request_mode_reply)                           \
5125 _(one_add_del_map_request_itr_rlocs_reply)              \
5126 _(one_eid_table_add_del_map_reply)                      \
5127 _(one_use_petr_reply)                                   \
5128 _(one_stats_enable_disable_reply)                       \
5129 _(one_add_del_l2_arp_entry_reply)                       \
5130 _(one_add_del_ndp_entry_reply)                          \
5131 _(one_stats_flush_reply)                                \
5132 _(one_enable_disable_xtr_mode_reply)                    \
5133 _(one_enable_disable_pitr_mode_reply)                   \
5134 _(one_enable_disable_petr_mode_reply)                   \
5135 _(gpe_enable_disable_reply)                             \
5136 _(gpe_set_encap_mode_reply)                             \
5137 _(gpe_add_del_iface_reply)                              \
5138 _(gpe_add_del_native_fwd_rpath_reply)                   \
5139 _(af_packet_delete_reply)                               \
5140 _(policer_classify_set_interface_reply)                 \
5141 _(set_ipfix_exporter_reply)                             \
5142 _(set_ipfix_classify_stream_reply)                      \
5143 _(ipfix_classify_table_add_del_reply)                   \
5144 _(flow_classify_set_interface_reply)                    \
5145 _(sw_interface_span_enable_disable_reply)               \
5146 _(pg_capture_reply)                                     \
5147 _(pg_enable_disable_reply)                              \
5148 _(ip_source_and_port_range_check_add_del_reply)         \
5149 _(ip_source_and_port_range_check_interface_add_del_reply)\
5150 _(delete_subif_reply)                                   \
5151 _(l2_interface_pbb_tag_rewrite_reply)                   \
5152 _(set_punt_reply)                                       \
5153 _(feature_enable_disable_reply)                         \
5154 _(feature_gso_enable_disable_reply)                     \
5155 _(sw_interface_tag_add_del_reply)                       \
5156 _(sw_interface_add_del_mac_address_reply)               \
5157 _(hw_interface_set_mtu_reply)                           \
5158 _(p2p_ethernet_add_reply)                               \
5159 _(p2p_ethernet_del_reply)                               \
5160 _(lldp_config_reply)                                    \
5161 _(sw_interface_set_lldp_reply)                          \
5162 _(tcp_configure_src_addresses_reply)                    \
5163 _(session_rule_add_del_reply)                           \
5164 _(ip_container_proxy_add_del_reply)                     \
5165 _(output_acl_set_interface_reply)                       \
5166 _(qos_record_enable_disable_reply)
5167
5168 #define _(n)                                    \
5169     static void vl_api_##n##_t_handler          \
5170     (vl_api_##n##_t * mp)                       \
5171     {                                           \
5172         vat_main_t * vam = &vat_main;           \
5173         i32 retval = ntohl(mp->retval);         \
5174         if (vam->async_mode) {                  \
5175             vam->async_errors += (retval < 0);  \
5176         } else {                                \
5177             vam->retval = retval;               \
5178             vam->result_ready = 1;              \
5179         }                                       \
5180     }
5181 foreach_standard_reply_retval_handler;
5182 #undef _
5183
5184 #define _(n)                                    \
5185     static void vl_api_##n##_t_handler_json     \
5186     (vl_api_##n##_t * mp)                       \
5187     {                                           \
5188         vat_main_t * vam = &vat_main;           \
5189         vat_json_node_t node;                   \
5190         vat_json_init_object(&node);            \
5191         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5192         vat_json_print(vam->ofp, &node);        \
5193         vam->retval = ntohl(mp->retval);        \
5194         vam->result_ready = 1;                  \
5195     }
5196 foreach_standard_reply_retval_handler;
5197 #undef _
5198
5199 /*
5200  * Table of message reply handlers, must include boilerplate handlers
5201  * we just generated
5202  */
5203
5204 #define foreach_vpe_api_reply_msg                                       \
5205 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5206 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5207 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5208 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5209 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5210 _(CLI_REPLY, cli_reply)                                                 \
5211 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5212 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5213   sw_interface_add_del_address_reply)                                   \
5214 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5215 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5216 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5217 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5218 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5219 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5220 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5221 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5222 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5223 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5224   sw_interface_set_l2_xconnect_reply)                                   \
5225 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5226   sw_interface_set_l2_bridge_reply)                                     \
5227 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5228 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5229 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5230 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5231 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5232 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5233 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5234 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5235 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5236 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5237 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5238 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5239 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5240 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5241 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5242 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5243 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5244 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5245 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5246 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5247 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5248 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5249 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5250 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5251 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5252 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5253 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5254 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5255 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5256 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5257 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5258 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5259 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5260 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5261   sw_interface_set_unnumbered_reply)                                    \
5262 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5263 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5264 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5265 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5266   sw_interface_ip6_enable_disable_reply)                                \
5267 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5268 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5269 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5270 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5271 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5272 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5273 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5274 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5275 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5276 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5277 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5278 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5279 classify_set_interface_ip_table_reply)                                  \
5280 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5281   classify_set_interface_l2_tables_reply)                               \
5282 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5283 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5284 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5285 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5286 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5287   l2tpv3_interface_enable_disable_reply)                                \
5288 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5289 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5290 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5291 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5292 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5293 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5294 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5295 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5296 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5297 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5298 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5299 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5300 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5301 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5302 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5303 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5304 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5305 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5306 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5307 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5308 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5309 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5310 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5311 _(L2_MACS_EVENT, l2_macs_event)                                         \
5312 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5313 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5314 _(IP_DETAILS, ip_details)                                               \
5315 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5316 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5317 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5318 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5319 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5320 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5321 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5322 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5323 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5324 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5325 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5326 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5327 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5328 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5329 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5330 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5331 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5332 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5333 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5334 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5335 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5336 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5337 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5338 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5339 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5340 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5341 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5342 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5343   one_map_register_enable_disable_reply)                                \
5344 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5345 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5346 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5347 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5348   one_map_register_fallback_threshold_reply)                            \
5349 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5350   one_rloc_probe_enable_disable_reply)                                  \
5351 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5352 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5353 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5354 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5355 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5356 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5357 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5358 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5359 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5360 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5361 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5362 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5363 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5364 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5365 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5366 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5367   show_one_stats_enable_disable_reply)                                  \
5368 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5369 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5370 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5371 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5372 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5373 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5374 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5375 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5376   one_enable_disable_pitr_mode_reply)                                   \
5377 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5378   one_enable_disable_petr_mode_reply)                                   \
5379 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5380 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5381 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5382 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5383 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5384 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5385 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5386 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5387 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5388 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5389 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5390 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5391   gpe_add_del_native_fwd_rpath_reply)                                   \
5392 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5393   gpe_fwd_entry_path_details)                                           \
5394 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5395 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5396   one_add_del_map_request_itr_rlocs_reply)                              \
5397 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5398   one_get_map_request_itr_rlocs_reply)                                  \
5399 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5400 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5401 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5402 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5403 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5404 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5405   show_one_map_register_state_reply)                                    \
5406 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5407 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5408   show_one_map_register_fallback_threshold_reply)                       \
5409 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5410 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5411 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5412 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5413 _(POLICER_DETAILS, policer_details)                                     \
5414 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5415 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5416 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5417 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5418 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5419 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5420 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5421 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5422 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5423 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5424 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5425 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5426 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5427 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5428 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5429 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5430 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5431 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5432 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5433 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5434 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5435 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5436 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5437 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5438  ip_source_and_port_range_check_add_del_reply)                          \
5439 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5440  ip_source_and_port_range_check_interface_add_del_reply)                \
5441 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5442 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5443 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5444 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5445 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5446 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5447 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5448 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5449 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5450 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5451 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5452 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5453 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5454 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5455 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5456 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5457 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5458 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5459 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5460 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5461 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5462 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5463 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5464
5465 #define foreach_standalone_reply_msg                                    \
5466 _(SW_INTERFACE_EVENT, sw_interface_event)
5467
5468 typedef struct
5469 {
5470   u8 *name;
5471   u32 value;
5472 } name_sort_t;
5473
5474 #define STR_VTR_OP_CASE(op)     \
5475     case L2_VTR_ ## op:         \
5476         return "" # op;
5477
5478 static const char *
5479 str_vtr_op (u32 vtr_op)
5480 {
5481   switch (vtr_op)
5482     {
5483       STR_VTR_OP_CASE (DISABLED);
5484       STR_VTR_OP_CASE (PUSH_1);
5485       STR_VTR_OP_CASE (PUSH_2);
5486       STR_VTR_OP_CASE (POP_1);
5487       STR_VTR_OP_CASE (POP_2);
5488       STR_VTR_OP_CASE (TRANSLATE_1_1);
5489       STR_VTR_OP_CASE (TRANSLATE_1_2);
5490       STR_VTR_OP_CASE (TRANSLATE_2_1);
5491       STR_VTR_OP_CASE (TRANSLATE_2_2);
5492     }
5493
5494   return "UNKNOWN";
5495 }
5496
5497 static int
5498 dump_sub_interface_table (vat_main_t * vam)
5499 {
5500   const sw_interface_subif_t *sub = NULL;
5501
5502   if (vam->json_output)
5503     {
5504       clib_warning
5505         ("JSON output supported only for VPE API calls and dump_stats_table");
5506       return -99;
5507     }
5508
5509   print (vam->ofp,
5510          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5511          "Interface", "sw_if_index",
5512          "sub id", "dot1ad", "tags", "outer id",
5513          "inner id", "exact", "default", "outer any", "inner any");
5514
5515   vec_foreach (sub, vam->sw_if_subif_table)
5516   {
5517     print (vam->ofp,
5518            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5519            sub->interface_name,
5520            sub->sw_if_index,
5521            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5522            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5523            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5524            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5525     if (sub->vtr_op != L2_VTR_DISABLED)
5526       {
5527         print (vam->ofp,
5528                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5529                "tag1: %d tag2: %d ]",
5530                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5531                sub->vtr_tag1, sub->vtr_tag2);
5532       }
5533   }
5534
5535   return 0;
5536 }
5537
5538 static int
5539 name_sort_cmp (void *a1, void *a2)
5540 {
5541   name_sort_t *n1 = a1;
5542   name_sort_t *n2 = a2;
5543
5544   return strcmp ((char *) n1->name, (char *) n2->name);
5545 }
5546
5547 static int
5548 dump_interface_table (vat_main_t * vam)
5549 {
5550   hash_pair_t *p;
5551   name_sort_t *nses = 0, *ns;
5552
5553   if (vam->json_output)
5554     {
5555       clib_warning
5556         ("JSON output supported only for VPE API calls and dump_stats_table");
5557       return -99;
5558     }
5559
5560   /* *INDENT-OFF* */
5561   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5562   ({
5563     vec_add2 (nses, ns, 1);
5564     ns->name = (u8 *)(p->key);
5565     ns->value = (u32) p->value[0];
5566   }));
5567   /* *INDENT-ON* */
5568
5569   vec_sort_with_function (nses, name_sort_cmp);
5570
5571   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5572   vec_foreach (ns, nses)
5573   {
5574     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5575   }
5576   vec_free (nses);
5577   return 0;
5578 }
5579
5580 static int
5581 dump_ip_table (vat_main_t * vam, int is_ipv6)
5582 {
5583   const ip_details_t *det = NULL;
5584   const ip_address_details_t *address = NULL;
5585   u32 i = ~0;
5586
5587   print (vam->ofp, "%-12s", "sw_if_index");
5588
5589   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5590   {
5591     i++;
5592     if (!det->present)
5593       {
5594         continue;
5595       }
5596     print (vam->ofp, "%-12d", i);
5597     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5598     if (!det->addr)
5599       {
5600         continue;
5601       }
5602     vec_foreach (address, det->addr)
5603     {
5604       print (vam->ofp,
5605              "            %-30U%-13d",
5606              is_ipv6 ? format_ip6_address : format_ip4_address,
5607              address->ip, address->prefix_length);
5608     }
5609   }
5610
5611   return 0;
5612 }
5613
5614 static int
5615 dump_ipv4_table (vat_main_t * vam)
5616 {
5617   if (vam->json_output)
5618     {
5619       clib_warning
5620         ("JSON output supported only for VPE API calls and dump_stats_table");
5621       return -99;
5622     }
5623
5624   return dump_ip_table (vam, 0);
5625 }
5626
5627 static int
5628 dump_ipv6_table (vat_main_t * vam)
5629 {
5630   if (vam->json_output)
5631     {
5632       clib_warning
5633         ("JSON output supported only for VPE API calls and dump_stats_table");
5634       return -99;
5635     }
5636
5637   return dump_ip_table (vam, 1);
5638 }
5639
5640 /*
5641  * Pass CLI buffers directly in the CLI_INBAND API message,
5642  * instead of an additional shared memory area.
5643  */
5644 static int
5645 exec_inband (vat_main_t * vam)
5646 {
5647   vl_api_cli_inband_t *mp;
5648   unformat_input_t *i = vam->input;
5649   int ret;
5650
5651   if (vec_len (i->buffer) == 0)
5652     return -1;
5653
5654   if (vam->exec_mode == 0 && unformat (i, "mode"))
5655     {
5656       vam->exec_mode = 1;
5657       return 0;
5658     }
5659   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5660     {
5661       vam->exec_mode = 0;
5662       return 0;
5663     }
5664
5665   /*
5666    * In order for the CLI command to work, it
5667    * must be a vector ending in \n, not a C-string ending
5668    * in \n\0.
5669    */
5670   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5671   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5672
5673   S (mp);
5674   W (ret);
5675   /* json responses may or may not include a useful reply... */
5676   if (vec_len (vam->cmd_reply))
5677     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5678   return ret;
5679 }
5680
5681 int
5682 exec (vat_main_t * vam)
5683 {
5684   return exec_inband (vam);
5685 }
5686
5687 static int
5688 api_create_loopback (vat_main_t * vam)
5689 {
5690   unformat_input_t *i = vam->input;
5691   vl_api_create_loopback_t *mp;
5692   vl_api_create_loopback_instance_t *mp_lbi;
5693   u8 mac_address[6];
5694   u8 mac_set = 0;
5695   u8 is_specified = 0;
5696   u32 user_instance = 0;
5697   int ret;
5698
5699   clib_memset (mac_address, 0, sizeof (mac_address));
5700
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5704         mac_set = 1;
5705       if (unformat (i, "instance %d", &user_instance))
5706         is_specified = 1;
5707       else
5708         break;
5709     }
5710
5711   if (is_specified)
5712     {
5713       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5714       mp_lbi->is_specified = is_specified;
5715       if (is_specified)
5716         mp_lbi->user_instance = htonl (user_instance);
5717       if (mac_set)
5718         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5719       S (mp_lbi);
5720     }
5721   else
5722     {
5723       /* Construct the API message */
5724       M (CREATE_LOOPBACK, mp);
5725       if (mac_set)
5726         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5727       S (mp);
5728     }
5729
5730   W (ret);
5731   return ret;
5732 }
5733
5734 static int
5735 api_delete_loopback (vat_main_t * vam)
5736 {
5737   unformat_input_t *i = vam->input;
5738   vl_api_delete_loopback_t *mp;
5739   u32 sw_if_index = ~0;
5740   int ret;
5741
5742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5743     {
5744       if (unformat (i, "sw_if_index %d", &sw_if_index))
5745         ;
5746       else
5747         break;
5748     }
5749
5750   if (sw_if_index == ~0)
5751     {
5752       errmsg ("missing sw_if_index");
5753       return -99;
5754     }
5755
5756   /* Construct the API message */
5757   M (DELETE_LOOPBACK, mp);
5758   mp->sw_if_index = ntohl (sw_if_index);
5759
5760   S (mp);
5761   W (ret);
5762   return ret;
5763 }
5764
5765 static int
5766 api_want_interface_events (vat_main_t * vam)
5767 {
5768   unformat_input_t *i = vam->input;
5769   vl_api_want_interface_events_t *mp;
5770   int enable = -1;
5771   int ret;
5772
5773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774     {
5775       if (unformat (i, "enable"))
5776         enable = 1;
5777       else if (unformat (i, "disable"))
5778         enable = 0;
5779       else
5780         break;
5781     }
5782
5783   if (enable == -1)
5784     {
5785       errmsg ("missing enable|disable");
5786       return -99;
5787     }
5788
5789   M (WANT_INTERFACE_EVENTS, mp);
5790   mp->enable_disable = enable;
5791
5792   vam->interface_event_display = enable;
5793
5794   S (mp);
5795   W (ret);
5796   return ret;
5797 }
5798
5799
5800 /* Note: non-static, called once to set up the initial intfc table */
5801 int
5802 api_sw_interface_dump (vat_main_t * vam)
5803 {
5804   vl_api_sw_interface_dump_t *mp;
5805   vl_api_control_ping_t *mp_ping;
5806   hash_pair_t *p;
5807   name_sort_t *nses = 0, *ns;
5808   sw_interface_subif_t *sub = NULL;
5809   int ret;
5810
5811   /* Toss the old name table */
5812   /* *INDENT-OFF* */
5813   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5814   ({
5815     vec_add2 (nses, ns, 1);
5816     ns->name = (u8 *)(p->key);
5817     ns->value = (u32) p->value[0];
5818   }));
5819   /* *INDENT-ON* */
5820
5821   hash_free (vam->sw_if_index_by_interface_name);
5822
5823   vec_foreach (ns, nses) vec_free (ns->name);
5824
5825   vec_free (nses);
5826
5827   vec_foreach (sub, vam->sw_if_subif_table)
5828   {
5829     vec_free (sub->interface_name);
5830   }
5831   vec_free (vam->sw_if_subif_table);
5832
5833   /* recreate the interface name hash table */
5834   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5835
5836   /*
5837    * Ask for all interface names. Otherwise, the epic catalog of
5838    * name filters becomes ridiculously long, and vat ends up needing
5839    * to be taught about new interface types.
5840    */
5841   M (SW_INTERFACE_DUMP, mp);
5842   S (mp);
5843
5844   /* Use a control ping for synchronization */
5845   MPING (CONTROL_PING, mp_ping);
5846   S (mp_ping);
5847
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_sw_interface_set_flags (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_sw_interface_set_flags_t *mp;
5857   u32 sw_if_index;
5858   u8 sw_if_index_set = 0;
5859   u8 admin_up = 0;
5860   int ret;
5861
5862   /* Parse args required to build the message */
5863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5864     {
5865       if (unformat (i, "admin-up"))
5866         admin_up = 1;
5867       else if (unformat (i, "admin-down"))
5868         admin_up = 0;
5869       else
5870         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5871         sw_if_index_set = 1;
5872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5873         sw_if_index_set = 1;
5874       else
5875         break;
5876     }
5877
5878   if (sw_if_index_set == 0)
5879     {
5880       errmsg ("missing interface name or sw_if_index");
5881       return -99;
5882     }
5883
5884   /* Construct the API message */
5885   M (SW_INTERFACE_SET_FLAGS, mp);
5886   mp->sw_if_index = ntohl (sw_if_index);
5887   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5888
5889   /* send it... */
5890   S (mp);
5891
5892   /* Wait for a reply, return the good/bad news... */
5893   W (ret);
5894   return ret;
5895 }
5896
5897 static int
5898 api_sw_interface_set_rx_mode (vat_main_t * vam)
5899 {
5900   unformat_input_t *i = vam->input;
5901   vl_api_sw_interface_set_rx_mode_t *mp;
5902   u32 sw_if_index;
5903   u8 sw_if_index_set = 0;
5904   int ret;
5905   u8 queue_id_valid = 0;
5906   u32 queue_id;
5907   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5908
5909   /* Parse args required to build the message */
5910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5911     {
5912       if (unformat (i, "queue %d", &queue_id))
5913         queue_id_valid = 1;
5914       else if (unformat (i, "polling"))
5915         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5916       else if (unformat (i, "interrupt"))
5917         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5918       else if (unformat (i, "adaptive"))
5919         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5920       else
5921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5922         sw_if_index_set = 1;
5923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5924         sw_if_index_set = 1;
5925       else
5926         break;
5927     }
5928
5929   if (sw_if_index_set == 0)
5930     {
5931       errmsg ("missing interface name or sw_if_index");
5932       return -99;
5933     }
5934   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5935     {
5936       errmsg ("missing rx-mode");
5937       return -99;
5938     }
5939
5940   /* Construct the API message */
5941   M (SW_INTERFACE_SET_RX_MODE, mp);
5942   mp->sw_if_index = ntohl (sw_if_index);
5943   mp->mode = (vl_api_rx_mode_t) mode;
5944   mp->queue_id_valid = queue_id_valid;
5945   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5946
5947   /* send it... */
5948   S (mp);
5949
5950   /* Wait for a reply, return the good/bad news... */
5951   W (ret);
5952   return ret;
5953 }
5954
5955 static int
5956 api_sw_interface_set_rx_placement (vat_main_t * vam)
5957 {
5958   unformat_input_t *i = vam->input;
5959   vl_api_sw_interface_set_rx_placement_t *mp;
5960   u32 sw_if_index;
5961   u8 sw_if_index_set = 0;
5962   int ret;
5963   u8 is_main = 0;
5964   u32 queue_id, thread_index;
5965
5966   /* Parse args required to build the message */
5967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5968     {
5969       if (unformat (i, "queue %d", &queue_id))
5970         ;
5971       else if (unformat (i, "main"))
5972         is_main = 1;
5973       else if (unformat (i, "worker %d", &thread_index))
5974         ;
5975       else
5976         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5977         sw_if_index_set = 1;
5978       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5979         sw_if_index_set = 1;
5980       else
5981         break;
5982     }
5983
5984   if (sw_if_index_set == 0)
5985     {
5986       errmsg ("missing interface name or sw_if_index");
5987       return -99;
5988     }
5989
5990   if (is_main)
5991     thread_index = 0;
5992   /* Construct the API message */
5993   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5994   mp->sw_if_index = ntohl (sw_if_index);
5995   mp->worker_id = ntohl (thread_index);
5996   mp->queue_id = ntohl (queue_id);
5997   mp->is_main = is_main;
5998
5999   /* send it... */
6000   S (mp);
6001   /* Wait for a reply, return the good/bad news... */
6002   W (ret);
6003   return ret;
6004 }
6005
6006 static void vl_api_sw_interface_rx_placement_details_t_handler
6007   (vl_api_sw_interface_rx_placement_details_t * mp)
6008 {
6009   vat_main_t *vam = &vat_main;
6010   u32 worker_id = ntohl (mp->worker_id);
6011
6012   print (vam->ofp,
6013          "\n%-11d %-11s %-6d %-5d %-9s",
6014          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6015          worker_id, ntohl (mp->queue_id),
6016          (mp->mode ==
6017           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6018 }
6019
6020 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6021   (vl_api_sw_interface_rx_placement_details_t * mp)
6022 {
6023   vat_main_t *vam = &vat_main;
6024   vat_json_node_t *node = NULL;
6025
6026   if (VAT_JSON_ARRAY != vam->json_tree.type)
6027     {
6028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6029       vat_json_init_array (&vam->json_tree);
6030     }
6031   node = vat_json_array_add (&vam->json_tree);
6032
6033   vat_json_init_object (node);
6034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6035   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6036   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6037   vat_json_object_add_uint (node, "mode", mp->mode);
6038 }
6039
6040 static int
6041 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_sw_interface_rx_placement_dump_t *mp;
6045   vl_api_control_ping_t *mp_ping;
6046   int ret;
6047   u32 sw_if_index;
6048   u8 sw_if_index_set = 0;
6049
6050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6051     {
6052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6053         sw_if_index_set++;
6054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6055         sw_if_index_set++;
6056       else
6057         break;
6058     }
6059
6060   print (vam->ofp,
6061          "\n%-11s %-11s %-6s %-5s %-4s",
6062          "sw_if_index", "main/worker", "thread", "queue", "mode");
6063
6064   /* Dump Interface rx placement */
6065   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6066
6067   if (sw_if_index_set)
6068     mp->sw_if_index = htonl (sw_if_index);
6069   else
6070     mp->sw_if_index = ~0;
6071
6072   S (mp);
6073
6074   /* Use a control ping for synchronization */
6075   MPING (CONTROL_PING, mp_ping);
6076   S (mp_ping);
6077
6078   W (ret);
6079   return ret;
6080 }
6081
6082 static int
6083 api_sw_interface_clear_stats (vat_main_t * vam)
6084 {
6085   unformat_input_t *i = vam->input;
6086   vl_api_sw_interface_clear_stats_t *mp;
6087   u32 sw_if_index;
6088   u8 sw_if_index_set = 0;
6089   int ret;
6090
6091   /* Parse args required to build the message */
6092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6093     {
6094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set = 1;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set = 1;
6098       else
6099         break;
6100     }
6101
6102   /* Construct the API message */
6103   M (SW_INTERFACE_CLEAR_STATS, mp);
6104
6105   if (sw_if_index_set == 1)
6106     mp->sw_if_index = ntohl (sw_if_index);
6107   else
6108     mp->sw_if_index = ~0;
6109
6110   /* send it... */
6111   S (mp);
6112
6113   /* Wait for a reply, return the good/bad news... */
6114   W (ret);
6115   return ret;
6116 }
6117
6118 static int
6119 api_sw_interface_add_del_address (vat_main_t * vam)
6120 {
6121   unformat_input_t *i = vam->input;
6122   vl_api_sw_interface_add_del_address_t *mp;
6123   u32 sw_if_index;
6124   u8 sw_if_index_set = 0;
6125   u8 is_add = 1, del_all = 0;
6126   u32 address_length = 0;
6127   u8 v4_address_set = 0;
6128   u8 v6_address_set = 0;
6129   ip4_address_t v4address;
6130   ip6_address_t v6address;
6131   int ret;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "del-all"))
6137         del_all = 1;
6138       else if (unformat (i, "del"))
6139         is_add = 0;
6140       else
6141         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6142         sw_if_index_set = 1;
6143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6144         sw_if_index_set = 1;
6145       else if (unformat (i, "%U/%d",
6146                          unformat_ip4_address, &v4address, &address_length))
6147         v4_address_set = 1;
6148       else if (unformat (i, "%U/%d",
6149                          unformat_ip6_address, &v6address, &address_length))
6150         v6_address_set = 1;
6151       else
6152         break;
6153     }
6154
6155   if (sw_if_index_set == 0)
6156     {
6157       errmsg ("missing interface name or sw_if_index");
6158       return -99;
6159     }
6160   if (v4_address_set && v6_address_set)
6161     {
6162       errmsg ("both v4 and v6 addresses set");
6163       return -99;
6164     }
6165   if (!v4_address_set && !v6_address_set && !del_all)
6166     {
6167       errmsg ("no addresses set");
6168       return -99;
6169     }
6170
6171   /* Construct the API message */
6172   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6173
6174   mp->sw_if_index = ntohl (sw_if_index);
6175   mp->is_add = is_add;
6176   mp->del_all = del_all;
6177   if (v6_address_set)
6178     {
6179       mp->prefix.address.af = ADDRESS_IP6;
6180       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6181     }
6182   else
6183     {
6184       mp->prefix.address.af = ADDRESS_IP4;
6185       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6186     }
6187   mp->prefix.len = address_length;
6188
6189   /* send it... */
6190   S (mp);
6191
6192   /* Wait for a reply, return good/bad news  */
6193   W (ret);
6194   return ret;
6195 }
6196
6197 static int
6198 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6199 {
6200   unformat_input_t *i = vam->input;
6201   vl_api_sw_interface_set_mpls_enable_t *mp;
6202   u32 sw_if_index;
6203   u8 sw_if_index_set = 0;
6204   u8 enable = 1;
6205   int ret;
6206
6207   /* Parse args required to build the message */
6208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6209     {
6210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6211         sw_if_index_set = 1;
6212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6213         sw_if_index_set = 1;
6214       else if (unformat (i, "disable"))
6215         enable = 0;
6216       else if (unformat (i, "dis"))
6217         enable = 0;
6218       else
6219         break;
6220     }
6221
6222   if (sw_if_index_set == 0)
6223     {
6224       errmsg ("missing interface name or sw_if_index");
6225       return -99;
6226     }
6227
6228   /* Construct the API message */
6229   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6230
6231   mp->sw_if_index = ntohl (sw_if_index);
6232   mp->enable = enable;
6233
6234   /* send it... */
6235   S (mp);
6236
6237   /* Wait for a reply... */
6238   W (ret);
6239   return ret;
6240 }
6241
6242 static int
6243 api_sw_interface_set_table (vat_main_t * vam)
6244 {
6245   unformat_input_t *i = vam->input;
6246   vl_api_sw_interface_set_table_t *mp;
6247   u32 sw_if_index, vrf_id = 0;
6248   u8 sw_if_index_set = 0;
6249   u8 is_ipv6 = 0;
6250   int ret;
6251
6252   /* Parse args required to build the message */
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set = 1;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set = 1;
6259       else if (unformat (i, "vrf %d", &vrf_id))
6260         ;
6261       else if (unformat (i, "ipv6"))
6262         is_ipv6 = 1;
6263       else
6264         break;
6265     }
6266
6267   if (sw_if_index_set == 0)
6268     {
6269       errmsg ("missing interface name or sw_if_index");
6270       return -99;
6271     }
6272
6273   /* Construct the API message */
6274   M (SW_INTERFACE_SET_TABLE, mp);
6275
6276   mp->sw_if_index = ntohl (sw_if_index);
6277   mp->is_ipv6 = is_ipv6;
6278   mp->vrf_id = ntohl (vrf_id);
6279
6280   /* send it... */
6281   S (mp);
6282
6283   /* Wait for a reply... */
6284   W (ret);
6285   return ret;
6286 }
6287
6288 static void vl_api_sw_interface_get_table_reply_t_handler
6289   (vl_api_sw_interface_get_table_reply_t * mp)
6290 {
6291   vat_main_t *vam = &vat_main;
6292
6293   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6294
6295   vam->retval = ntohl (mp->retval);
6296   vam->result_ready = 1;
6297
6298 }
6299
6300 static void vl_api_sw_interface_get_table_reply_t_handler_json
6301   (vl_api_sw_interface_get_table_reply_t * mp)
6302 {
6303   vat_main_t *vam = &vat_main;
6304   vat_json_node_t node;
6305
6306   vat_json_init_object (&node);
6307   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6308   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6309
6310   vat_json_print (vam->ofp, &node);
6311   vat_json_free (&node);
6312
6313   vam->retval = ntohl (mp->retval);
6314   vam->result_ready = 1;
6315 }
6316
6317 static int
6318 api_sw_interface_get_table (vat_main_t * vam)
6319 {
6320   unformat_input_t *i = vam->input;
6321   vl_api_sw_interface_get_table_t *mp;
6322   u32 sw_if_index;
6323   u8 sw_if_index_set = 0;
6324   u8 is_ipv6 = 0;
6325   int ret;
6326
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6330         sw_if_index_set = 1;
6331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6332         sw_if_index_set = 1;
6333       else if (unformat (i, "ipv6"))
6334         is_ipv6 = 1;
6335       else
6336         break;
6337     }
6338
6339   if (sw_if_index_set == 0)
6340     {
6341       errmsg ("missing interface name or sw_if_index");
6342       return -99;
6343     }
6344
6345   M (SW_INTERFACE_GET_TABLE, mp);
6346   mp->sw_if_index = htonl (sw_if_index);
6347   mp->is_ipv6 = is_ipv6;
6348
6349   S (mp);
6350   W (ret);
6351   return ret;
6352 }
6353
6354 static int
6355 api_sw_interface_set_vpath (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_sw_interface_set_vpath_t *mp;
6359   u32 sw_if_index = 0;
6360   u8 sw_if_index_set = 0;
6361   u8 is_enable = 0;
6362   int ret;
6363
6364   /* Parse args required to build the message */
6365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6366     {
6367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6368         sw_if_index_set = 1;
6369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "enable"))
6372         is_enable = 1;
6373       else if (unformat (i, "disable"))
6374         is_enable = 0;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   /* Construct the API message */
6386   M (SW_INTERFACE_SET_VPATH, mp);
6387
6388   mp->sw_if_index = ntohl (sw_if_index);
6389   mp->enable = is_enable;
6390
6391   /* send it... */
6392   S (mp);
6393
6394   /* Wait for a reply... */
6395   W (ret);
6396   return ret;
6397 }
6398
6399 static int
6400 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6404   u32 sw_if_index = 0;
6405   u8 sw_if_index_set = 0;
6406   u8 is_enable = 1;
6407   u8 is_ipv6 = 0;
6408   int ret;
6409
6410   /* Parse args required to build the message */
6411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6412     {
6413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6414         sw_if_index_set = 1;
6415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6416         sw_if_index_set = 1;
6417       else if (unformat (i, "enable"))
6418         is_enable = 1;
6419       else if (unformat (i, "disable"))
6420         is_enable = 0;
6421       else if (unformat (i, "ip4"))
6422         is_ipv6 = 0;
6423       else if (unformat (i, "ip6"))
6424         is_ipv6 = 1;
6425       else
6426         break;
6427     }
6428
6429   if (sw_if_index_set == 0)
6430     {
6431       errmsg ("missing interface name or sw_if_index");
6432       return -99;
6433     }
6434
6435   /* Construct the API message */
6436   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6437
6438   mp->sw_if_index = ntohl (sw_if_index);
6439   mp->enable = is_enable;
6440   mp->is_ipv6 = is_ipv6;
6441
6442   /* send it... */
6443   S (mp);
6444
6445   /* Wait for a reply... */
6446   W (ret);
6447   return ret;
6448 }
6449
6450 static int
6451 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_sw_interface_set_geneve_bypass_t *mp;
6455   u32 sw_if_index = 0;
6456   u8 sw_if_index_set = 0;
6457   u8 is_enable = 1;
6458   u8 is_ipv6 = 0;
6459   int ret;
6460
6461   /* Parse args required to build the message */
6462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6463     {
6464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6465         sw_if_index_set = 1;
6466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6467         sw_if_index_set = 1;
6468       else if (unformat (i, "enable"))
6469         is_enable = 1;
6470       else if (unformat (i, "disable"))
6471         is_enable = 0;
6472       else if (unformat (i, "ip4"))
6473         is_ipv6 = 0;
6474       else if (unformat (i, "ip6"))
6475         is_ipv6 = 1;
6476       else
6477         break;
6478     }
6479
6480   if (sw_if_index_set == 0)
6481     {
6482       errmsg ("missing interface name or sw_if_index");
6483       return -99;
6484     }
6485
6486   /* Construct the API message */
6487   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6488
6489   mp->sw_if_index = ntohl (sw_if_index);
6490   mp->enable = is_enable;
6491   mp->is_ipv6 = is_ipv6;
6492
6493   /* send it... */
6494   S (mp);
6495
6496   /* Wait for a reply... */
6497   W (ret);
6498   return ret;
6499 }
6500
6501 static int
6502 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6503 {
6504   unformat_input_t *i = vam->input;
6505   vl_api_sw_interface_set_l2_xconnect_t *mp;
6506   u32 rx_sw_if_index;
6507   u8 rx_sw_if_index_set = 0;
6508   u32 tx_sw_if_index;
6509   u8 tx_sw_if_index_set = 0;
6510   u8 enable = 1;
6511   int ret;
6512
6513   /* Parse args required to build the message */
6514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6515     {
6516       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6517         rx_sw_if_index_set = 1;
6518       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6519         tx_sw_if_index_set = 1;
6520       else if (unformat (i, "rx"))
6521         {
6522           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523             {
6524               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6525                             &rx_sw_if_index))
6526                 rx_sw_if_index_set = 1;
6527             }
6528           else
6529             break;
6530         }
6531       else if (unformat (i, "tx"))
6532         {
6533           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6534             {
6535               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6536                             &tx_sw_if_index))
6537                 tx_sw_if_index_set = 1;
6538             }
6539           else
6540             break;
6541         }
6542       else if (unformat (i, "enable"))
6543         enable = 1;
6544       else if (unformat (i, "disable"))
6545         enable = 0;
6546       else
6547         break;
6548     }
6549
6550   if (rx_sw_if_index_set == 0)
6551     {
6552       errmsg ("missing rx interface name or rx_sw_if_index");
6553       return -99;
6554     }
6555
6556   if (enable && (tx_sw_if_index_set == 0))
6557     {
6558       errmsg ("missing tx interface name or tx_sw_if_index");
6559       return -99;
6560     }
6561
6562   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6563
6564   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6565   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6566   mp->enable = enable;
6567
6568   S (mp);
6569   W (ret);
6570   return ret;
6571 }
6572
6573 static int
6574 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6575 {
6576   unformat_input_t *i = vam->input;
6577   vl_api_sw_interface_set_l2_bridge_t *mp;
6578   vl_api_l2_port_type_t port_type;
6579   u32 rx_sw_if_index;
6580   u8 rx_sw_if_index_set = 0;
6581   u32 bd_id;
6582   u8 bd_id_set = 0;
6583   u32 shg = 0;
6584   u8 enable = 1;
6585   int ret;
6586
6587   port_type = L2_API_PORT_TYPE_NORMAL;
6588
6589   /* Parse args required to build the message */
6590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6591     {
6592       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6593         rx_sw_if_index_set = 1;
6594       else if (unformat (i, "bd_id %d", &bd_id))
6595         bd_id_set = 1;
6596       else
6597         if (unformat
6598             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6599         rx_sw_if_index_set = 1;
6600       else if (unformat (i, "shg %d", &shg))
6601         ;
6602       else if (unformat (i, "bvi"))
6603         port_type = L2_API_PORT_TYPE_BVI;
6604       else if (unformat (i, "uu-fwd"))
6605         port_type = L2_API_PORT_TYPE_UU_FWD;
6606       else if (unformat (i, "enable"))
6607         enable = 1;
6608       else if (unformat (i, "disable"))
6609         enable = 0;
6610       else
6611         break;
6612     }
6613
6614   if (rx_sw_if_index_set == 0)
6615     {
6616       errmsg ("missing rx interface name or sw_if_index");
6617       return -99;
6618     }
6619
6620   if (enable && (bd_id_set == 0))
6621     {
6622       errmsg ("missing bridge domain");
6623       return -99;
6624     }
6625
6626   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6627
6628   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6629   mp->bd_id = ntohl (bd_id);
6630   mp->shg = (u8) shg;
6631   mp->port_type = ntohl (port_type);
6632   mp->enable = enable;
6633
6634   S (mp);
6635   W (ret);
6636   return ret;
6637 }
6638
6639 static int
6640 api_bridge_domain_dump (vat_main_t * vam)
6641 {
6642   unformat_input_t *i = vam->input;
6643   vl_api_bridge_domain_dump_t *mp;
6644   vl_api_control_ping_t *mp_ping;
6645   u32 bd_id = ~0;
6646   int ret;
6647
6648   /* Parse args required to build the message */
6649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650     {
6651       if (unformat (i, "bd_id %d", &bd_id))
6652         ;
6653       else
6654         break;
6655     }
6656
6657   M (BRIDGE_DOMAIN_DUMP, mp);
6658   mp->bd_id = ntohl (bd_id);
6659   S (mp);
6660
6661   /* Use a control ping for synchronization */
6662   MPING (CONTROL_PING, mp_ping);
6663   S (mp_ping);
6664
6665   W (ret);
6666   return ret;
6667 }
6668
6669 static int
6670 api_bridge_domain_add_del (vat_main_t * vam)
6671 {
6672   unformat_input_t *i = vam->input;
6673   vl_api_bridge_domain_add_del_t *mp;
6674   u32 bd_id = ~0;
6675   u8 is_add = 1;
6676   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6677   u8 *bd_tag = NULL;
6678   u32 mac_age = 0;
6679   int ret;
6680
6681   /* Parse args required to build the message */
6682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683     {
6684       if (unformat (i, "bd_id %d", &bd_id))
6685         ;
6686       else if (unformat (i, "flood %d", &flood))
6687         ;
6688       else if (unformat (i, "uu-flood %d", &uu_flood))
6689         ;
6690       else if (unformat (i, "forward %d", &forward))
6691         ;
6692       else if (unformat (i, "learn %d", &learn))
6693         ;
6694       else if (unformat (i, "arp-term %d", &arp_term))
6695         ;
6696       else if (unformat (i, "mac-age %d", &mac_age))
6697         ;
6698       else if (unformat (i, "bd-tag %s", &bd_tag))
6699         ;
6700       else if (unformat (i, "del"))
6701         {
6702           is_add = 0;
6703           flood = uu_flood = forward = learn = 0;
6704         }
6705       else
6706         break;
6707     }
6708
6709   if (bd_id == ~0)
6710     {
6711       errmsg ("missing bridge domain");
6712       ret = -99;
6713       goto done;
6714     }
6715
6716   if (mac_age > 255)
6717     {
6718       errmsg ("mac age must be less than 256 ");
6719       ret = -99;
6720       goto done;
6721     }
6722
6723   if ((bd_tag) && (vec_len (bd_tag) > 63))
6724     {
6725       errmsg ("bd-tag cannot be longer than 63");
6726       ret = -99;
6727       goto done;
6728     }
6729
6730   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6731
6732   mp->bd_id = ntohl (bd_id);
6733   mp->flood = flood;
6734   mp->uu_flood = uu_flood;
6735   mp->forward = forward;
6736   mp->learn = learn;
6737   mp->arp_term = arp_term;
6738   mp->is_add = is_add;
6739   mp->mac_age = (u8) mac_age;
6740   if (bd_tag)
6741     {
6742       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6743       mp->bd_tag[vec_len (bd_tag)] = 0;
6744     }
6745   S (mp);
6746   W (ret);
6747
6748 done:
6749   vec_free (bd_tag);
6750   return ret;
6751 }
6752
6753 static int
6754 api_l2fib_flush_bd (vat_main_t * vam)
6755 {
6756   unformat_input_t *i = vam->input;
6757   vl_api_l2fib_flush_bd_t *mp;
6758   u32 bd_id = ~0;
6759   int ret;
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "bd_id %d", &bd_id));
6765       else
6766         break;
6767     }
6768
6769   if (bd_id == ~0)
6770     {
6771       errmsg ("missing bridge domain");
6772       return -99;
6773     }
6774
6775   M (L2FIB_FLUSH_BD, mp);
6776
6777   mp->bd_id = htonl (bd_id);
6778
6779   S (mp);
6780   W (ret);
6781   return ret;
6782 }
6783
6784 static int
6785 api_l2fib_flush_int (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_l2fib_flush_int_t *mp;
6789   u32 sw_if_index = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "sw_if_index %d", &sw_if_index));
6796       else
6797         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6798       else
6799         break;
6800     }
6801
6802   if (sw_if_index == ~0)
6803     {
6804       errmsg ("missing interface name or sw_if_index");
6805       return -99;
6806     }
6807
6808   M (L2FIB_FLUSH_INT, mp);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811
6812   S (mp);
6813   W (ret);
6814   return ret;
6815 }
6816
6817 static int
6818 api_l2fib_add_del (vat_main_t * vam)
6819 {
6820   unformat_input_t *i = vam->input;
6821   vl_api_l2fib_add_del_t *mp;
6822   f64 timeout;
6823   u8 mac[6] = { 0 };
6824   u8 mac_set = 0;
6825   u32 bd_id;
6826   u8 bd_id_set = 0;
6827   u32 sw_if_index = 0;
6828   u8 sw_if_index_set = 0;
6829   u8 is_add = 1;
6830   u8 static_mac = 0;
6831   u8 filter_mac = 0;
6832   u8 bvi_mac = 0;
6833   int count = 1;
6834   f64 before = 0;
6835   int j;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6841         mac_set = 1;
6842       else if (unformat (i, "bd_id %d", &bd_id))
6843         bd_id_set = 1;
6844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6845         sw_if_index_set = 1;
6846       else if (unformat (i, "sw_if"))
6847         {
6848           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6849             {
6850               if (unformat
6851                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6852                 sw_if_index_set = 1;
6853             }
6854           else
6855             break;
6856         }
6857       else if (unformat (i, "static"))
6858         static_mac = 1;
6859       else if (unformat (i, "filter"))
6860         {
6861           filter_mac = 1;
6862           static_mac = 1;
6863         }
6864       else if (unformat (i, "bvi"))
6865         {
6866           bvi_mac = 1;
6867           static_mac = 1;
6868         }
6869       else if (unformat (i, "del"))
6870         is_add = 0;
6871       else if (unformat (i, "count %d", &count))
6872         ;
6873       else
6874         break;
6875     }
6876
6877   if (mac_set == 0)
6878     {
6879       errmsg ("missing mac address");
6880       return -99;
6881     }
6882
6883   if (bd_id_set == 0)
6884     {
6885       errmsg ("missing bridge domain");
6886       return -99;
6887     }
6888
6889   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6890     {
6891       errmsg ("missing interface name or sw_if_index");
6892       return -99;
6893     }
6894
6895   if (count > 1)
6896     {
6897       /* Turn on async mode */
6898       vam->async_mode = 1;
6899       vam->async_errors = 0;
6900       before = vat_time_now (vam);
6901     }
6902
6903   for (j = 0; j < count; j++)
6904     {
6905       M (L2FIB_ADD_DEL, mp);
6906
6907       clib_memcpy (mp->mac, mac, 6);
6908       mp->bd_id = ntohl (bd_id);
6909       mp->is_add = is_add;
6910       mp->sw_if_index = ntohl (sw_if_index);
6911
6912       if (is_add)
6913         {
6914           mp->static_mac = static_mac;
6915           mp->filter_mac = filter_mac;
6916           mp->bvi_mac = bvi_mac;
6917         }
6918       increment_mac_address (mac);
6919       /* send it... */
6920       S (mp);
6921     }
6922
6923   if (count > 1)
6924     {
6925       vl_api_control_ping_t *mp_ping;
6926       f64 after;
6927
6928       /* Shut off async mode */
6929       vam->async_mode = 0;
6930
6931       MPING (CONTROL_PING, mp_ping);
6932       S (mp_ping);
6933
6934       timeout = vat_time_now (vam) + 1.0;
6935       while (vat_time_now (vam) < timeout)
6936         if (vam->result_ready == 1)
6937           goto out;
6938       vam->retval = -99;
6939
6940     out:
6941       if (vam->retval == -99)
6942         errmsg ("timeout");
6943
6944       if (vam->async_errors > 0)
6945         {
6946           errmsg ("%d asynchronous errors", vam->async_errors);
6947           vam->retval = -98;
6948         }
6949       vam->async_errors = 0;
6950       after = vat_time_now (vam);
6951
6952       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6953              count, after - before, count / (after - before));
6954     }
6955   else
6956     {
6957       int ret;
6958
6959       /* Wait for a reply... */
6960       W (ret);
6961       return ret;
6962     }
6963   /* Return the good/bad news */
6964   return (vam->retval);
6965 }
6966
6967 static int
6968 api_bridge_domain_set_mac_age (vat_main_t * vam)
6969 {
6970   unformat_input_t *i = vam->input;
6971   vl_api_bridge_domain_set_mac_age_t *mp;
6972   u32 bd_id = ~0;
6973   u32 mac_age = 0;
6974   int ret;
6975
6976   /* Parse args required to build the message */
6977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978     {
6979       if (unformat (i, "bd_id %d", &bd_id));
6980       else if (unformat (i, "mac-age %d", &mac_age));
6981       else
6982         break;
6983     }
6984
6985   if (bd_id == ~0)
6986     {
6987       errmsg ("missing bridge domain");
6988       return -99;
6989     }
6990
6991   if (mac_age > 255)
6992     {
6993       errmsg ("mac age must be less than 256 ");
6994       return -99;
6995     }
6996
6997   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6998
6999   mp->bd_id = htonl (bd_id);
7000   mp->mac_age = (u8) mac_age;
7001
7002   S (mp);
7003   W (ret);
7004   return ret;
7005 }
7006
7007 static int
7008 api_l2_flags (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_l2_flags_t *mp;
7012   u32 sw_if_index;
7013   u32 flags = 0;
7014   u8 sw_if_index_set = 0;
7015   u8 is_set = 0;
7016   int ret;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "sw_if_index %d", &sw_if_index))
7022         sw_if_index_set = 1;
7023       else if (unformat (i, "sw_if"))
7024         {
7025           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7026             {
7027               if (unformat
7028                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7029                 sw_if_index_set = 1;
7030             }
7031           else
7032             break;
7033         }
7034       else if (unformat (i, "learn"))
7035         flags |= L2_LEARN;
7036       else if (unformat (i, "forward"))
7037         flags |= L2_FWD;
7038       else if (unformat (i, "flood"))
7039         flags |= L2_FLOOD;
7040       else if (unformat (i, "uu-flood"))
7041         flags |= L2_UU_FLOOD;
7042       else if (unformat (i, "arp-term"))
7043         flags |= L2_ARP_TERM;
7044       else if (unformat (i, "off"))
7045         is_set = 0;
7046       else if (unformat (i, "disable"))
7047         is_set = 0;
7048       else
7049         break;
7050     }
7051
7052   if (sw_if_index_set == 0)
7053     {
7054       errmsg ("missing interface name or sw_if_index");
7055       return -99;
7056     }
7057
7058   M (L2_FLAGS, mp);
7059
7060   mp->sw_if_index = ntohl (sw_if_index);
7061   mp->feature_bitmap = ntohl (flags);
7062   mp->is_set = is_set;
7063
7064   S (mp);
7065   W (ret);
7066   return ret;
7067 }
7068
7069 static int
7070 api_bridge_flags (vat_main_t * vam)
7071 {
7072   unformat_input_t *i = vam->input;
7073   vl_api_bridge_flags_t *mp;
7074   u32 bd_id;
7075   u8 bd_id_set = 0;
7076   u8 is_set = 1;
7077   bd_flags_t flags = 0;
7078   int ret;
7079
7080   /* Parse args required to build the message */
7081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7082     {
7083       if (unformat (i, "bd_id %d", &bd_id))
7084         bd_id_set = 1;
7085       else if (unformat (i, "learn"))
7086         flags |= BRIDGE_API_FLAG_LEARN;
7087       else if (unformat (i, "forward"))
7088         flags |= BRIDGE_API_FLAG_FWD;
7089       else if (unformat (i, "flood"))
7090         flags |= BRIDGE_API_FLAG_FLOOD;
7091       else if (unformat (i, "uu-flood"))
7092         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7093       else if (unformat (i, "arp-term"))
7094         flags |= BRIDGE_API_FLAG_ARP_TERM;
7095       else if (unformat (i, "off"))
7096         is_set = 0;
7097       else if (unformat (i, "disable"))
7098         is_set = 0;
7099       else
7100         break;
7101     }
7102
7103   if (bd_id_set == 0)
7104     {
7105       errmsg ("missing bridge domain");
7106       return -99;
7107     }
7108
7109   M (BRIDGE_FLAGS, mp);
7110
7111   mp->bd_id = ntohl (bd_id);
7112   mp->flags = ntohl (flags);
7113   mp->is_set = is_set;
7114
7115   S (mp);
7116   W (ret);
7117   return ret;
7118 }
7119
7120 static int
7121 api_bd_ip_mac_add_del (vat_main_t * vam)
7122 {
7123   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7124   vl_api_mac_address_t mac = { 0 };
7125   unformat_input_t *i = vam->input;
7126   vl_api_bd_ip_mac_add_del_t *mp;
7127   u32 bd_id;
7128   u8 is_add = 1;
7129   u8 bd_id_set = 0;
7130   u8 ip_set = 0;
7131   u8 mac_set = 0;
7132   int ret;
7133
7134
7135   /* Parse args required to build the message */
7136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137     {
7138       if (unformat (i, "bd_id %d", &bd_id))
7139         {
7140           bd_id_set++;
7141         }
7142       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7143         {
7144           ip_set++;
7145         }
7146       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7147         {
7148           mac_set++;
7149         }
7150       else if (unformat (i, "del"))
7151         is_add = 0;
7152       else
7153         break;
7154     }
7155
7156   if (bd_id_set == 0)
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161   else if (ip_set == 0)
7162     {
7163       errmsg ("missing IP address");
7164       return -99;
7165     }
7166   else if (mac_set == 0)
7167     {
7168       errmsg ("missing MAC address");
7169       return -99;
7170     }
7171
7172   M (BD_IP_MAC_ADD_DEL, mp);
7173
7174   mp->entry.bd_id = ntohl (bd_id);
7175   mp->is_add = is_add;
7176
7177   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7178   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7179
7180   S (mp);
7181   W (ret);
7182   return ret;
7183 }
7184
7185 static int
7186 api_bd_ip_mac_flush (vat_main_t * vam)
7187 {
7188   unformat_input_t *i = vam->input;
7189   vl_api_bd_ip_mac_flush_t *mp;
7190   u32 bd_id;
7191   u8 bd_id_set = 0;
7192   int ret;
7193
7194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7195     {
7196       if (unformat (i, "bd_id %d", &bd_id))
7197         {
7198           bd_id_set++;
7199         }
7200       else
7201         break;
7202     }
7203
7204   if (bd_id_set == 0)
7205     {
7206       errmsg ("missing bridge domain");
7207       return -99;
7208     }
7209
7210   M (BD_IP_MAC_FLUSH, mp);
7211
7212   mp->bd_id = ntohl (bd_id);
7213
7214   S (mp);
7215   W (ret);
7216   return ret;
7217 }
7218
7219 static void vl_api_bd_ip_mac_details_t_handler
7220   (vl_api_bd_ip_mac_details_t * mp)
7221 {
7222   vat_main_t *vam = &vat_main;
7223
7224   print (vam->ofp,
7225          "\n%-5d %U %U",
7226          ntohl (mp->entry.bd_id),
7227          format_vl_api_mac_address, mp->entry.mac,
7228          format_vl_api_address, &mp->entry.ip);
7229 }
7230
7231 static void vl_api_bd_ip_mac_details_t_handler_json
7232   (vl_api_bd_ip_mac_details_t * mp)
7233 {
7234   vat_main_t *vam = &vat_main;
7235   vat_json_node_t *node = NULL;
7236
7237   if (VAT_JSON_ARRAY != vam->json_tree.type)
7238     {
7239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7240       vat_json_init_array (&vam->json_tree);
7241     }
7242   node = vat_json_array_add (&vam->json_tree);
7243
7244   vat_json_init_object (node);
7245   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7246   vat_json_object_add_string_copy (node, "mac_address",
7247                                    format (0, "%U", format_vl_api_mac_address,
7248                                            &mp->entry.mac));
7249   u8 *ip = 0;
7250
7251   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7252   vat_json_object_add_string_copy (node, "ip_address", ip);
7253   vec_free (ip);
7254 }
7255
7256 static int
7257 api_bd_ip_mac_dump (vat_main_t * vam)
7258 {
7259   unformat_input_t *i = vam->input;
7260   vl_api_bd_ip_mac_dump_t *mp;
7261   vl_api_control_ping_t *mp_ping;
7262   int ret;
7263   u32 bd_id;
7264   u8 bd_id_set = 0;
7265
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "bd_id %d", &bd_id))
7269         {
7270           bd_id_set++;
7271         }
7272       else
7273         break;
7274     }
7275
7276   print (vam->ofp,
7277          "\n%-5s %-7s %-20s %-30s",
7278          "bd_id", "is_ipv6", "mac_address", "ip_address");
7279
7280   /* Dump Bridge Domain Ip to Mac entries */
7281   M (BD_IP_MAC_DUMP, mp);
7282
7283   if (bd_id_set)
7284     mp->bd_id = htonl (bd_id);
7285   else
7286     mp->bd_id = ~0;
7287
7288   S (mp);
7289
7290   /* Use a control ping for synchronization */
7291   MPING (CONTROL_PING, mp_ping);
7292   S (mp_ping);
7293
7294   W (ret);
7295   return ret;
7296 }
7297
7298 static int
7299 api_tap_create_v2 (vat_main_t * vam)
7300 {
7301   unformat_input_t *i = vam->input;
7302   vl_api_tap_create_v2_t *mp;
7303   u8 mac_address[6];
7304   u8 random_mac = 1;
7305   u32 id = ~0;
7306   u32 num_rx_queues = 0;
7307   u8 *host_if_name = 0;
7308   u8 host_if_name_set = 0;
7309   u8 *host_ns = 0;
7310   u8 host_ns_set = 0;
7311   u8 host_mac_addr[6];
7312   u8 host_mac_addr_set = 0;
7313   u8 *host_bridge = 0;
7314   u8 host_bridge_set = 0;
7315   u8 host_ip4_prefix_set = 0;
7316   u8 host_ip6_prefix_set = 0;
7317   ip4_address_t host_ip4_addr;
7318   ip4_address_t host_ip4_gw;
7319   u8 host_ip4_gw_set = 0;
7320   u32 host_ip4_prefix_len = 0;
7321   ip6_address_t host_ip6_addr;
7322   ip6_address_t host_ip6_gw;
7323   u8 host_ip6_gw_set = 0;
7324   u32 host_ip6_prefix_len = 0;
7325   u32 host_mtu_size = 0;
7326   u8 host_mtu_set = 0;
7327   u32 tap_flags = 0;
7328   int ret;
7329   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7330
7331   clib_memset (mac_address, 0, sizeof (mac_address));
7332
7333   /* Parse args required to build the message */
7334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7335     {
7336       if (unformat (i, "id %u", &id))
7337         ;
7338       else
7339         if (unformat
7340             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7341         random_mac = 0;
7342       else if (unformat (i, "host-if-name %s", &host_if_name))
7343         host_if_name_set = 1;
7344       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7345         ;
7346       else if (unformat (i, "host-ns %s", &host_ns))
7347         host_ns_set = 1;
7348       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7349                          host_mac_addr))
7350         host_mac_addr_set = 1;
7351       else if (unformat (i, "host-bridge %s", &host_bridge))
7352         host_bridge_set = 1;
7353       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7354                          &host_ip4_addr, &host_ip4_prefix_len))
7355         host_ip4_prefix_set = 1;
7356       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7357                          &host_ip6_addr, &host_ip6_prefix_len))
7358         host_ip6_prefix_set = 1;
7359       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7360                          &host_ip4_gw))
7361         host_ip4_gw_set = 1;
7362       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7363                          &host_ip6_gw))
7364         host_ip6_gw_set = 1;
7365       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7366         ;
7367       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7368         ;
7369       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7370         host_mtu_set = 1;
7371       else if (unformat (i, "no-gso"))
7372         tap_flags &= ~TAP_FLAG_GSO;
7373       else if (unformat (i, "gso"))
7374         tap_flags |= TAP_FLAG_GSO;
7375       else if (unformat (i, "csum-offload"))
7376         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7377       else if (unformat (i, "persist"))
7378         tap_flags |= TAP_FLAG_PERSIST;
7379       else if (unformat (i, "attach"))
7380         tap_flags |= TAP_FLAG_ATTACH;
7381       else
7382         break;
7383     }
7384
7385   if (vec_len (host_if_name) > 63)
7386     {
7387       errmsg ("tap name too long. ");
7388       return -99;
7389     }
7390   if (vec_len (host_ns) > 63)
7391     {
7392       errmsg ("host name space too long. ");
7393       return -99;
7394     }
7395   if (vec_len (host_bridge) > 63)
7396     {
7397       errmsg ("host bridge name too long. ");
7398       return -99;
7399     }
7400   if (host_ip4_prefix_len > 32)
7401     {
7402       errmsg ("host ip4 prefix length not valid. ");
7403       return -99;
7404     }
7405   if (host_ip6_prefix_len > 128)
7406     {
7407       errmsg ("host ip6 prefix length not valid. ");
7408       return -99;
7409     }
7410   if (!is_pow2 (rx_ring_sz))
7411     {
7412       errmsg ("rx ring size must be power of 2. ");
7413       return -99;
7414     }
7415   if (rx_ring_sz > 32768)
7416     {
7417       errmsg ("rx ring size must be 32768 or lower. ");
7418       return -99;
7419     }
7420   if (!is_pow2 (tx_ring_sz))
7421     {
7422       errmsg ("tx ring size must be power of 2. ");
7423       return -99;
7424     }
7425   if (tx_ring_sz > 32768)
7426     {
7427       errmsg ("tx ring size must be 32768 or lower. ");
7428       return -99;
7429     }
7430   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7431     {
7432       errmsg ("host MTU size must be in between 64 and 65355. ");
7433       return -99;
7434     }
7435
7436   /* Construct the API message */
7437   M (TAP_CREATE_V2, mp);
7438
7439   mp->id = ntohl (id);
7440   mp->use_random_mac = random_mac;
7441   mp->num_rx_queues = (u8) num_rx_queues;
7442   mp->tx_ring_sz = ntohs (tx_ring_sz);
7443   mp->rx_ring_sz = ntohs (rx_ring_sz);
7444   mp->host_mtu_set = host_mtu_set;
7445   mp->host_mtu_size = ntohl (host_mtu_size);
7446   mp->host_mac_addr_set = host_mac_addr_set;
7447   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7448   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7449   mp->host_ip4_gw_set = host_ip4_gw_set;
7450   mp->host_ip6_gw_set = host_ip6_gw_set;
7451   mp->tap_flags = ntohl (tap_flags);
7452   mp->host_namespace_set = host_ns_set;
7453   mp->host_if_name_set = host_if_name_set;
7454   mp->host_bridge_set = host_bridge_set;
7455
7456   if (random_mac == 0)
7457     clib_memcpy (mp->mac_address, mac_address, 6);
7458   if (host_mac_addr_set)
7459     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7460   if (host_if_name_set)
7461     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7462   if (host_ns_set)
7463     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7464   if (host_bridge_set)
7465     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7466   if (host_ip4_prefix_set)
7467     {
7468       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7469       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7470     }
7471   if (host_ip6_prefix_set)
7472     {
7473       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7474       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7475     }
7476   if (host_ip4_gw_set)
7477     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7478   if (host_ip6_gw_set)
7479     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7480
7481   vec_free (host_ns);
7482   vec_free (host_if_name);
7483   vec_free (host_bridge);
7484
7485   /* send it... */
7486   S (mp);
7487
7488   /* Wait for a reply... */
7489   W (ret);
7490   return ret;
7491 }
7492
7493 static int
7494 api_tap_delete_v2 (vat_main_t * vam)
7495 {
7496   unformat_input_t *i = vam->input;
7497   vl_api_tap_delete_v2_t *mp;
7498   u32 sw_if_index = ~0;
7499   u8 sw_if_index_set = 0;
7500   int ret;
7501
7502   /* Parse args required to build the message */
7503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7504     {
7505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7506         sw_if_index_set = 1;
7507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7508         sw_if_index_set = 1;
7509       else
7510         break;
7511     }
7512
7513   if (sw_if_index_set == 0)
7514     {
7515       errmsg ("missing vpp interface name. ");
7516       return -99;
7517     }
7518
7519   /* Construct the API message */
7520   M (TAP_DELETE_V2, mp);
7521
7522   mp->sw_if_index = ntohl (sw_if_index);
7523
7524   /* send it... */
7525   S (mp);
7526
7527   /* Wait for a reply... */
7528   W (ret);
7529   return ret;
7530 }
7531
7532 uword
7533 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7534 {
7535   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7536   u32 x[4];
7537
7538   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7539     return 0;
7540
7541   addr->domain = x[0];
7542   addr->bus = x[1];
7543   addr->slot = x[2];
7544   addr->function = x[3];
7545
7546   return 1;
7547 }
7548
7549 static int
7550 api_virtio_pci_create (vat_main_t * vam)
7551 {
7552   unformat_input_t *i = vam->input;
7553   vl_api_virtio_pci_create_t *mp;
7554   u8 mac_address[6];
7555   u8 random_mac = 1;
7556   u8 gso_enabled = 0;
7557   u8 checksum_offload_enabled = 0;
7558   u32 pci_addr = 0;
7559   u64 features = (u64) ~ (0ULL);
7560   int ret;
7561
7562   clib_memset (mac_address, 0, sizeof (mac_address));
7563
7564   /* Parse args required to build the message */
7565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7566     {
7567       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7568         {
7569           random_mac = 0;
7570         }
7571       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7572         ;
7573       else if (unformat (i, "features 0x%llx", &features))
7574         ;
7575       else if (unformat (i, "gso-enabled"))
7576         gso_enabled = 1;
7577       else if (unformat (i, "csum-offload-enabled"))
7578         checksum_offload_enabled = 1;
7579       else
7580         break;
7581     }
7582
7583   if (pci_addr == 0)
7584     {
7585       errmsg ("pci address must be non zero. ");
7586       return -99;
7587     }
7588
7589   /* Construct the API message */
7590   M (VIRTIO_PCI_CREATE, mp);
7591
7592   mp->use_random_mac = random_mac;
7593
7594   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7595   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7596   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7597   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7598
7599   mp->features = clib_host_to_net_u64 (features);
7600   mp->gso_enabled = gso_enabled;
7601   mp->checksum_offload_enabled = checksum_offload_enabled;
7602
7603   if (random_mac == 0)
7604     clib_memcpy (mp->mac_address, mac_address, 6);
7605
7606   /* send it... */
7607   S (mp);
7608
7609   /* Wait for a reply... */
7610   W (ret);
7611   return ret;
7612 }
7613
7614 static int
7615 api_virtio_pci_delete (vat_main_t * vam)
7616 {
7617   unformat_input_t *i = vam->input;
7618   vl_api_virtio_pci_delete_t *mp;
7619   u32 sw_if_index = ~0;
7620   u8 sw_if_index_set = 0;
7621   int ret;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else
7631         break;
7632     }
7633
7634   if (sw_if_index_set == 0)
7635     {
7636       errmsg ("missing vpp interface name. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (VIRTIO_PCI_DELETE, mp);
7642
7643   mp->sw_if_index = htonl (sw_if_index);
7644
7645   /* send it... */
7646   S (mp);
7647
7648   /* Wait for a reply... */
7649   W (ret);
7650   return ret;
7651 }
7652
7653 static int
7654 api_bond_create (vat_main_t * vam)
7655 {
7656   unformat_input_t *i = vam->input;
7657   vl_api_bond_create_t *mp;
7658   u8 mac_address[6];
7659   u8 custom_mac = 0;
7660   int ret;
7661   u8 mode;
7662   u8 lb;
7663   u8 mode_is_set = 0;
7664   u32 id = ~0;
7665   u8 numa_only = 0;
7666
7667   clib_memset (mac_address, 0, sizeof (mac_address));
7668   lb = BOND_LB_L2;
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7674         mode_is_set = 1;
7675       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7676                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7677         ;
7678       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7679                          mac_address))
7680         custom_mac = 1;
7681       else if (unformat (i, "numa-only"))
7682         numa_only = 1;
7683       else if (unformat (i, "id %u", &id))
7684         ;
7685       else
7686         break;
7687     }
7688
7689   if (mode_is_set == 0)
7690     {
7691       errmsg ("Missing bond mode. ");
7692       return -99;
7693     }
7694
7695   /* Construct the API message */
7696   M (BOND_CREATE, mp);
7697
7698   mp->use_custom_mac = custom_mac;
7699
7700   mp->mode = htonl (mode);
7701   mp->lb = htonl (lb);
7702   mp->id = htonl (id);
7703   mp->numa_only = numa_only;
7704
7705   if (custom_mac)
7706     clib_memcpy (mp->mac_address, mac_address, 6);
7707
7708   /* send it... */
7709   S (mp);
7710
7711   /* Wait for a reply... */
7712   W (ret);
7713   return ret;
7714 }
7715
7716 static int
7717 api_bond_delete (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_bond_delete_t *mp;
7721   u32 sw_if_index = ~0;
7722   u8 sw_if_index_set = 0;
7723   int ret;
7724
7725   /* Parse args required to build the message */
7726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7727     {
7728       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7729         sw_if_index_set = 1;
7730       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7731         sw_if_index_set = 1;
7732       else
7733         break;
7734     }
7735
7736   if (sw_if_index_set == 0)
7737     {
7738       errmsg ("missing vpp interface name. ");
7739       return -99;
7740     }
7741
7742   /* Construct the API message */
7743   M (BOND_DELETE, mp);
7744
7745   mp->sw_if_index = ntohl (sw_if_index);
7746
7747   /* send it... */
7748   S (mp);
7749
7750   /* Wait for a reply... */
7751   W (ret);
7752   return ret;
7753 }
7754
7755 static int
7756 api_bond_enslave (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_bond_enslave_t *mp;
7760   u32 bond_sw_if_index;
7761   int ret;
7762   u8 is_passive;
7763   u8 is_long_timeout;
7764   u32 bond_sw_if_index_is_set = 0;
7765   u32 sw_if_index;
7766   u8 sw_if_index_is_set = 0;
7767
7768   /* Parse args required to build the message */
7769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770     {
7771       if (unformat (i, "sw_if_index %d", &sw_if_index))
7772         sw_if_index_is_set = 1;
7773       else if (unformat (i, "bond %u", &bond_sw_if_index))
7774         bond_sw_if_index_is_set = 1;
7775       else if (unformat (i, "passive %d", &is_passive))
7776         ;
7777       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7778         ;
7779       else
7780         break;
7781     }
7782
7783   if (bond_sw_if_index_is_set == 0)
7784     {
7785       errmsg ("Missing bond sw_if_index. ");
7786       return -99;
7787     }
7788   if (sw_if_index_is_set == 0)
7789     {
7790       errmsg ("Missing slave sw_if_index. ");
7791       return -99;
7792     }
7793
7794   /* Construct the API message */
7795   M (BOND_ENSLAVE, mp);
7796
7797   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7798   mp->sw_if_index = ntohl (sw_if_index);
7799   mp->is_long_timeout = is_long_timeout;
7800   mp->is_passive = is_passive;
7801
7802   /* send it... */
7803   S (mp);
7804
7805   /* Wait for a reply... */
7806   W (ret);
7807   return ret;
7808 }
7809
7810 static int
7811 api_bond_detach_slave (vat_main_t * vam)
7812 {
7813   unformat_input_t *i = vam->input;
7814   vl_api_bond_detach_slave_t *mp;
7815   u32 sw_if_index = ~0;
7816   u8 sw_if_index_set = 0;
7817   int ret;
7818
7819   /* Parse args required to build the message */
7820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7823         sw_if_index_set = 1;
7824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7825         sw_if_index_set = 1;
7826       else
7827         break;
7828     }
7829
7830   if (sw_if_index_set == 0)
7831     {
7832       errmsg ("missing vpp interface name. ");
7833       return -99;
7834     }
7835
7836   /* Construct the API message */
7837   M (BOND_DETACH_SLAVE, mp);
7838
7839   mp->sw_if_index = ntohl (sw_if_index);
7840
7841   /* send it... */
7842   S (mp);
7843
7844   /* Wait for a reply... */
7845   W (ret);
7846   return ret;
7847 }
7848
7849 static int
7850 api_ip_table_add_del (vat_main_t * vam)
7851 {
7852   unformat_input_t *i = vam->input;
7853   vl_api_ip_table_add_del_t *mp;
7854   u32 table_id = ~0;
7855   u8 is_ipv6 = 0;
7856   u8 is_add = 1;
7857   int ret = 0;
7858
7859   /* Parse args required to build the message */
7860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7861     {
7862       if (unformat (i, "ipv6"))
7863         is_ipv6 = 1;
7864       else if (unformat (i, "del"))
7865         is_add = 0;
7866       else if (unformat (i, "add"))
7867         is_add = 1;
7868       else if (unformat (i, "table %d", &table_id))
7869         ;
7870       else
7871         {
7872           clib_warning ("parse error '%U'", format_unformat_error, i);
7873           return -99;
7874         }
7875     }
7876
7877   if (~0 == table_id)
7878     {
7879       errmsg ("missing table-ID");
7880       return -99;
7881     }
7882
7883   /* Construct the API message */
7884   M (IP_TABLE_ADD_DEL, mp);
7885
7886   mp->table.table_id = ntohl (table_id);
7887   mp->table.is_ip6 = is_ipv6;
7888   mp->is_add = is_add;
7889
7890   /* send it... */
7891   S (mp);
7892
7893   /* Wait for a reply... */
7894   W (ret);
7895
7896   return ret;
7897 }
7898
7899 uword
7900 unformat_fib_path (unformat_input_t * input, va_list * args)
7901 {
7902   vat_main_t *vam = va_arg (*args, vat_main_t *);
7903   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7904   u32 weight, preference;
7905   mpls_label_t out_label;
7906
7907   clib_memset (path, 0, sizeof (*path));
7908   path->weight = 1;
7909   path->sw_if_index = ~0;
7910   path->rpf_id = ~0;
7911   path->n_labels = 0;
7912
7913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7914     {
7915       if (unformat (input, "%U %U",
7916                     unformat_vl_api_ip4_address,
7917                     &path->nh.address.ip4,
7918                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7919         {
7920           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7921         }
7922       else if (unformat (input, "%U %U",
7923                          unformat_vl_api_ip6_address,
7924                          &path->nh.address.ip6,
7925                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7926         {
7927           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7928         }
7929       else if (unformat (input, "weight %u", &weight))
7930         {
7931           path->weight = weight;
7932         }
7933       else if (unformat (input, "preference %u", &preference))
7934         {
7935           path->preference = preference;
7936         }
7937       else if (unformat (input, "%U next-hop-table %d",
7938                          unformat_vl_api_ip4_address,
7939                          &path->nh.address.ip4, &path->table_id))
7940         {
7941           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7942         }
7943       else if (unformat (input, "%U next-hop-table %d",
7944                          unformat_vl_api_ip6_address,
7945                          &path->nh.address.ip6, &path->table_id))
7946         {
7947           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7948         }
7949       else if (unformat (input, "%U",
7950                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7951         {
7952           /*
7953            * the recursive next-hops are by default in the default table
7954            */
7955           path->table_id = 0;
7956           path->sw_if_index = ~0;
7957           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7958         }
7959       else if (unformat (input, "%U",
7960                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7961         {
7962           /*
7963            * the recursive next-hops are by default in the default table
7964            */
7965           path->table_id = 0;
7966           path->sw_if_index = ~0;
7967           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7968         }
7969       else if (unformat (input, "resolve-via-host"))
7970         {
7971           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7972         }
7973       else if (unformat (input, "resolve-via-attached"))
7974         {
7975           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7976         }
7977       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7978         {
7979           path->type = FIB_API_PATH_TYPE_LOCAL;
7980           path->sw_if_index = ~0;
7981           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7982         }
7983       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7984         {
7985           path->type = FIB_API_PATH_TYPE_LOCAL;
7986           path->sw_if_index = ~0;
7987           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7988         }
7989       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7990         ;
7991       else if (unformat (input, "via-label %d", &path->nh.via_label))
7992         {
7993           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7994           path->sw_if_index = ~0;
7995         }
7996       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7997         {
7998           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7999           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8000         }
8001       else if (unformat (input, "local"))
8002         {
8003           path->type = FIB_API_PATH_TYPE_LOCAL;
8004         }
8005       else if (unformat (input, "out-labels"))
8006         {
8007           while (unformat (input, "%d", &out_label))
8008             {
8009               path->label_stack[path->n_labels].label = out_label;
8010               path->label_stack[path->n_labels].is_uniform = 0;
8011               path->label_stack[path->n_labels].ttl = 64;
8012               path->n_labels++;
8013             }
8014         }
8015       else if (unformat (input, "via"))
8016         {
8017           /* new path, back up and return */
8018           unformat_put_input (input);
8019           unformat_put_input (input);
8020           unformat_put_input (input);
8021           unformat_put_input (input);
8022           break;
8023         }
8024       else
8025         {
8026           return (0);
8027         }
8028     }
8029
8030   path->proto = ntohl (path->proto);
8031   path->type = ntohl (path->type);
8032   path->flags = ntohl (path->flags);
8033   path->table_id = ntohl (path->table_id);
8034   path->sw_if_index = ntohl (path->sw_if_index);
8035
8036   return (1);
8037 }
8038
8039 static int
8040 api_ip_route_add_del (vat_main_t * vam)
8041 {
8042   unformat_input_t *i = vam->input;
8043   vl_api_ip_route_add_del_t *mp;
8044   u32 vrf_id = 0;
8045   u8 is_add = 1;
8046   u8 is_multipath = 0;
8047   u8 prefix_set = 0;
8048   u8 path_count = 0;
8049   vl_api_prefix_t pfx = { };
8050   vl_api_fib_path_t paths[8];
8051   int count = 1;
8052   int j;
8053   f64 before = 0;
8054   u32 random_add_del = 0;
8055   u32 *random_vector = 0;
8056   u32 random_seed = 0xdeaddabe;
8057
8058   /* Parse args required to build the message */
8059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8060     {
8061       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8062         prefix_set = 1;
8063       else if (unformat (i, "del"))
8064         is_add = 0;
8065       else if (unformat (i, "add"))
8066         is_add = 1;
8067       else if (unformat (i, "vrf %d", &vrf_id))
8068         ;
8069       else if (unformat (i, "count %d", &count))
8070         ;
8071       else if (unformat (i, "random"))
8072         random_add_del = 1;
8073       else if (unformat (i, "multipath"))
8074         is_multipath = 1;
8075       else if (unformat (i, "seed %d", &random_seed))
8076         ;
8077       else
8078         if (unformat
8079             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8080         {
8081           path_count++;
8082           if (8 == path_count)
8083             {
8084               errmsg ("max 8 paths");
8085               return -99;
8086             }
8087         }
8088       else
8089         {
8090           clib_warning ("parse error '%U'", format_unformat_error, i);
8091           return -99;
8092         }
8093     }
8094
8095   if (!path_count)
8096     {
8097       errmsg ("specify a path; via ...");
8098       return -99;
8099     }
8100   if (prefix_set == 0)
8101     {
8102       errmsg ("missing prefix");
8103       return -99;
8104     }
8105
8106   /* Generate a pile of unique, random routes */
8107   if (random_add_del)
8108     {
8109       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8110       u32 this_random_address;
8111       uword *random_hash;
8112
8113       random_hash = hash_create (count, sizeof (uword));
8114
8115       hash_set (random_hash, i->as_u32, 1);
8116       for (j = 0; j <= count; j++)
8117         {
8118           do
8119             {
8120               this_random_address = random_u32 (&random_seed);
8121               this_random_address =
8122                 clib_host_to_net_u32 (this_random_address);
8123             }
8124           while (hash_get (random_hash, this_random_address));
8125           vec_add1 (random_vector, this_random_address);
8126           hash_set (random_hash, this_random_address, 1);
8127         }
8128       hash_free (random_hash);
8129       set_ip4_address (&pfx.address, random_vector[0]);
8130     }
8131
8132   if (count > 1)
8133     {
8134       /* Turn on async mode */
8135       vam->async_mode = 1;
8136       vam->async_errors = 0;
8137       before = vat_time_now (vam);
8138     }
8139
8140   for (j = 0; j < count; j++)
8141     {
8142       /* Construct the API message */
8143       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8144
8145       mp->is_add = is_add;
8146       mp->is_multipath = is_multipath;
8147
8148       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8149       mp->route.table_id = ntohl (vrf_id);
8150       mp->route.n_paths = path_count;
8151
8152       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8153
8154       if (random_add_del)
8155         set_ip4_address (&pfx.address, random_vector[j + 1]);
8156       else
8157         increment_address (&pfx.address);
8158       /* send it... */
8159       S (mp);
8160       /* If we receive SIGTERM, stop now... */
8161       if (vam->do_exit)
8162         break;
8163     }
8164
8165   /* When testing multiple add/del ops, use a control-ping to sync */
8166   if (count > 1)
8167     {
8168       vl_api_control_ping_t *mp_ping;
8169       f64 after;
8170       f64 timeout;
8171
8172       /* Shut off async mode */
8173       vam->async_mode = 0;
8174
8175       MPING (CONTROL_PING, mp_ping);
8176       S (mp_ping);
8177
8178       timeout = vat_time_now (vam) + 1.0;
8179       while (vat_time_now (vam) < timeout)
8180         if (vam->result_ready == 1)
8181           goto out;
8182       vam->retval = -99;
8183
8184     out:
8185       if (vam->retval == -99)
8186         errmsg ("timeout");
8187
8188       if (vam->async_errors > 0)
8189         {
8190           errmsg ("%d asynchronous errors", vam->async_errors);
8191           vam->retval = -98;
8192         }
8193       vam->async_errors = 0;
8194       after = vat_time_now (vam);
8195
8196       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8197       if (j > 0)
8198         count = j;
8199
8200       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8201              count, after - before, count / (after - before));
8202     }
8203   else
8204     {
8205       int ret;
8206
8207       /* Wait for a reply... */
8208       W (ret);
8209       return ret;
8210     }
8211
8212   /* Return the good/bad news */
8213   return (vam->retval);
8214 }
8215
8216 static int
8217 api_ip_mroute_add_del (vat_main_t * vam)
8218 {
8219   unformat_input_t *i = vam->input;
8220   u8 path_set = 0, prefix_set = 0, is_add = 1;
8221   vl_api_ip_mroute_add_del_t *mp;
8222   mfib_entry_flags_t eflags = 0;
8223   vl_api_mfib_path_t path;
8224   vl_api_mprefix_t pfx = { };
8225   u32 vrf_id = 0;
8226   int ret;
8227
8228   /* Parse args required to build the message */
8229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8232         {
8233           prefix_set = 1;
8234           pfx.grp_address_length = htons (pfx.grp_address_length);
8235         }
8236       else if (unformat (i, "del"))
8237         is_add = 0;
8238       else if (unformat (i, "add"))
8239         is_add = 1;
8240       else if (unformat (i, "vrf %d", &vrf_id))
8241         ;
8242       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8243         path.itf_flags = htonl (path.itf_flags);
8244       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8245         ;
8246       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8247         path_set = 1;
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (prefix_set == 0)
8256     {
8257       errmsg ("missing addresses\n");
8258       return -99;
8259     }
8260   if (path_set == 0)
8261     {
8262       errmsg ("missing path\n");
8263       return -99;
8264     }
8265
8266   /* Construct the API message */
8267   M (IP_MROUTE_ADD_DEL, mp);
8268
8269   mp->is_add = is_add;
8270   mp->is_multipath = 1;
8271
8272   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8273   mp->route.table_id = htonl (vrf_id);
8274   mp->route.n_paths = 1;
8275   mp->route.entry_flags = htonl (eflags);
8276
8277   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8278
8279   /* send it... */
8280   S (mp);
8281   /* Wait for a reply... */
8282   W (ret);
8283   return ret;
8284 }
8285
8286 static int
8287 api_mpls_table_add_del (vat_main_t * vam)
8288 {
8289   unformat_input_t *i = vam->input;
8290   vl_api_mpls_table_add_del_t *mp;
8291   u32 table_id = ~0;
8292   u8 is_add = 1;
8293   int ret = 0;
8294
8295   /* Parse args required to build the message */
8296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (i, "table %d", &table_id))
8299         ;
8300       else if (unformat (i, "del"))
8301         is_add = 0;
8302       else if (unformat (i, "add"))
8303         is_add = 1;
8304       else
8305         {
8306           clib_warning ("parse error '%U'", format_unformat_error, i);
8307           return -99;
8308         }
8309     }
8310
8311   if (~0 == table_id)
8312     {
8313       errmsg ("missing table-ID");
8314       return -99;
8315     }
8316
8317   /* Construct the API message */
8318   M (MPLS_TABLE_ADD_DEL, mp);
8319
8320   mp->mt_table.mt_table_id = ntohl (table_id);
8321   mp->mt_is_add = is_add;
8322
8323   /* send it... */
8324   S (mp);
8325
8326   /* Wait for a reply... */
8327   W (ret);
8328
8329   return ret;
8330 }
8331
8332 static int
8333 api_mpls_route_add_del (vat_main_t * vam)
8334 {
8335   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8336   mpls_label_t local_label = MPLS_LABEL_INVALID;
8337   unformat_input_t *i = vam->input;
8338   vl_api_mpls_route_add_del_t *mp;
8339   vl_api_fib_path_t paths[8];
8340   int count = 1, j;
8341   f64 before = 0;
8342
8343   /* Parse args required to build the message */
8344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8345     {
8346       if (unformat (i, "%d", &local_label))
8347         ;
8348       else if (unformat (i, "eos"))
8349         is_eos = 1;
8350       else if (unformat (i, "non-eos"))
8351         is_eos = 0;
8352       else if (unformat (i, "del"))
8353         is_add = 0;
8354       else if (unformat (i, "add"))
8355         is_add = 1;
8356       else if (unformat (i, "multipath"))
8357         is_multipath = 1;
8358       else if (unformat (i, "count %d", &count))
8359         ;
8360       else
8361         if (unformat
8362             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8363         {
8364           path_count++;
8365           if (8 == path_count)
8366             {
8367               errmsg ("max 8 paths");
8368               return -99;
8369             }
8370         }
8371       else
8372         {
8373           clib_warning ("parse error '%U'", format_unformat_error, i);
8374           return -99;
8375         }
8376     }
8377
8378   if (!path_count)
8379     {
8380       errmsg ("specify a path; via ...");
8381       return -99;
8382     }
8383
8384   if (MPLS_LABEL_INVALID == local_label)
8385     {
8386       errmsg ("missing label");
8387       return -99;
8388     }
8389
8390   if (count > 1)
8391     {
8392       /* Turn on async mode */
8393       vam->async_mode = 1;
8394       vam->async_errors = 0;
8395       before = vat_time_now (vam);
8396     }
8397
8398   for (j = 0; j < count; j++)
8399     {
8400       /* Construct the API message */
8401       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8402
8403       mp->mr_is_add = is_add;
8404       mp->mr_is_multipath = is_multipath;
8405
8406       mp->mr_route.mr_label = local_label;
8407       mp->mr_route.mr_eos = is_eos;
8408       mp->mr_route.mr_table_id = 0;
8409       mp->mr_route.mr_n_paths = path_count;
8410
8411       clib_memcpy (&mp->mr_route.mr_paths, paths,
8412                    sizeof (paths[0]) * path_count);
8413
8414       local_label++;
8415
8416       /* send it... */
8417       S (mp);
8418       /* If we receive SIGTERM, stop now... */
8419       if (vam->do_exit)
8420         break;
8421     }
8422
8423   /* When testing multiple add/del ops, use a control-ping to sync */
8424   if (count > 1)
8425     {
8426       vl_api_control_ping_t *mp_ping;
8427       f64 after;
8428       f64 timeout;
8429
8430       /* Shut off async mode */
8431       vam->async_mode = 0;
8432
8433       MPING (CONTROL_PING, mp_ping);
8434       S (mp_ping);
8435
8436       timeout = vat_time_now (vam) + 1.0;
8437       while (vat_time_now (vam) < timeout)
8438         if (vam->result_ready == 1)
8439           goto out;
8440       vam->retval = -99;
8441
8442     out:
8443       if (vam->retval == -99)
8444         errmsg ("timeout");
8445
8446       if (vam->async_errors > 0)
8447         {
8448           errmsg ("%d asynchronous errors", vam->async_errors);
8449           vam->retval = -98;
8450         }
8451       vam->async_errors = 0;
8452       after = vat_time_now (vam);
8453
8454       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8455       if (j > 0)
8456         count = j;
8457
8458       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8459              count, after - before, count / (after - before));
8460     }
8461   else
8462     {
8463       int ret;
8464
8465       /* Wait for a reply... */
8466       W (ret);
8467       return ret;
8468     }
8469
8470   /* Return the good/bad news */
8471   return (vam->retval);
8472   return (0);
8473 }
8474
8475 static int
8476 api_mpls_ip_bind_unbind (vat_main_t * vam)
8477 {
8478   unformat_input_t *i = vam->input;
8479   vl_api_mpls_ip_bind_unbind_t *mp;
8480   u32 ip_table_id = 0;
8481   u8 is_bind = 1;
8482   vl_api_prefix_t pfx;
8483   u8 prefix_set = 0;
8484   mpls_label_t local_label = MPLS_LABEL_INVALID;
8485   int ret;
8486
8487   /* Parse args required to build the message */
8488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8489     {
8490       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8491         prefix_set = 1;
8492       else if (unformat (i, "%d", &local_label))
8493         ;
8494       else if (unformat (i, "table-id %d", &ip_table_id))
8495         ;
8496       else if (unformat (i, "unbind"))
8497         is_bind = 0;
8498       else if (unformat (i, "bind"))
8499         is_bind = 1;
8500       else
8501         {
8502           clib_warning ("parse error '%U'", format_unformat_error, i);
8503           return -99;
8504         }
8505     }
8506
8507   if (!prefix_set)
8508     {
8509       errmsg ("IP prefix not set");
8510       return -99;
8511     }
8512
8513   if (MPLS_LABEL_INVALID == local_label)
8514     {
8515       errmsg ("missing label");
8516       return -99;
8517     }
8518
8519   /* Construct the API message */
8520   M (MPLS_IP_BIND_UNBIND, mp);
8521
8522   mp->mb_is_bind = is_bind;
8523   mp->mb_ip_table_id = ntohl (ip_table_id);
8524   mp->mb_mpls_table_id = 0;
8525   mp->mb_label = ntohl (local_label);
8526   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8527
8528   /* send it... */
8529   S (mp);
8530
8531   /* Wait for a reply... */
8532   W (ret);
8533   return ret;
8534   return (0);
8535 }
8536
8537 static int
8538 api_sr_mpls_policy_add (vat_main_t * vam)
8539 {
8540   unformat_input_t *i = vam->input;
8541   vl_api_sr_mpls_policy_add_t *mp;
8542   u32 bsid = 0;
8543   u32 weight = 1;
8544   u8 type = 0;
8545   u8 n_segments = 0;
8546   u32 sid;
8547   u32 *segments = NULL;
8548   int ret;
8549
8550   /* Parse args required to build the message */
8551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8552     {
8553       if (unformat (i, "bsid %d", &bsid))
8554         ;
8555       else if (unformat (i, "weight %d", &weight))
8556         ;
8557       else if (unformat (i, "spray"))
8558         type = 1;
8559       else if (unformat (i, "next %d", &sid))
8560         {
8561           n_segments += 1;
8562           vec_add1 (segments, htonl (sid));
8563         }
8564       else
8565         {
8566           clib_warning ("parse error '%U'", format_unformat_error, i);
8567           return -99;
8568         }
8569     }
8570
8571   if (bsid == 0)
8572     {
8573       errmsg ("bsid not set");
8574       return -99;
8575     }
8576
8577   if (n_segments == 0)
8578     {
8579       errmsg ("no sid in segment stack");
8580       return -99;
8581     }
8582
8583   /* Construct the API message */
8584   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8585
8586   mp->bsid = htonl (bsid);
8587   mp->weight = htonl (weight);
8588   mp->is_spray = type;
8589   mp->n_segments = n_segments;
8590   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8591   vec_free (segments);
8592
8593   /* send it... */
8594   S (mp);
8595
8596   /* Wait for a reply... */
8597   W (ret);
8598   return ret;
8599 }
8600
8601 static int
8602 api_sr_mpls_policy_del (vat_main_t * vam)
8603 {
8604   unformat_input_t *i = vam->input;
8605   vl_api_sr_mpls_policy_del_t *mp;
8606   u32 bsid = 0;
8607   int ret;
8608
8609   /* Parse args required to build the message */
8610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8611     {
8612       if (unformat (i, "bsid %d", &bsid))
8613         ;
8614       else
8615         {
8616           clib_warning ("parse error '%U'", format_unformat_error, i);
8617           return -99;
8618         }
8619     }
8620
8621   if (bsid == 0)
8622     {
8623       errmsg ("bsid not set");
8624       return -99;
8625     }
8626
8627   /* Construct the API message */
8628   M (SR_MPLS_POLICY_DEL, mp);
8629
8630   mp->bsid = htonl (bsid);
8631
8632   /* send it... */
8633   S (mp);
8634
8635   /* Wait for a reply... */
8636   W (ret);
8637   return ret;
8638 }
8639
8640 static int
8641 api_bier_table_add_del (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_bier_table_add_del_t *mp;
8645   u8 is_add = 1;
8646   u32 set = 0, sub_domain = 0, hdr_len = 3;
8647   mpls_label_t local_label = MPLS_LABEL_INVALID;
8648   int ret;
8649
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "sub-domain %d", &sub_domain))
8654         ;
8655       else if (unformat (i, "set %d", &set))
8656         ;
8657       else if (unformat (i, "label %d", &local_label))
8658         ;
8659       else if (unformat (i, "hdr-len %d", &hdr_len))
8660         ;
8661       else if (unformat (i, "add"))
8662         is_add = 1;
8663       else if (unformat (i, "del"))
8664         is_add = 0;
8665       else
8666         {
8667           clib_warning ("parse error '%U'", format_unformat_error, i);
8668           return -99;
8669         }
8670     }
8671
8672   if (MPLS_LABEL_INVALID == local_label)
8673     {
8674       errmsg ("missing label\n");
8675       return -99;
8676     }
8677
8678   /* Construct the API message */
8679   M (BIER_TABLE_ADD_DEL, mp);
8680
8681   mp->bt_is_add = is_add;
8682   mp->bt_label = ntohl (local_label);
8683   mp->bt_tbl_id.bt_set = set;
8684   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8685   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8686
8687   /* send it... */
8688   S (mp);
8689
8690   /* Wait for a reply... */
8691   W (ret);
8692
8693   return (ret);
8694 }
8695
8696 static int
8697 api_bier_route_add_del (vat_main_t * vam)
8698 {
8699   unformat_input_t *i = vam->input;
8700   vl_api_bier_route_add_del_t *mp;
8701   u8 is_add = 1;
8702   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8703   ip4_address_t v4_next_hop_address;
8704   ip6_address_t v6_next_hop_address;
8705   u8 next_hop_set = 0;
8706   u8 next_hop_proto_is_ip4 = 1;
8707   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8708   int ret;
8709
8710   /* Parse args required to build the message */
8711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8712     {
8713       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8714         {
8715           next_hop_proto_is_ip4 = 1;
8716           next_hop_set = 1;
8717         }
8718       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8719         {
8720           next_hop_proto_is_ip4 = 0;
8721           next_hop_set = 1;
8722         }
8723       if (unformat (i, "sub-domain %d", &sub_domain))
8724         ;
8725       else if (unformat (i, "set %d", &set))
8726         ;
8727       else if (unformat (i, "hdr-len %d", &hdr_len))
8728         ;
8729       else if (unformat (i, "bp %d", &bp))
8730         ;
8731       else if (unformat (i, "add"))
8732         is_add = 1;
8733       else if (unformat (i, "del"))
8734         is_add = 0;
8735       else if (unformat (i, "out-label %d", &next_hop_out_label))
8736         ;
8737       else
8738         {
8739           clib_warning ("parse error '%U'", format_unformat_error, i);
8740           return -99;
8741         }
8742     }
8743
8744   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8745     {
8746       errmsg ("next hop / label set\n");
8747       return -99;
8748     }
8749   if (0 == bp)
8750     {
8751       errmsg ("bit=position not set\n");
8752       return -99;
8753     }
8754
8755   /* Construct the API message */
8756   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8757
8758   mp->br_is_add = is_add;
8759   mp->br_route.br_tbl_id.bt_set = set;
8760   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8761   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8762   mp->br_route.br_bp = ntohs (bp);
8763   mp->br_route.br_n_paths = 1;
8764   mp->br_route.br_paths[0].n_labels = 1;
8765   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8766   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8767                                     FIB_API_PATH_NH_PROTO_IP4 :
8768                                     FIB_API_PATH_NH_PROTO_IP6);
8769
8770   if (next_hop_proto_is_ip4)
8771     {
8772       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8773                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8774     }
8775   else
8776     {
8777       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8778                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8779     }
8780
8781   /* send it... */
8782   S (mp);
8783
8784   /* Wait for a reply... */
8785   W (ret);
8786
8787   return (ret);
8788 }
8789
8790 static int
8791 api_mpls_tunnel_add_del (vat_main_t * vam)
8792 {
8793   unformat_input_t *i = vam->input;
8794   vl_api_mpls_tunnel_add_del_t *mp;
8795
8796   vl_api_fib_path_t paths[8];
8797   u32 sw_if_index = ~0;
8798   u8 path_count = 0;
8799   u8 l2_only = 0;
8800   u8 is_add = 1;
8801   int ret;
8802
8803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8804     {
8805       if (unformat (i, "add"))
8806         is_add = 1;
8807       else
8808         if (unformat
8809             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8810         is_add = 0;
8811       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8812         is_add = 0;
8813       else if (unformat (i, "l2-only"))
8814         l2_only = 1;
8815       else
8816         if (unformat
8817             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8818         {
8819           path_count++;
8820           if (8 == path_count)
8821             {
8822               errmsg ("max 8 paths");
8823               return -99;
8824             }
8825         }
8826       else
8827         {
8828           clib_warning ("parse error '%U'", format_unformat_error, i);
8829           return -99;
8830         }
8831     }
8832
8833   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8834
8835   mp->mt_is_add = is_add;
8836   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8837   mp->mt_tunnel.mt_l2_only = l2_only;
8838   mp->mt_tunnel.mt_is_multicast = 0;
8839   mp->mt_tunnel.mt_n_paths = path_count;
8840
8841   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8842                sizeof (paths[0]) * path_count);
8843
8844   S (mp);
8845   W (ret);
8846   return ret;
8847 }
8848
8849 static int
8850 api_sw_interface_set_unnumbered (vat_main_t * vam)
8851 {
8852   unformat_input_t *i = vam->input;
8853   vl_api_sw_interface_set_unnumbered_t *mp;
8854   u32 sw_if_index;
8855   u32 unnum_sw_index = ~0;
8856   u8 is_add = 1;
8857   u8 sw_if_index_set = 0;
8858   int ret;
8859
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8863         sw_if_index_set = 1;
8864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8865         sw_if_index_set = 1;
8866       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8867         ;
8868       else if (unformat (i, "del"))
8869         is_add = 0;
8870       else
8871         {
8872           clib_warning ("parse error '%U'", format_unformat_error, i);
8873           return -99;
8874         }
8875     }
8876
8877   if (sw_if_index_set == 0)
8878     {
8879       errmsg ("missing interface name or sw_if_index");
8880       return -99;
8881     }
8882
8883   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8884
8885   mp->sw_if_index = ntohl (sw_if_index);
8886   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8887   mp->is_add = is_add;
8888
8889   S (mp);
8890   W (ret);
8891   return ret;
8892 }
8893
8894
8895 static int
8896 api_create_vlan_subif (vat_main_t * vam)
8897 {
8898   unformat_input_t *i = vam->input;
8899   vl_api_create_vlan_subif_t *mp;
8900   u32 sw_if_index;
8901   u8 sw_if_index_set = 0;
8902   u32 vlan_id;
8903   u8 vlan_id_set = 0;
8904   int ret;
8905
8906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8907     {
8908       if (unformat (i, "sw_if_index %d", &sw_if_index))
8909         sw_if_index_set = 1;
8910       else
8911         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8912         sw_if_index_set = 1;
8913       else if (unformat (i, "vlan %d", &vlan_id))
8914         vlan_id_set = 1;
8915       else
8916         {
8917           clib_warning ("parse error '%U'", format_unformat_error, i);
8918           return -99;
8919         }
8920     }
8921
8922   if (sw_if_index_set == 0)
8923     {
8924       errmsg ("missing interface name or sw_if_index");
8925       return -99;
8926     }
8927
8928   if (vlan_id_set == 0)
8929     {
8930       errmsg ("missing vlan_id");
8931       return -99;
8932     }
8933   M (CREATE_VLAN_SUBIF, mp);
8934
8935   mp->sw_if_index = ntohl (sw_if_index);
8936   mp->vlan_id = ntohl (vlan_id);
8937
8938   S (mp);
8939   W (ret);
8940   return ret;
8941 }
8942
8943 #define foreach_create_subif_bit                \
8944 _(no_tags)                                      \
8945 _(one_tag)                                      \
8946 _(two_tags)                                     \
8947 _(dot1ad)                                       \
8948 _(exact_match)                                  \
8949 _(default_sub)                                  \
8950 _(outer_vlan_id_any)                            \
8951 _(inner_vlan_id_any)
8952
8953 #define foreach_create_subif_flag               \
8954 _(0, "no_tags")                                 \
8955 _(1, "one_tag")                                 \
8956 _(2, "two_tags")                                \
8957 _(3, "dot1ad")                                  \
8958 _(4, "exact_match")                             \
8959 _(5, "default_sub")                             \
8960 _(6, "outer_vlan_id_any")                       \
8961 _(7, "inner_vlan_id_any")
8962
8963 static int
8964 api_create_subif (vat_main_t * vam)
8965 {
8966   unformat_input_t *i = vam->input;
8967   vl_api_create_subif_t *mp;
8968   u32 sw_if_index;
8969   u8 sw_if_index_set = 0;
8970   u32 sub_id;
8971   u8 sub_id_set = 0;
8972   u32 __attribute__ ((unused)) no_tags = 0;
8973   u32 __attribute__ ((unused)) one_tag = 0;
8974   u32 __attribute__ ((unused)) two_tags = 0;
8975   u32 __attribute__ ((unused)) dot1ad = 0;
8976   u32 __attribute__ ((unused)) exact_match = 0;
8977   u32 __attribute__ ((unused)) default_sub = 0;
8978   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8979   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8980   u32 tmp;
8981   u16 outer_vlan_id = 0;
8982   u16 inner_vlan_id = 0;
8983   int ret;
8984
8985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8986     {
8987       if (unformat (i, "sw_if_index %d", &sw_if_index))
8988         sw_if_index_set = 1;
8989       else
8990         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8991         sw_if_index_set = 1;
8992       else if (unformat (i, "sub_id %d", &sub_id))
8993         sub_id_set = 1;
8994       else if (unformat (i, "outer_vlan_id %d", &tmp))
8995         outer_vlan_id = tmp;
8996       else if (unformat (i, "inner_vlan_id %d", &tmp))
8997         inner_vlan_id = tmp;
8998
8999 #define _(a) else if (unformat (i, #a)) a = 1 ;
9000       foreach_create_subif_bit
9001 #undef _
9002         else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (sw_if_index_set == 0)
9010     {
9011       errmsg ("missing interface name or sw_if_index");
9012       return -99;
9013     }
9014
9015   if (sub_id_set == 0)
9016     {
9017       errmsg ("missing sub_id");
9018       return -99;
9019     }
9020   M (CREATE_SUBIF, mp);
9021
9022   mp->sw_if_index = ntohl (sw_if_index);
9023   mp->sub_id = ntohl (sub_id);
9024
9025 #define _(a,b) mp->sub_if_flags |= (1 << a);
9026   foreach_create_subif_flag;
9027 #undef _
9028
9029   mp->outer_vlan_id = ntohs (outer_vlan_id);
9030   mp->inner_vlan_id = ntohs (inner_vlan_id);
9031
9032   S (mp);
9033   W (ret);
9034   return ret;
9035 }
9036
9037 static int
9038 api_ip_table_replace_begin (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_ip_table_replace_begin_t *mp;
9042   u32 table_id = 0;
9043   u8 is_ipv6 = 0;
9044
9045   int ret;
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "table %d", &table_id))
9049         ;
9050       else if (unformat (i, "ipv6"))
9051         is_ipv6 = 1;
9052       else
9053         {
9054           clib_warning ("parse error '%U'", format_unformat_error, i);
9055           return -99;
9056         }
9057     }
9058
9059   M (IP_TABLE_REPLACE_BEGIN, mp);
9060
9061   mp->table.table_id = ntohl (table_id);
9062   mp->table.is_ip6 = is_ipv6;
9063
9064   S (mp);
9065   W (ret);
9066   return ret;
9067 }
9068
9069 static int
9070 api_ip_table_flush (vat_main_t * vam)
9071 {
9072   unformat_input_t *i = vam->input;
9073   vl_api_ip_table_flush_t *mp;
9074   u32 table_id = 0;
9075   u8 is_ipv6 = 0;
9076
9077   int ret;
9078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9079     {
9080       if (unformat (i, "table %d", &table_id))
9081         ;
9082       else if (unformat (i, "ipv6"))
9083         is_ipv6 = 1;
9084       else
9085         {
9086           clib_warning ("parse error '%U'", format_unformat_error, i);
9087           return -99;
9088         }
9089     }
9090
9091   M (IP_TABLE_FLUSH, mp);
9092
9093   mp->table.table_id = ntohl (table_id);
9094   mp->table.is_ip6 = is_ipv6;
9095
9096   S (mp);
9097   W (ret);
9098   return ret;
9099 }
9100
9101 static int
9102 api_ip_table_replace_end (vat_main_t * vam)
9103 {
9104   unformat_input_t *i = vam->input;
9105   vl_api_ip_table_replace_end_t *mp;
9106   u32 table_id = 0;
9107   u8 is_ipv6 = 0;
9108
9109   int ret;
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "table %d", &table_id))
9113         ;
9114       else if (unformat (i, "ipv6"))
9115         is_ipv6 = 1;
9116       else
9117         {
9118           clib_warning ("parse error '%U'", format_unformat_error, i);
9119           return -99;
9120         }
9121     }
9122
9123   M (IP_TABLE_REPLACE_END, mp);
9124
9125   mp->table.table_id = ntohl (table_id);
9126   mp->table.is_ip6 = is_ipv6;
9127
9128   S (mp);
9129   W (ret);
9130   return ret;
9131 }
9132
9133 static int
9134 api_set_ip_flow_hash (vat_main_t * vam)
9135 {
9136   unformat_input_t *i = vam->input;
9137   vl_api_set_ip_flow_hash_t *mp;
9138   u32 vrf_id = 0;
9139   u8 is_ipv6 = 0;
9140   u8 vrf_id_set = 0;
9141   u8 src = 0;
9142   u8 dst = 0;
9143   u8 sport = 0;
9144   u8 dport = 0;
9145   u8 proto = 0;
9146   u8 reverse = 0;
9147   int ret;
9148
9149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9150     {
9151       if (unformat (i, "vrf %d", &vrf_id))
9152         vrf_id_set = 1;
9153       else if (unformat (i, "ipv6"))
9154         is_ipv6 = 1;
9155       else if (unformat (i, "src"))
9156         src = 1;
9157       else if (unformat (i, "dst"))
9158         dst = 1;
9159       else if (unformat (i, "sport"))
9160         sport = 1;
9161       else if (unformat (i, "dport"))
9162         dport = 1;
9163       else if (unformat (i, "proto"))
9164         proto = 1;
9165       else if (unformat (i, "reverse"))
9166         reverse = 1;
9167
9168       else
9169         {
9170           clib_warning ("parse error '%U'", format_unformat_error, i);
9171           return -99;
9172         }
9173     }
9174
9175   if (vrf_id_set == 0)
9176     {
9177       errmsg ("missing vrf id");
9178       return -99;
9179     }
9180
9181   M (SET_IP_FLOW_HASH, mp);
9182   mp->src = src;
9183   mp->dst = dst;
9184   mp->sport = sport;
9185   mp->dport = dport;
9186   mp->proto = proto;
9187   mp->reverse = reverse;
9188   mp->vrf_id = ntohl (vrf_id);
9189   mp->is_ipv6 = is_ipv6;
9190
9191   S (mp);
9192   W (ret);
9193   return ret;
9194 }
9195
9196 static int
9197 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9198 {
9199   unformat_input_t *i = vam->input;
9200   vl_api_sw_interface_ip6_enable_disable_t *mp;
9201   u32 sw_if_index;
9202   u8 sw_if_index_set = 0;
9203   u8 enable = 0;
9204   int ret;
9205
9206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9207     {
9208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9209         sw_if_index_set = 1;
9210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9211         sw_if_index_set = 1;
9212       else if (unformat (i, "enable"))
9213         enable = 1;
9214       else if (unformat (i, "disable"))
9215         enable = 0;
9216       else
9217         {
9218           clib_warning ("parse error '%U'", format_unformat_error, i);
9219           return -99;
9220         }
9221     }
9222
9223   if (sw_if_index_set == 0)
9224     {
9225       errmsg ("missing interface name or sw_if_index");
9226       return -99;
9227     }
9228
9229   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9230
9231   mp->sw_if_index = ntohl (sw_if_index);
9232   mp->enable = enable;
9233
9234   S (mp);
9235   W (ret);
9236   return ret;
9237 }
9238
9239
9240 static int
9241 api_l2_patch_add_del (vat_main_t * vam)
9242 {
9243   unformat_input_t *i = vam->input;
9244   vl_api_l2_patch_add_del_t *mp;
9245   u32 rx_sw_if_index;
9246   u8 rx_sw_if_index_set = 0;
9247   u32 tx_sw_if_index;
9248   u8 tx_sw_if_index_set = 0;
9249   u8 is_add = 1;
9250   int ret;
9251
9252   /* Parse args required to build the message */
9253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9254     {
9255       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9256         rx_sw_if_index_set = 1;
9257       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9258         tx_sw_if_index_set = 1;
9259       else if (unformat (i, "rx"))
9260         {
9261           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9262             {
9263               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9264                             &rx_sw_if_index))
9265                 rx_sw_if_index_set = 1;
9266             }
9267           else
9268             break;
9269         }
9270       else if (unformat (i, "tx"))
9271         {
9272           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9273             {
9274               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9275                             &tx_sw_if_index))
9276                 tx_sw_if_index_set = 1;
9277             }
9278           else
9279             break;
9280         }
9281       else if (unformat (i, "del"))
9282         is_add = 0;
9283       else
9284         break;
9285     }
9286
9287   if (rx_sw_if_index_set == 0)
9288     {
9289       errmsg ("missing rx interface name or rx_sw_if_index");
9290       return -99;
9291     }
9292
9293   if (tx_sw_if_index_set == 0)
9294     {
9295       errmsg ("missing tx interface name or tx_sw_if_index");
9296       return -99;
9297     }
9298
9299   M (L2_PATCH_ADD_DEL, mp);
9300
9301   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9302   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9303   mp->is_add = is_add;
9304
9305   S (mp);
9306   W (ret);
9307   return ret;
9308 }
9309
9310 u8 is_del;
9311 u8 localsid_addr[16];
9312 u8 end_psp;
9313 u8 behavior;
9314 u32 sw_if_index;
9315 u32 vlan_index;
9316 u32 fib_table;
9317 u8 nh_addr[16];
9318
9319 static int
9320 api_sr_localsid_add_del (vat_main_t * vam)
9321 {
9322   unformat_input_t *i = vam->input;
9323   vl_api_sr_localsid_add_del_t *mp;
9324
9325   u8 is_del;
9326   ip6_address_t localsid;
9327   u8 end_psp = 0;
9328   u8 behavior = ~0;
9329   u32 sw_if_index;
9330   u32 fib_table = ~(u32) 0;
9331   ip46_address_t nh_addr;
9332   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9333
9334   bool nexthop_set = 0;
9335
9336   int ret;
9337
9338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9339     {
9340       if (unformat (i, "del"))
9341         is_del = 1;
9342       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9343       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9344         nexthop_set = 1;
9345       else if (unformat (i, "behavior %u", &behavior));
9346       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9347       else if (unformat (i, "fib-table %u", &fib_table));
9348       else if (unformat (i, "end.psp %u", &behavior));
9349       else
9350         break;
9351     }
9352
9353   M (SR_LOCALSID_ADD_DEL, mp);
9354
9355   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9356
9357   if (nexthop_set)
9358     {
9359       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9360     }
9361   mp->behavior = behavior;
9362   mp->sw_if_index = ntohl (sw_if_index);
9363   mp->fib_table = ntohl (fib_table);
9364   mp->end_psp = end_psp;
9365   mp->is_del = is_del;
9366
9367   S (mp);
9368   W (ret);
9369   return ret;
9370 }
9371
9372 static int
9373 api_ioam_enable (vat_main_t * vam)
9374 {
9375   unformat_input_t *input = vam->input;
9376   vl_api_ioam_enable_t *mp;
9377   u32 id = 0;
9378   int has_trace_option = 0;
9379   int has_pot_option = 0;
9380   int has_seqno_option = 0;
9381   int has_analyse_option = 0;
9382   int ret;
9383
9384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9385     {
9386       if (unformat (input, "trace"))
9387         has_trace_option = 1;
9388       else if (unformat (input, "pot"))
9389         has_pot_option = 1;
9390       else if (unformat (input, "seqno"))
9391         has_seqno_option = 1;
9392       else if (unformat (input, "analyse"))
9393         has_analyse_option = 1;
9394       else
9395         break;
9396     }
9397   M (IOAM_ENABLE, mp);
9398   mp->id = htons (id);
9399   mp->seqno = has_seqno_option;
9400   mp->analyse = has_analyse_option;
9401   mp->pot_enable = has_pot_option;
9402   mp->trace_enable = has_trace_option;
9403
9404   S (mp);
9405   W (ret);
9406   return ret;
9407 }
9408
9409
9410 static int
9411 api_ioam_disable (vat_main_t * vam)
9412 {
9413   vl_api_ioam_disable_t *mp;
9414   int ret;
9415
9416   M (IOAM_DISABLE, mp);
9417   S (mp);
9418   W (ret);
9419   return ret;
9420 }
9421
9422 #define foreach_tcp_proto_field                 \
9423 _(src_port)                                     \
9424 _(dst_port)
9425
9426 #define foreach_udp_proto_field                 \
9427 _(src_port)                                     \
9428 _(dst_port)
9429
9430 #define foreach_ip4_proto_field                 \
9431 _(src_address)                                  \
9432 _(dst_address)                                  \
9433 _(tos)                                          \
9434 _(length)                                       \
9435 _(fragment_id)                                  \
9436 _(ttl)                                          \
9437 _(protocol)                                     \
9438 _(checksum)
9439
9440 typedef struct
9441 {
9442   u16 src_port, dst_port;
9443 } tcpudp_header_t;
9444
9445 #if VPP_API_TEST_BUILTIN == 0
9446 uword
9447 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9448 {
9449   u8 **maskp = va_arg (*args, u8 **);
9450   u8 *mask = 0;
9451   u8 found_something = 0;
9452   tcp_header_t *tcp;
9453
9454 #define _(a) u8 a=0;
9455   foreach_tcp_proto_field;
9456 #undef _
9457
9458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9459     {
9460       if (0);
9461 #define _(a) else if (unformat (input, #a)) a=1;
9462       foreach_tcp_proto_field
9463 #undef _
9464         else
9465         break;
9466     }
9467
9468 #define _(a) found_something += a;
9469   foreach_tcp_proto_field;
9470 #undef _
9471
9472   if (found_something == 0)
9473     return 0;
9474
9475   vec_validate (mask, sizeof (*tcp) - 1);
9476
9477   tcp = (tcp_header_t *) mask;
9478
9479 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9480   foreach_tcp_proto_field;
9481 #undef _
9482
9483   *maskp = mask;
9484   return 1;
9485 }
9486
9487 uword
9488 unformat_udp_mask (unformat_input_t * input, va_list * args)
9489 {
9490   u8 **maskp = va_arg (*args, u8 **);
9491   u8 *mask = 0;
9492   u8 found_something = 0;
9493   udp_header_t *udp;
9494
9495 #define _(a) u8 a=0;
9496   foreach_udp_proto_field;
9497 #undef _
9498
9499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9500     {
9501       if (0);
9502 #define _(a) else if (unformat (input, #a)) a=1;
9503       foreach_udp_proto_field
9504 #undef _
9505         else
9506         break;
9507     }
9508
9509 #define _(a) found_something += a;
9510   foreach_udp_proto_field;
9511 #undef _
9512
9513   if (found_something == 0)
9514     return 0;
9515
9516   vec_validate (mask, sizeof (*udp) - 1);
9517
9518   udp = (udp_header_t *) mask;
9519
9520 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9521   foreach_udp_proto_field;
9522 #undef _
9523
9524   *maskp = mask;
9525   return 1;
9526 }
9527
9528 uword
9529 unformat_l4_mask (unformat_input_t * input, va_list * args)
9530 {
9531   u8 **maskp = va_arg (*args, u8 **);
9532   u16 src_port = 0, dst_port = 0;
9533   tcpudp_header_t *tcpudp;
9534
9535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9536     {
9537       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9538         return 1;
9539       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9540         return 1;
9541       else if (unformat (input, "src_port"))
9542         src_port = 0xFFFF;
9543       else if (unformat (input, "dst_port"))
9544         dst_port = 0xFFFF;
9545       else
9546         return 0;
9547     }
9548
9549   if (!src_port && !dst_port)
9550     return 0;
9551
9552   u8 *mask = 0;
9553   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9554
9555   tcpudp = (tcpudp_header_t *) mask;
9556   tcpudp->src_port = src_port;
9557   tcpudp->dst_port = dst_port;
9558
9559   *maskp = mask;
9560
9561   return 1;
9562 }
9563
9564 uword
9565 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9566 {
9567   u8 **maskp = va_arg (*args, u8 **);
9568   u8 *mask = 0;
9569   u8 found_something = 0;
9570   ip4_header_t *ip;
9571
9572 #define _(a) u8 a=0;
9573   foreach_ip4_proto_field;
9574 #undef _
9575   u8 version = 0;
9576   u8 hdr_length = 0;
9577
9578
9579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9580     {
9581       if (unformat (input, "version"))
9582         version = 1;
9583       else if (unformat (input, "hdr_length"))
9584         hdr_length = 1;
9585       else if (unformat (input, "src"))
9586         src_address = 1;
9587       else if (unformat (input, "dst"))
9588         dst_address = 1;
9589       else if (unformat (input, "proto"))
9590         protocol = 1;
9591
9592 #define _(a) else if (unformat (input, #a)) a=1;
9593       foreach_ip4_proto_field
9594 #undef _
9595         else
9596         break;
9597     }
9598
9599 #define _(a) found_something += a;
9600   foreach_ip4_proto_field;
9601 #undef _
9602
9603   if (found_something == 0)
9604     return 0;
9605
9606   vec_validate (mask, sizeof (*ip) - 1);
9607
9608   ip = (ip4_header_t *) mask;
9609
9610 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9611   foreach_ip4_proto_field;
9612 #undef _
9613
9614   ip->ip_version_and_header_length = 0;
9615
9616   if (version)
9617     ip->ip_version_and_header_length |= 0xF0;
9618
9619   if (hdr_length)
9620     ip->ip_version_and_header_length |= 0x0F;
9621
9622   *maskp = mask;
9623   return 1;
9624 }
9625
9626 #define foreach_ip6_proto_field                 \
9627 _(src_address)                                  \
9628 _(dst_address)                                  \
9629 _(payload_length)                               \
9630 _(hop_limit)                                    \
9631 _(protocol)
9632
9633 uword
9634 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9635 {
9636   u8 **maskp = va_arg (*args, u8 **);
9637   u8 *mask = 0;
9638   u8 found_something = 0;
9639   ip6_header_t *ip;
9640   u32 ip_version_traffic_class_and_flow_label;
9641
9642 #define _(a) u8 a=0;
9643   foreach_ip6_proto_field;
9644 #undef _
9645   u8 version = 0;
9646   u8 traffic_class = 0;
9647   u8 flow_label = 0;
9648
9649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (input, "version"))
9652         version = 1;
9653       else if (unformat (input, "traffic-class"))
9654         traffic_class = 1;
9655       else if (unformat (input, "flow-label"))
9656         flow_label = 1;
9657       else if (unformat (input, "src"))
9658         src_address = 1;
9659       else if (unformat (input, "dst"))
9660         dst_address = 1;
9661       else if (unformat (input, "proto"))
9662         protocol = 1;
9663
9664 #define _(a) else if (unformat (input, #a)) a=1;
9665       foreach_ip6_proto_field
9666 #undef _
9667         else
9668         break;
9669     }
9670
9671 #define _(a) found_something += a;
9672   foreach_ip6_proto_field;
9673 #undef _
9674
9675   if (found_something == 0)
9676     return 0;
9677
9678   vec_validate (mask, sizeof (*ip) - 1);
9679
9680   ip = (ip6_header_t *) mask;
9681
9682 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9683   foreach_ip6_proto_field;
9684 #undef _
9685
9686   ip_version_traffic_class_and_flow_label = 0;
9687
9688   if (version)
9689     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9690
9691   if (traffic_class)
9692     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9693
9694   if (flow_label)
9695     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9696
9697   ip->ip_version_traffic_class_and_flow_label =
9698     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9699
9700   *maskp = mask;
9701   return 1;
9702 }
9703
9704 uword
9705 unformat_l3_mask (unformat_input_t * input, va_list * args)
9706 {
9707   u8 **maskp = va_arg (*args, u8 **);
9708
9709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9710     {
9711       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9712         return 1;
9713       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9714         return 1;
9715       else
9716         break;
9717     }
9718   return 0;
9719 }
9720
9721 uword
9722 unformat_l2_mask (unformat_input_t * input, va_list * args)
9723 {
9724   u8 **maskp = va_arg (*args, u8 **);
9725   u8 *mask = 0;
9726   u8 src = 0;
9727   u8 dst = 0;
9728   u8 proto = 0;
9729   u8 tag1 = 0;
9730   u8 tag2 = 0;
9731   u8 ignore_tag1 = 0;
9732   u8 ignore_tag2 = 0;
9733   u8 cos1 = 0;
9734   u8 cos2 = 0;
9735   u8 dot1q = 0;
9736   u8 dot1ad = 0;
9737   int len = 14;
9738
9739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9740     {
9741       if (unformat (input, "src"))
9742         src = 1;
9743       else if (unformat (input, "dst"))
9744         dst = 1;
9745       else if (unformat (input, "proto"))
9746         proto = 1;
9747       else if (unformat (input, "tag1"))
9748         tag1 = 1;
9749       else if (unformat (input, "tag2"))
9750         tag2 = 1;
9751       else if (unformat (input, "ignore-tag1"))
9752         ignore_tag1 = 1;
9753       else if (unformat (input, "ignore-tag2"))
9754         ignore_tag2 = 1;
9755       else if (unformat (input, "cos1"))
9756         cos1 = 1;
9757       else if (unformat (input, "cos2"))
9758         cos2 = 1;
9759       else if (unformat (input, "dot1q"))
9760         dot1q = 1;
9761       else if (unformat (input, "dot1ad"))
9762         dot1ad = 1;
9763       else
9764         break;
9765     }
9766   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9767        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9768     return 0;
9769
9770   if (tag1 || ignore_tag1 || cos1 || dot1q)
9771     len = 18;
9772   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9773     len = 22;
9774
9775   vec_validate (mask, len - 1);
9776
9777   if (dst)
9778     clib_memset (mask, 0xff, 6);
9779
9780   if (src)
9781     clib_memset (mask + 6, 0xff, 6);
9782
9783   if (tag2 || dot1ad)
9784     {
9785       /* inner vlan tag */
9786       if (tag2)
9787         {
9788           mask[19] = 0xff;
9789           mask[18] = 0x0f;
9790         }
9791       if (cos2)
9792         mask[18] |= 0xe0;
9793       if (proto)
9794         mask[21] = mask[20] = 0xff;
9795       if (tag1)
9796         {
9797           mask[15] = 0xff;
9798           mask[14] = 0x0f;
9799         }
9800       if (cos1)
9801         mask[14] |= 0xe0;
9802       *maskp = mask;
9803       return 1;
9804     }
9805   if (tag1 | dot1q)
9806     {
9807       if (tag1)
9808         {
9809           mask[15] = 0xff;
9810           mask[14] = 0x0f;
9811         }
9812       if (cos1)
9813         mask[14] |= 0xe0;
9814       if (proto)
9815         mask[16] = mask[17] = 0xff;
9816
9817       *maskp = mask;
9818       return 1;
9819     }
9820   if (cos2)
9821     mask[18] |= 0xe0;
9822   if (cos1)
9823     mask[14] |= 0xe0;
9824   if (proto)
9825     mask[12] = mask[13] = 0xff;
9826
9827   *maskp = mask;
9828   return 1;
9829 }
9830
9831 uword
9832 unformat_classify_mask (unformat_input_t * input, va_list * args)
9833 {
9834   u8 **maskp = va_arg (*args, u8 **);
9835   u32 *skipp = va_arg (*args, u32 *);
9836   u32 *matchp = va_arg (*args, u32 *);
9837   u32 match;
9838   u8 *mask = 0;
9839   u8 *l2 = 0;
9840   u8 *l3 = 0;
9841   u8 *l4 = 0;
9842   int i;
9843
9844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9845     {
9846       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9847         ;
9848       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9849         ;
9850       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9851         ;
9852       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9853         ;
9854       else
9855         break;
9856     }
9857
9858   if (l4 && !l3)
9859     {
9860       vec_free (mask);
9861       vec_free (l2);
9862       vec_free (l4);
9863       return 0;
9864     }
9865
9866   if (mask || l2 || l3 || l4)
9867     {
9868       if (l2 || l3 || l4)
9869         {
9870           /* "With a free Ethernet header in every package" */
9871           if (l2 == 0)
9872             vec_validate (l2, 13);
9873           mask = l2;
9874           if (vec_len (l3))
9875             {
9876               vec_append (mask, l3);
9877               vec_free (l3);
9878             }
9879           if (vec_len (l4))
9880             {
9881               vec_append (mask, l4);
9882               vec_free (l4);
9883             }
9884         }
9885
9886       /* Scan forward looking for the first significant mask octet */
9887       for (i = 0; i < vec_len (mask); i++)
9888         if (mask[i])
9889           break;
9890
9891       /* compute (skip, match) params */
9892       *skipp = i / sizeof (u32x4);
9893       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9894
9895       /* Pad mask to an even multiple of the vector size */
9896       while (vec_len (mask) % sizeof (u32x4))
9897         vec_add1 (mask, 0);
9898
9899       match = vec_len (mask) / sizeof (u32x4);
9900
9901       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9902         {
9903           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9904           if (*tmp || *(tmp + 1))
9905             break;
9906           match--;
9907         }
9908       if (match == 0)
9909         clib_warning ("BUG: match 0");
9910
9911       _vec_len (mask) = match * sizeof (u32x4);
9912
9913       *matchp = match;
9914       *maskp = mask;
9915
9916       return 1;
9917     }
9918
9919   return 0;
9920 }
9921 #endif /* VPP_API_TEST_BUILTIN */
9922
9923 #define foreach_l2_next                         \
9924 _(drop, DROP)                                   \
9925 _(ethernet, ETHERNET_INPUT)                     \
9926 _(ip4, IP4_INPUT)                               \
9927 _(ip6, IP6_INPUT)
9928
9929 uword
9930 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9931 {
9932   u32 *miss_next_indexp = va_arg (*args, u32 *);
9933   u32 next_index = 0;
9934   u32 tmp;
9935
9936 #define _(n,N) \
9937   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9938   foreach_l2_next;
9939 #undef _
9940
9941   if (unformat (input, "%d", &tmp))
9942     {
9943       next_index = tmp;
9944       goto out;
9945     }
9946
9947   return 0;
9948
9949 out:
9950   *miss_next_indexp = next_index;
9951   return 1;
9952 }
9953
9954 #define foreach_ip_next                         \
9955 _(drop, DROP)                                   \
9956 _(local, LOCAL)                                 \
9957 _(rewrite, REWRITE)
9958
9959 uword
9960 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9961 {
9962   u32 *miss_next_indexp = va_arg (*args, u32 *);
9963   u32 next_index = 0;
9964   u32 tmp;
9965
9966 #define _(n,N) \
9967   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9968   foreach_ip_next;
9969 #undef _
9970
9971   if (unformat (input, "%d", &tmp))
9972     {
9973       next_index = tmp;
9974       goto out;
9975     }
9976
9977   return 0;
9978
9979 out:
9980   *miss_next_indexp = next_index;
9981   return 1;
9982 }
9983
9984 #define foreach_acl_next                        \
9985 _(deny, DENY)
9986
9987 uword
9988 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9989 {
9990   u32 *miss_next_indexp = va_arg (*args, u32 *);
9991   u32 next_index = 0;
9992   u32 tmp;
9993
9994 #define _(n,N) \
9995   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9996   foreach_acl_next;
9997 #undef _
9998
9999   if (unformat (input, "permit"))
10000     {
10001       next_index = ~0;
10002       goto out;
10003     }
10004   else if (unformat (input, "%d", &tmp))
10005     {
10006       next_index = tmp;
10007       goto out;
10008     }
10009
10010   return 0;
10011
10012 out:
10013   *miss_next_indexp = next_index;
10014   return 1;
10015 }
10016
10017 uword
10018 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10019 {
10020   u32 *r = va_arg (*args, u32 *);
10021
10022   if (unformat (input, "conform-color"))
10023     *r = POLICE_CONFORM;
10024   else if (unformat (input, "exceed-color"))
10025     *r = POLICE_EXCEED;
10026   else
10027     return 0;
10028
10029   return 1;
10030 }
10031
10032 static int
10033 api_classify_add_del_table (vat_main_t * vam)
10034 {
10035   unformat_input_t *i = vam->input;
10036   vl_api_classify_add_del_table_t *mp;
10037
10038   u32 nbuckets = 2;
10039   u32 skip = ~0;
10040   u32 match = ~0;
10041   int is_add = 1;
10042   int del_chain = 0;
10043   u32 table_index = ~0;
10044   u32 next_table_index = ~0;
10045   u32 miss_next_index = ~0;
10046   u32 memory_size = 32 << 20;
10047   u8 *mask = 0;
10048   u32 current_data_flag = 0;
10049   int current_data_offset = 0;
10050   int ret;
10051
10052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10053     {
10054       if (unformat (i, "del"))
10055         is_add = 0;
10056       else if (unformat (i, "del-chain"))
10057         {
10058           is_add = 0;
10059           del_chain = 1;
10060         }
10061       else if (unformat (i, "buckets %d", &nbuckets))
10062         ;
10063       else if (unformat (i, "memory_size %d", &memory_size))
10064         ;
10065       else if (unformat (i, "skip %d", &skip))
10066         ;
10067       else if (unformat (i, "match %d", &match))
10068         ;
10069       else if (unformat (i, "table %d", &table_index))
10070         ;
10071       else if (unformat (i, "mask %U", unformat_classify_mask,
10072                          &mask, &skip, &match))
10073         ;
10074       else if (unformat (i, "next-table %d", &next_table_index))
10075         ;
10076       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10077                          &miss_next_index))
10078         ;
10079       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10080                          &miss_next_index))
10081         ;
10082       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10083                          &miss_next_index))
10084         ;
10085       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10086         ;
10087       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10088         ;
10089       else
10090         break;
10091     }
10092
10093   if (is_add && mask == 0)
10094     {
10095       errmsg ("Mask required");
10096       return -99;
10097     }
10098
10099   if (is_add && skip == ~0)
10100     {
10101       errmsg ("skip count required");
10102       return -99;
10103     }
10104
10105   if (is_add && match == ~0)
10106     {
10107       errmsg ("match count required");
10108       return -99;
10109     }
10110
10111   if (!is_add && table_index == ~0)
10112     {
10113       errmsg ("table index required for delete");
10114       return -99;
10115     }
10116
10117   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10118
10119   mp->is_add = is_add;
10120   mp->del_chain = del_chain;
10121   mp->table_index = ntohl (table_index);
10122   mp->nbuckets = ntohl (nbuckets);
10123   mp->memory_size = ntohl (memory_size);
10124   mp->skip_n_vectors = ntohl (skip);
10125   mp->match_n_vectors = ntohl (match);
10126   mp->next_table_index = ntohl (next_table_index);
10127   mp->miss_next_index = ntohl (miss_next_index);
10128   mp->current_data_flag = ntohl (current_data_flag);
10129   mp->current_data_offset = ntohl (current_data_offset);
10130   mp->mask_len = ntohl (vec_len (mask));
10131   clib_memcpy (mp->mask, mask, vec_len (mask));
10132
10133   vec_free (mask);
10134
10135   S (mp);
10136   W (ret);
10137   return ret;
10138 }
10139
10140 #if VPP_API_TEST_BUILTIN == 0
10141 uword
10142 unformat_l4_match (unformat_input_t * input, va_list * args)
10143 {
10144   u8 **matchp = va_arg (*args, u8 **);
10145
10146   u8 *proto_header = 0;
10147   int src_port = 0;
10148   int dst_port = 0;
10149
10150   tcpudp_header_t h;
10151
10152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10153     {
10154       if (unformat (input, "src_port %d", &src_port))
10155         ;
10156       else if (unformat (input, "dst_port %d", &dst_port))
10157         ;
10158       else
10159         return 0;
10160     }
10161
10162   h.src_port = clib_host_to_net_u16 (src_port);
10163   h.dst_port = clib_host_to_net_u16 (dst_port);
10164   vec_validate (proto_header, sizeof (h) - 1);
10165   memcpy (proto_header, &h, sizeof (h));
10166
10167   *matchp = proto_header;
10168
10169   return 1;
10170 }
10171
10172 uword
10173 unformat_ip4_match (unformat_input_t * input, va_list * args)
10174 {
10175   u8 **matchp = va_arg (*args, u8 **);
10176   u8 *match = 0;
10177   ip4_header_t *ip;
10178   int version = 0;
10179   u32 version_val;
10180   int hdr_length = 0;
10181   u32 hdr_length_val;
10182   int src = 0, dst = 0;
10183   ip4_address_t src_val, dst_val;
10184   int proto = 0;
10185   u32 proto_val;
10186   int tos = 0;
10187   u32 tos_val;
10188   int length = 0;
10189   u32 length_val;
10190   int fragment_id = 0;
10191   u32 fragment_id_val;
10192   int ttl = 0;
10193   int ttl_val;
10194   int checksum = 0;
10195   u32 checksum_val;
10196
10197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10198     {
10199       if (unformat (input, "version %d", &version_val))
10200         version = 1;
10201       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10202         hdr_length = 1;
10203       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10204         src = 1;
10205       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10206         dst = 1;
10207       else if (unformat (input, "proto %d", &proto_val))
10208         proto = 1;
10209       else if (unformat (input, "tos %d", &tos_val))
10210         tos = 1;
10211       else if (unformat (input, "length %d", &length_val))
10212         length = 1;
10213       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10214         fragment_id = 1;
10215       else if (unformat (input, "ttl %d", &ttl_val))
10216         ttl = 1;
10217       else if (unformat (input, "checksum %d", &checksum_val))
10218         checksum = 1;
10219       else
10220         break;
10221     }
10222
10223   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10224       + ttl + checksum == 0)
10225     return 0;
10226
10227   /*
10228    * Aligned because we use the real comparison functions
10229    */
10230   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10231
10232   ip = (ip4_header_t *) match;
10233
10234   /* These are realistically matched in practice */
10235   if (src)
10236     ip->src_address.as_u32 = src_val.as_u32;
10237
10238   if (dst)
10239     ip->dst_address.as_u32 = dst_val.as_u32;
10240
10241   if (proto)
10242     ip->protocol = proto_val;
10243
10244
10245   /* These are not, but they're included for completeness */
10246   if (version)
10247     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10248
10249   if (hdr_length)
10250     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10251
10252   if (tos)
10253     ip->tos = tos_val;
10254
10255   if (length)
10256     ip->length = clib_host_to_net_u16 (length_val);
10257
10258   if (ttl)
10259     ip->ttl = ttl_val;
10260
10261   if (checksum)
10262     ip->checksum = clib_host_to_net_u16 (checksum_val);
10263
10264   *matchp = match;
10265   return 1;
10266 }
10267
10268 uword
10269 unformat_ip6_match (unformat_input_t * input, va_list * args)
10270 {
10271   u8 **matchp = va_arg (*args, u8 **);
10272   u8 *match = 0;
10273   ip6_header_t *ip;
10274   int version = 0;
10275   u32 version_val;
10276   u8 traffic_class = 0;
10277   u32 traffic_class_val = 0;
10278   u8 flow_label = 0;
10279   u8 flow_label_val;
10280   int src = 0, dst = 0;
10281   ip6_address_t src_val, dst_val;
10282   int proto = 0;
10283   u32 proto_val;
10284   int payload_length = 0;
10285   u32 payload_length_val;
10286   int hop_limit = 0;
10287   int hop_limit_val;
10288   u32 ip_version_traffic_class_and_flow_label;
10289
10290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10291     {
10292       if (unformat (input, "version %d", &version_val))
10293         version = 1;
10294       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10295         traffic_class = 1;
10296       else if (unformat (input, "flow_label %d", &flow_label_val))
10297         flow_label = 1;
10298       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10299         src = 1;
10300       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10301         dst = 1;
10302       else if (unformat (input, "proto %d", &proto_val))
10303         proto = 1;
10304       else if (unformat (input, "payload_length %d", &payload_length_val))
10305         payload_length = 1;
10306       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10307         hop_limit = 1;
10308       else
10309         break;
10310     }
10311
10312   if (version + traffic_class + flow_label + src + dst + proto +
10313       payload_length + hop_limit == 0)
10314     return 0;
10315
10316   /*
10317    * Aligned because we use the real comparison functions
10318    */
10319   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10320
10321   ip = (ip6_header_t *) match;
10322
10323   if (src)
10324     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10325
10326   if (dst)
10327     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10328
10329   if (proto)
10330     ip->protocol = proto_val;
10331
10332   ip_version_traffic_class_and_flow_label = 0;
10333
10334   if (version)
10335     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10336
10337   if (traffic_class)
10338     ip_version_traffic_class_and_flow_label |=
10339       (traffic_class_val & 0xFF) << 20;
10340
10341   if (flow_label)
10342     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10343
10344   ip->ip_version_traffic_class_and_flow_label =
10345     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10346
10347   if (payload_length)
10348     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10349
10350   if (hop_limit)
10351     ip->hop_limit = hop_limit_val;
10352
10353   *matchp = match;
10354   return 1;
10355 }
10356
10357 uword
10358 unformat_l3_match (unformat_input_t * input, va_list * args)
10359 {
10360   u8 **matchp = va_arg (*args, u8 **);
10361
10362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10363     {
10364       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10365         return 1;
10366       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10367         return 1;
10368       else
10369         break;
10370     }
10371   return 0;
10372 }
10373
10374 uword
10375 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10376 {
10377   u8 *tagp = va_arg (*args, u8 *);
10378   u32 tag;
10379
10380   if (unformat (input, "%d", &tag))
10381     {
10382       tagp[0] = (tag >> 8) & 0x0F;
10383       tagp[1] = tag & 0xFF;
10384       return 1;
10385     }
10386
10387   return 0;
10388 }
10389
10390 uword
10391 unformat_l2_match (unformat_input_t * input, va_list * args)
10392 {
10393   u8 **matchp = va_arg (*args, u8 **);
10394   u8 *match = 0;
10395   u8 src = 0;
10396   u8 src_val[6];
10397   u8 dst = 0;
10398   u8 dst_val[6];
10399   u8 proto = 0;
10400   u16 proto_val;
10401   u8 tag1 = 0;
10402   u8 tag1_val[2];
10403   u8 tag2 = 0;
10404   u8 tag2_val[2];
10405   int len = 14;
10406   u8 ignore_tag1 = 0;
10407   u8 ignore_tag2 = 0;
10408   u8 cos1 = 0;
10409   u8 cos2 = 0;
10410   u32 cos1_val = 0;
10411   u32 cos2_val = 0;
10412
10413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10416         src = 1;
10417       else
10418         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10419         dst = 1;
10420       else if (unformat (input, "proto %U",
10421                          unformat_ethernet_type_host_byte_order, &proto_val))
10422         proto = 1;
10423       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10424         tag1 = 1;
10425       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10426         tag2 = 1;
10427       else if (unformat (input, "ignore-tag1"))
10428         ignore_tag1 = 1;
10429       else if (unformat (input, "ignore-tag2"))
10430         ignore_tag2 = 1;
10431       else if (unformat (input, "cos1 %d", &cos1_val))
10432         cos1 = 1;
10433       else if (unformat (input, "cos2 %d", &cos2_val))
10434         cos2 = 1;
10435       else
10436         break;
10437     }
10438   if ((src + dst + proto + tag1 + tag2 +
10439        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10440     return 0;
10441
10442   if (tag1 || ignore_tag1 || cos1)
10443     len = 18;
10444   if (tag2 || ignore_tag2 || cos2)
10445     len = 22;
10446
10447   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10448
10449   if (dst)
10450     clib_memcpy (match, dst_val, 6);
10451
10452   if (src)
10453     clib_memcpy (match + 6, src_val, 6);
10454
10455   if (tag2)
10456     {
10457       /* inner vlan tag */
10458       match[19] = tag2_val[1];
10459       match[18] = tag2_val[0];
10460       if (cos2)
10461         match[18] |= (cos2_val & 0x7) << 5;
10462       if (proto)
10463         {
10464           match[21] = proto_val & 0xff;
10465           match[20] = proto_val >> 8;
10466         }
10467       if (tag1)
10468         {
10469           match[15] = tag1_val[1];
10470           match[14] = tag1_val[0];
10471         }
10472       if (cos1)
10473         match[14] |= (cos1_val & 0x7) << 5;
10474       *matchp = match;
10475       return 1;
10476     }
10477   if (tag1)
10478     {
10479       match[15] = tag1_val[1];
10480       match[14] = tag1_val[0];
10481       if (proto)
10482         {
10483           match[17] = proto_val & 0xff;
10484           match[16] = proto_val >> 8;
10485         }
10486       if (cos1)
10487         match[14] |= (cos1_val & 0x7) << 5;
10488
10489       *matchp = match;
10490       return 1;
10491     }
10492   if (cos2)
10493     match[18] |= (cos2_val & 0x7) << 5;
10494   if (cos1)
10495     match[14] |= (cos1_val & 0x7) << 5;
10496   if (proto)
10497     {
10498       match[13] = proto_val & 0xff;
10499       match[12] = proto_val >> 8;
10500     }
10501
10502   *matchp = match;
10503   return 1;
10504 }
10505
10506 uword
10507 unformat_qos_source (unformat_input_t * input, va_list * args)
10508 {
10509   int *qs = va_arg (*args, int *);
10510
10511   if (unformat (input, "ip"))
10512     *qs = QOS_SOURCE_IP;
10513   else if (unformat (input, "mpls"))
10514     *qs = QOS_SOURCE_MPLS;
10515   else if (unformat (input, "ext"))
10516     *qs = QOS_SOURCE_EXT;
10517   else if (unformat (input, "vlan"))
10518     *qs = QOS_SOURCE_VLAN;
10519   else
10520     return 0;
10521
10522   return 1;
10523 }
10524 #endif
10525
10526 uword
10527 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10528 {
10529   u8 **matchp = va_arg (*args, u8 **);
10530   u32 skip_n_vectors = va_arg (*args, u32);
10531   u32 match_n_vectors = va_arg (*args, u32);
10532
10533   u8 *match = 0;
10534   u8 *l2 = 0;
10535   u8 *l3 = 0;
10536   u8 *l4 = 0;
10537
10538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10539     {
10540       if (unformat (input, "hex %U", unformat_hex_string, &match))
10541         ;
10542       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10543         ;
10544       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10545         ;
10546       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10547         ;
10548       else
10549         break;
10550     }
10551
10552   if (l4 && !l3)
10553     {
10554       vec_free (match);
10555       vec_free (l2);
10556       vec_free (l4);
10557       return 0;
10558     }
10559
10560   if (match || l2 || l3 || l4)
10561     {
10562       if (l2 || l3 || l4)
10563         {
10564           /* "Win a free Ethernet header in every packet" */
10565           if (l2 == 0)
10566             vec_validate_aligned (l2, 13, sizeof (u32x4));
10567           match = l2;
10568           if (vec_len (l3))
10569             {
10570               vec_append_aligned (match, l3, sizeof (u32x4));
10571               vec_free (l3);
10572             }
10573           if (vec_len (l4))
10574             {
10575               vec_append_aligned (match, l4, sizeof (u32x4));
10576               vec_free (l4);
10577             }
10578         }
10579
10580       /* Make sure the vector is big enough even if key is all 0's */
10581       vec_validate_aligned
10582         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10583          sizeof (u32x4));
10584
10585       /* Set size, include skipped vectors */
10586       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10587
10588       *matchp = match;
10589
10590       return 1;
10591     }
10592
10593   return 0;
10594 }
10595
10596 static int
10597 api_classify_add_del_session (vat_main_t * vam)
10598 {
10599   unformat_input_t *i = vam->input;
10600   vl_api_classify_add_del_session_t *mp;
10601   int is_add = 1;
10602   u32 table_index = ~0;
10603   u32 hit_next_index = ~0;
10604   u32 opaque_index = ~0;
10605   u8 *match = 0;
10606   i32 advance = 0;
10607   u32 skip_n_vectors = 0;
10608   u32 match_n_vectors = 0;
10609   u32 action = 0;
10610   u32 metadata = 0;
10611   int ret;
10612
10613   /*
10614    * Warning: you have to supply skip_n and match_n
10615    * because the API client cant simply look at the classify
10616    * table object.
10617    */
10618
10619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10620     {
10621       if (unformat (i, "del"))
10622         is_add = 0;
10623       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10624                          &hit_next_index))
10625         ;
10626       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10627                          &hit_next_index))
10628         ;
10629       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10630                          &hit_next_index))
10631         ;
10632       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10633         ;
10634       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10635         ;
10636       else if (unformat (i, "opaque-index %d", &opaque_index))
10637         ;
10638       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10639         ;
10640       else if (unformat (i, "match_n %d", &match_n_vectors))
10641         ;
10642       else if (unformat (i, "match %U", api_unformat_classify_match,
10643                          &match, skip_n_vectors, match_n_vectors))
10644         ;
10645       else if (unformat (i, "advance %d", &advance))
10646         ;
10647       else if (unformat (i, "table-index %d", &table_index))
10648         ;
10649       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10650         action = 1;
10651       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10652         action = 2;
10653       else if (unformat (i, "action %d", &action))
10654         ;
10655       else if (unformat (i, "metadata %d", &metadata))
10656         ;
10657       else
10658         break;
10659     }
10660
10661   if (table_index == ~0)
10662     {
10663       errmsg ("Table index required");
10664       return -99;
10665     }
10666
10667   if (is_add && match == 0)
10668     {
10669       errmsg ("Match value required");
10670       return -99;
10671     }
10672
10673   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10674
10675   mp->is_add = is_add;
10676   mp->table_index = ntohl (table_index);
10677   mp->hit_next_index = ntohl (hit_next_index);
10678   mp->opaque_index = ntohl (opaque_index);
10679   mp->advance = ntohl (advance);
10680   mp->action = action;
10681   mp->metadata = ntohl (metadata);
10682   mp->match_len = ntohl (vec_len (match));
10683   clib_memcpy (mp->match, match, vec_len (match));
10684   vec_free (match);
10685
10686   S (mp);
10687   W (ret);
10688   return ret;
10689 }
10690
10691 static int
10692 api_classify_set_interface_ip_table (vat_main_t * vam)
10693 {
10694   unformat_input_t *i = vam->input;
10695   vl_api_classify_set_interface_ip_table_t *mp;
10696   u32 sw_if_index;
10697   int sw_if_index_set;
10698   u32 table_index = ~0;
10699   u8 is_ipv6 = 0;
10700   int ret;
10701
10702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10705         sw_if_index_set = 1;
10706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "table %d", &table_index))
10709         ;
10710       else
10711         {
10712           clib_warning ("parse error '%U'", format_unformat_error, i);
10713           return -99;
10714         }
10715     }
10716
10717   if (sw_if_index_set == 0)
10718     {
10719       errmsg ("missing interface name or sw_if_index");
10720       return -99;
10721     }
10722
10723
10724   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10725
10726   mp->sw_if_index = ntohl (sw_if_index);
10727   mp->table_index = ntohl (table_index);
10728   mp->is_ipv6 = is_ipv6;
10729
10730   S (mp);
10731   W (ret);
10732   return ret;
10733 }
10734
10735 static int
10736 api_classify_set_interface_l2_tables (vat_main_t * vam)
10737 {
10738   unformat_input_t *i = vam->input;
10739   vl_api_classify_set_interface_l2_tables_t *mp;
10740   u32 sw_if_index;
10741   int sw_if_index_set;
10742   u32 ip4_table_index = ~0;
10743   u32 ip6_table_index = ~0;
10744   u32 other_table_index = ~0;
10745   u32 is_input = 1;
10746   int ret;
10747
10748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10749     {
10750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10751         sw_if_index_set = 1;
10752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10755         ;
10756       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10757         ;
10758       else if (unformat (i, "other-table %d", &other_table_index))
10759         ;
10760       else if (unformat (i, "is-input %d", &is_input))
10761         ;
10762       else
10763         {
10764           clib_warning ("parse error '%U'", format_unformat_error, i);
10765           return -99;
10766         }
10767     }
10768
10769   if (sw_if_index_set == 0)
10770     {
10771       errmsg ("missing interface name or sw_if_index");
10772       return -99;
10773     }
10774
10775
10776   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10777
10778   mp->sw_if_index = ntohl (sw_if_index);
10779   mp->ip4_table_index = ntohl (ip4_table_index);
10780   mp->ip6_table_index = ntohl (ip6_table_index);
10781   mp->other_table_index = ntohl (other_table_index);
10782   mp->is_input = (u8) is_input;
10783
10784   S (mp);
10785   W (ret);
10786   return ret;
10787 }
10788
10789 static int
10790 api_set_ipfix_exporter (vat_main_t * vam)
10791 {
10792   unformat_input_t *i = vam->input;
10793   vl_api_set_ipfix_exporter_t *mp;
10794   ip4_address_t collector_address;
10795   u8 collector_address_set = 0;
10796   u32 collector_port = ~0;
10797   ip4_address_t src_address;
10798   u8 src_address_set = 0;
10799   u32 vrf_id = ~0;
10800   u32 path_mtu = ~0;
10801   u32 template_interval = ~0;
10802   u8 udp_checksum = 0;
10803   int ret;
10804
10805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (i, "collector_address %U", unformat_ip4_address,
10808                     &collector_address))
10809         collector_address_set = 1;
10810       else if (unformat (i, "collector_port %d", &collector_port))
10811         ;
10812       else if (unformat (i, "src_address %U", unformat_ip4_address,
10813                          &src_address))
10814         src_address_set = 1;
10815       else if (unformat (i, "vrf_id %d", &vrf_id))
10816         ;
10817       else if (unformat (i, "path_mtu %d", &path_mtu))
10818         ;
10819       else if (unformat (i, "template_interval %d", &template_interval))
10820         ;
10821       else if (unformat (i, "udp_checksum"))
10822         udp_checksum = 1;
10823       else
10824         break;
10825     }
10826
10827   if (collector_address_set == 0)
10828     {
10829       errmsg ("collector_address required");
10830       return -99;
10831     }
10832
10833   if (src_address_set == 0)
10834     {
10835       errmsg ("src_address required");
10836       return -99;
10837     }
10838
10839   M (SET_IPFIX_EXPORTER, mp);
10840
10841   memcpy (mp->collector_address.un.ip4, collector_address.data,
10842           sizeof (collector_address.data));
10843   mp->collector_port = htons ((u16) collector_port);
10844   memcpy (mp->src_address.un.ip4, src_address.data,
10845           sizeof (src_address.data));
10846   mp->vrf_id = htonl (vrf_id);
10847   mp->path_mtu = htonl (path_mtu);
10848   mp->template_interval = htonl (template_interval);
10849   mp->udp_checksum = udp_checksum;
10850
10851   S (mp);
10852   W (ret);
10853   return ret;
10854 }
10855
10856 static int
10857 api_set_ipfix_classify_stream (vat_main_t * vam)
10858 {
10859   unformat_input_t *i = vam->input;
10860   vl_api_set_ipfix_classify_stream_t *mp;
10861   u32 domain_id = 0;
10862   u32 src_port = UDP_DST_PORT_ipfix;
10863   int ret;
10864
10865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (i, "domain %d", &domain_id))
10868         ;
10869       else if (unformat (i, "src_port %d", &src_port))
10870         ;
10871       else
10872         {
10873           errmsg ("unknown input `%U'", format_unformat_error, i);
10874           return -99;
10875         }
10876     }
10877
10878   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10879
10880   mp->domain_id = htonl (domain_id);
10881   mp->src_port = htons ((u16) src_port);
10882
10883   S (mp);
10884   W (ret);
10885   return ret;
10886 }
10887
10888 static int
10889 api_ipfix_classify_table_add_del (vat_main_t * vam)
10890 {
10891   unformat_input_t *i = vam->input;
10892   vl_api_ipfix_classify_table_add_del_t *mp;
10893   int is_add = -1;
10894   u32 classify_table_index = ~0;
10895   u8 ip_version = 0;
10896   u8 transport_protocol = 255;
10897   int ret;
10898
10899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900     {
10901       if (unformat (i, "add"))
10902         is_add = 1;
10903       else if (unformat (i, "del"))
10904         is_add = 0;
10905       else if (unformat (i, "table %d", &classify_table_index))
10906         ;
10907       else if (unformat (i, "ip4"))
10908         ip_version = 4;
10909       else if (unformat (i, "ip6"))
10910         ip_version = 6;
10911       else if (unformat (i, "tcp"))
10912         transport_protocol = 6;
10913       else if (unformat (i, "udp"))
10914         transport_protocol = 17;
10915       else
10916         {
10917           errmsg ("unknown input `%U'", format_unformat_error, i);
10918           return -99;
10919         }
10920     }
10921
10922   if (is_add == -1)
10923     {
10924       errmsg ("expecting: add|del");
10925       return -99;
10926     }
10927   if (classify_table_index == ~0)
10928     {
10929       errmsg ("classifier table not specified");
10930       return -99;
10931     }
10932   if (ip_version == 0)
10933     {
10934       errmsg ("IP version not specified");
10935       return -99;
10936     }
10937
10938   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10939
10940   mp->is_add = is_add;
10941   mp->table_id = htonl (classify_table_index);
10942   mp->ip_version = ip_version;
10943   mp->transport_protocol = transport_protocol;
10944
10945   S (mp);
10946   W (ret);
10947   return ret;
10948 }
10949
10950 static int
10951 api_get_node_index (vat_main_t * vam)
10952 {
10953   unformat_input_t *i = vam->input;
10954   vl_api_get_node_index_t *mp;
10955   u8 *name = 0;
10956   int ret;
10957
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "node %s", &name))
10961         ;
10962       else
10963         break;
10964     }
10965   if (name == 0)
10966     {
10967       errmsg ("node name required");
10968       return -99;
10969     }
10970   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10971     {
10972       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10973       return -99;
10974     }
10975
10976   M (GET_NODE_INDEX, mp);
10977   clib_memcpy (mp->node_name, name, vec_len (name));
10978   vec_free (name);
10979
10980   S (mp);
10981   W (ret);
10982   return ret;
10983 }
10984
10985 static int
10986 api_get_next_index (vat_main_t * vam)
10987 {
10988   unformat_input_t *i = vam->input;
10989   vl_api_get_next_index_t *mp;
10990   u8 *node_name = 0, *next_node_name = 0;
10991   int ret;
10992
10993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10994     {
10995       if (unformat (i, "node-name %s", &node_name))
10996         ;
10997       else if (unformat (i, "next-node-name %s", &next_node_name))
10998         break;
10999     }
11000
11001   if (node_name == 0)
11002     {
11003       errmsg ("node name required");
11004       return -99;
11005     }
11006   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11007     {
11008       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11009       return -99;
11010     }
11011
11012   if (next_node_name == 0)
11013     {
11014       errmsg ("next node name required");
11015       return -99;
11016     }
11017   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11018     {
11019       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11020       return -99;
11021     }
11022
11023   M (GET_NEXT_INDEX, mp);
11024   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11025   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11026   vec_free (node_name);
11027   vec_free (next_node_name);
11028
11029   S (mp);
11030   W (ret);
11031   return ret;
11032 }
11033
11034 static int
11035 api_add_node_next (vat_main_t * vam)
11036 {
11037   unformat_input_t *i = vam->input;
11038   vl_api_add_node_next_t *mp;
11039   u8 *name = 0;
11040   u8 *next = 0;
11041   int ret;
11042
11043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11044     {
11045       if (unformat (i, "node %s", &name))
11046         ;
11047       else if (unformat (i, "next %s", &next))
11048         ;
11049       else
11050         break;
11051     }
11052   if (name == 0)
11053     {
11054       errmsg ("node name required");
11055       return -99;
11056     }
11057   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11058     {
11059       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11060       return -99;
11061     }
11062   if (next == 0)
11063     {
11064       errmsg ("next node required");
11065       return -99;
11066     }
11067   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11068     {
11069       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11070       return -99;
11071     }
11072
11073   M (ADD_NODE_NEXT, mp);
11074   clib_memcpy (mp->node_name, name, vec_len (name));
11075   clib_memcpy (mp->next_name, next, vec_len (next));
11076   vec_free (name);
11077   vec_free (next);
11078
11079   S (mp);
11080   W (ret);
11081   return ret;
11082 }
11083
11084 static int
11085 api_l2tpv3_create_tunnel (vat_main_t * vam)
11086 {
11087   unformat_input_t *i = vam->input;
11088   ip6_address_t client_address, our_address;
11089   int client_address_set = 0;
11090   int our_address_set = 0;
11091   u32 local_session_id = 0;
11092   u32 remote_session_id = 0;
11093   u64 local_cookie = 0;
11094   u64 remote_cookie = 0;
11095   u8 l2_sublayer_present = 0;
11096   vl_api_l2tpv3_create_tunnel_t *mp;
11097   int ret;
11098
11099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11100     {
11101       if (unformat (i, "client_address %U", unformat_ip6_address,
11102                     &client_address))
11103         client_address_set = 1;
11104       else if (unformat (i, "our_address %U", unformat_ip6_address,
11105                          &our_address))
11106         our_address_set = 1;
11107       else if (unformat (i, "local_session_id %d", &local_session_id))
11108         ;
11109       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11110         ;
11111       else if (unformat (i, "local_cookie %lld", &local_cookie))
11112         ;
11113       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11114         ;
11115       else if (unformat (i, "l2-sublayer-present"))
11116         l2_sublayer_present = 1;
11117       else
11118         break;
11119     }
11120
11121   if (client_address_set == 0)
11122     {
11123       errmsg ("client_address required");
11124       return -99;
11125     }
11126
11127   if (our_address_set == 0)
11128     {
11129       errmsg ("our_address required");
11130       return -99;
11131     }
11132
11133   M (L2TPV3_CREATE_TUNNEL, mp);
11134
11135   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11136                sizeof (ip6_address_t));
11137
11138   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11139                sizeof (ip6_address_t));
11140
11141   mp->local_session_id = ntohl (local_session_id);
11142   mp->remote_session_id = ntohl (remote_session_id);
11143   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11144   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11145   mp->l2_sublayer_present = l2_sublayer_present;
11146
11147   S (mp);
11148   W (ret);
11149   return ret;
11150 }
11151
11152 static int
11153 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11154 {
11155   unformat_input_t *i = vam->input;
11156   u32 sw_if_index;
11157   u8 sw_if_index_set = 0;
11158   u64 new_local_cookie = 0;
11159   u64 new_remote_cookie = 0;
11160   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11161   int ret;
11162
11163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11164     {
11165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11166         sw_if_index_set = 1;
11167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11170         ;
11171       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11172         ;
11173       else
11174         break;
11175     }
11176
11177   if (sw_if_index_set == 0)
11178     {
11179       errmsg ("missing interface name or sw_if_index");
11180       return -99;
11181     }
11182
11183   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11184
11185   mp->sw_if_index = ntohl (sw_if_index);
11186   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11187   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11188
11189   S (mp);
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static int
11195 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11196 {
11197   unformat_input_t *i = vam->input;
11198   vl_api_l2tpv3_interface_enable_disable_t *mp;
11199   u32 sw_if_index;
11200   u8 sw_if_index_set = 0;
11201   u8 enable_disable = 1;
11202   int ret;
11203
11204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11205     {
11206       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11207         sw_if_index_set = 1;
11208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11209         sw_if_index_set = 1;
11210       else if (unformat (i, "enable"))
11211         enable_disable = 1;
11212       else if (unformat (i, "disable"))
11213         enable_disable = 0;
11214       else
11215         break;
11216     }
11217
11218   if (sw_if_index_set == 0)
11219     {
11220       errmsg ("missing interface name or sw_if_index");
11221       return -99;
11222     }
11223
11224   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11225
11226   mp->sw_if_index = ntohl (sw_if_index);
11227   mp->enable_disable = enable_disable;
11228
11229   S (mp);
11230   W (ret);
11231   return ret;
11232 }
11233
11234 static int
11235 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_l2tpv3_set_lookup_key_t *mp;
11239   u8 key = ~0;
11240   int ret;
11241
11242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11243     {
11244       if (unformat (i, "lookup_v6_src"))
11245         key = L2T_LOOKUP_SRC_ADDRESS;
11246       else if (unformat (i, "lookup_v6_dst"))
11247         key = L2T_LOOKUP_DST_ADDRESS;
11248       else if (unformat (i, "lookup_session_id"))
11249         key = L2T_LOOKUP_SESSION_ID;
11250       else
11251         break;
11252     }
11253
11254   if (key == (u8) ~ 0)
11255     {
11256       errmsg ("l2tp session lookup key unset");
11257       return -99;
11258     }
11259
11260   M (L2TPV3_SET_LOOKUP_KEY, mp);
11261
11262   mp->key = key;
11263
11264   S (mp);
11265   W (ret);
11266   return ret;
11267 }
11268
11269 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11270   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11271 {
11272   vat_main_t *vam = &vat_main;
11273
11274   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11275          format_ip6_address, mp->our_address,
11276          format_ip6_address, mp->client_address,
11277          clib_net_to_host_u32 (mp->sw_if_index));
11278
11279   print (vam->ofp,
11280          "   local cookies %016llx %016llx remote cookie %016llx",
11281          clib_net_to_host_u64 (mp->local_cookie[0]),
11282          clib_net_to_host_u64 (mp->local_cookie[1]),
11283          clib_net_to_host_u64 (mp->remote_cookie));
11284
11285   print (vam->ofp, "   local session-id %d remote session-id %d",
11286          clib_net_to_host_u32 (mp->local_session_id),
11287          clib_net_to_host_u32 (mp->remote_session_id));
11288
11289   print (vam->ofp, "   l2 specific sublayer %s\n",
11290          mp->l2_sublayer_present ? "preset" : "absent");
11291
11292 }
11293
11294 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11295   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11296 {
11297   vat_main_t *vam = &vat_main;
11298   vat_json_node_t *node = NULL;
11299   struct in6_addr addr;
11300
11301   if (VAT_JSON_ARRAY != vam->json_tree.type)
11302     {
11303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11304       vat_json_init_array (&vam->json_tree);
11305     }
11306   node = vat_json_array_add (&vam->json_tree);
11307
11308   vat_json_init_object (node);
11309
11310   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11311   vat_json_object_add_ip6 (node, "our_address", addr);
11312   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11313   vat_json_object_add_ip6 (node, "client_address", addr);
11314
11315   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11316   vat_json_init_array (lc);
11317   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11318   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11319   vat_json_object_add_uint (node, "remote_cookie",
11320                             clib_net_to_host_u64 (mp->remote_cookie));
11321
11322   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11323   vat_json_object_add_uint (node, "local_session_id",
11324                             clib_net_to_host_u32 (mp->local_session_id));
11325   vat_json_object_add_uint (node, "remote_session_id",
11326                             clib_net_to_host_u32 (mp->remote_session_id));
11327   vat_json_object_add_string_copy (node, "l2_sublayer",
11328                                    mp->l2_sublayer_present ? (u8 *) "present"
11329                                    : (u8 *) "absent");
11330 }
11331
11332 static int
11333 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11334 {
11335   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11336   vl_api_control_ping_t *mp_ping;
11337   int ret;
11338
11339   /* Get list of l2tpv3-tunnel interfaces */
11340   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11341   S (mp);
11342
11343   /* Use a control ping for synchronization */
11344   MPING (CONTROL_PING, mp_ping);
11345   S (mp_ping);
11346
11347   W (ret);
11348   return ret;
11349 }
11350
11351
11352 static void vl_api_sw_interface_tap_v2_details_t_handler
11353   (vl_api_sw_interface_tap_v2_details_t * mp)
11354 {
11355   vat_main_t *vam = &vat_main;
11356
11357   u8 *ip4 =
11358     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11359             mp->host_ip4_prefix.len);
11360   u8 *ip6 =
11361     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11362             mp->host_ip6_prefix.len);
11363
11364   print (vam->ofp,
11365          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11366          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11367          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11368          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11369          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11370
11371   vec_free (ip4);
11372   vec_free (ip6);
11373 }
11374
11375 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11376   (vl_api_sw_interface_tap_v2_details_t * mp)
11377 {
11378   vat_main_t *vam = &vat_main;
11379   vat_json_node_t *node = NULL;
11380
11381   if (VAT_JSON_ARRAY != vam->json_tree.type)
11382     {
11383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11384       vat_json_init_array (&vam->json_tree);
11385     }
11386   node = vat_json_array_add (&vam->json_tree);
11387
11388   vat_json_init_object (node);
11389   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11390   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11391   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11392   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11393   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11394   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11395   vat_json_object_add_string_copy (node, "host_mac_addr",
11396                                    format (0, "%U", format_ethernet_address,
11397                                            &mp->host_mac_addr));
11398   vat_json_object_add_string_copy (node, "host_namespace",
11399                                    mp->host_namespace);
11400   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11401   vat_json_object_add_string_copy (node, "host_ip4_addr",
11402                                    format (0, "%U/%d", format_ip4_address,
11403                                            mp->host_ip4_prefix.address,
11404                                            mp->host_ip4_prefix.len));
11405   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11406                                    format (0, "%U/%d", format_ip6_address,
11407                                            mp->host_ip6_prefix.address,
11408                                            mp->host_ip6_prefix.len));
11409
11410 }
11411
11412 static int
11413 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11414 {
11415   vl_api_sw_interface_tap_v2_dump_t *mp;
11416   vl_api_control_ping_t *mp_ping;
11417   int ret;
11418
11419   print (vam->ofp,
11420          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11421          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11422          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11423          "host_ip6_addr");
11424
11425   /* Get list of tap interfaces */
11426   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11427   S (mp);
11428
11429   /* Use a control ping for synchronization */
11430   MPING (CONTROL_PING, mp_ping);
11431   S (mp_ping);
11432
11433   W (ret);
11434   return ret;
11435 }
11436
11437 static void vl_api_sw_interface_virtio_pci_details_t_handler
11438   (vl_api_sw_interface_virtio_pci_details_t * mp)
11439 {
11440   vat_main_t *vam = &vat_main;
11441
11442   typedef union
11443   {
11444     struct
11445     {
11446       u16 domain;
11447       u8 bus;
11448       u8 slot:5;
11449       u8 function:3;
11450     };
11451     u32 as_u32;
11452   } pci_addr_t;
11453   pci_addr_t addr;
11454
11455   addr.domain = ntohs (mp->pci_addr.domain);
11456   addr.bus = mp->pci_addr.bus;
11457   addr.slot = mp->pci_addr.slot;
11458   addr.function = mp->pci_addr.function;
11459
11460   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11461                          addr.slot, addr.function);
11462
11463   print (vam->ofp,
11464          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11465          pci_addr, ntohl (mp->sw_if_index),
11466          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11467          format_ethernet_address, mp->mac_addr,
11468          clib_net_to_host_u64 (mp->features));
11469   vec_free (pci_addr);
11470 }
11471
11472 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11473   (vl_api_sw_interface_virtio_pci_details_t * mp)
11474 {
11475   vat_main_t *vam = &vat_main;
11476   vat_json_node_t *node = NULL;
11477   vlib_pci_addr_t pci_addr;
11478
11479   if (VAT_JSON_ARRAY != vam->json_tree.type)
11480     {
11481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11482       vat_json_init_array (&vam->json_tree);
11483     }
11484   node = vat_json_array_add (&vam->json_tree);
11485
11486   pci_addr.domain = ntohs (mp->pci_addr.domain);
11487   pci_addr.bus = mp->pci_addr.bus;
11488   pci_addr.slot = mp->pci_addr.slot;
11489   pci_addr.function = mp->pci_addr.function;
11490
11491   vat_json_init_object (node);
11492   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11493   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11494   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11495   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11496   vat_json_object_add_uint (node, "features",
11497                             clib_net_to_host_u64 (mp->features));
11498   vat_json_object_add_string_copy (node, "mac_addr",
11499                                    format (0, "%U", format_ethernet_address,
11500                                            &mp->mac_addr));
11501 }
11502
11503 static int
11504 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11505 {
11506   vl_api_sw_interface_virtio_pci_dump_t *mp;
11507   vl_api_control_ping_t *mp_ping;
11508   int ret;
11509
11510   print (vam->ofp,
11511          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11512          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11513          "mac_addr", "features");
11514
11515   /* Get list of tap interfaces */
11516   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11517   S (mp);
11518
11519   /* Use a control ping for synchronization */
11520   MPING (CONTROL_PING, mp_ping);
11521   S (mp_ping);
11522
11523   W (ret);
11524   return ret;
11525 }
11526
11527 static int
11528 api_vxlan_offload_rx (vat_main_t * vam)
11529 {
11530   unformat_input_t *line_input = vam->input;
11531   vl_api_vxlan_offload_rx_t *mp;
11532   u32 hw_if_index = ~0, rx_if_index = ~0;
11533   u8 is_add = 1;
11534   int ret;
11535
11536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11537     {
11538       if (unformat (line_input, "del"))
11539         is_add = 0;
11540       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11541                          &hw_if_index))
11542         ;
11543       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11544         ;
11545       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11546                          &rx_if_index))
11547         ;
11548       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11549         ;
11550       else
11551         {
11552           errmsg ("parse error '%U'", format_unformat_error, line_input);
11553           return -99;
11554         }
11555     }
11556
11557   if (hw_if_index == ~0)
11558     {
11559       errmsg ("no hw interface");
11560       return -99;
11561     }
11562
11563   if (rx_if_index == ~0)
11564     {
11565       errmsg ("no rx tunnel");
11566       return -99;
11567     }
11568
11569   M (VXLAN_OFFLOAD_RX, mp);
11570
11571   mp->hw_if_index = ntohl (hw_if_index);
11572   mp->sw_if_index = ntohl (rx_if_index);
11573   mp->enable = is_add;
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static uword unformat_vxlan_decap_next
11581   (unformat_input_t * input, va_list * args)
11582 {
11583   u32 *result = va_arg (*args, u32 *);
11584   u32 tmp;
11585
11586   if (unformat (input, "l2"))
11587     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11588   else if (unformat (input, "%d", &tmp))
11589     *result = tmp;
11590   else
11591     return 0;
11592   return 1;
11593 }
11594
11595 static int
11596 api_vxlan_add_del_tunnel (vat_main_t * vam)
11597 {
11598   unformat_input_t *line_input = vam->input;
11599   vl_api_vxlan_add_del_tunnel_t *mp;
11600   ip46_address_t src, dst;
11601   u8 is_add = 1;
11602   u8 ipv4_set = 0, ipv6_set = 0;
11603   u8 src_set = 0;
11604   u8 dst_set = 0;
11605   u8 grp_set = 0;
11606   u32 instance = ~0;
11607   u32 mcast_sw_if_index = ~0;
11608   u32 encap_vrf_id = 0;
11609   u32 decap_next_index = ~0;
11610   u32 vni = 0;
11611   int ret;
11612
11613   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11614   clib_memset (&src, 0, sizeof src);
11615   clib_memset (&dst, 0, sizeof dst);
11616
11617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11618     {
11619       if (unformat (line_input, "del"))
11620         is_add = 0;
11621       else if (unformat (line_input, "instance %d", &instance))
11622         ;
11623       else
11624         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11625         {
11626           ipv4_set = 1;
11627           src_set = 1;
11628         }
11629       else
11630         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11631         {
11632           ipv4_set = 1;
11633           dst_set = 1;
11634         }
11635       else
11636         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11637         {
11638           ipv6_set = 1;
11639           src_set = 1;
11640         }
11641       else
11642         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11643         {
11644           ipv6_set = 1;
11645           dst_set = 1;
11646         }
11647       else if (unformat (line_input, "group %U %U",
11648                          unformat_ip4_address, &dst.ip4,
11649                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11650         {
11651           grp_set = dst_set = 1;
11652           ipv4_set = 1;
11653         }
11654       else if (unformat (line_input, "group %U",
11655                          unformat_ip4_address, &dst.ip4))
11656         {
11657           grp_set = dst_set = 1;
11658           ipv4_set = 1;
11659         }
11660       else if (unformat (line_input, "group %U %U",
11661                          unformat_ip6_address, &dst.ip6,
11662                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11663         {
11664           grp_set = dst_set = 1;
11665           ipv6_set = 1;
11666         }
11667       else if (unformat (line_input, "group %U",
11668                          unformat_ip6_address, &dst.ip6))
11669         {
11670           grp_set = dst_set = 1;
11671           ipv6_set = 1;
11672         }
11673       else
11674         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11675         ;
11676       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11677         ;
11678       else if (unformat (line_input, "decap-next %U",
11679                          unformat_vxlan_decap_next, &decap_next_index))
11680         ;
11681       else if (unformat (line_input, "vni %d", &vni))
11682         ;
11683       else
11684         {
11685           errmsg ("parse error '%U'", format_unformat_error, line_input);
11686           return -99;
11687         }
11688     }
11689
11690   if (src_set == 0)
11691     {
11692       errmsg ("tunnel src address not specified");
11693       return -99;
11694     }
11695   if (dst_set == 0)
11696     {
11697       errmsg ("tunnel dst address not specified");
11698       return -99;
11699     }
11700
11701   if (grp_set && !ip46_address_is_multicast (&dst))
11702     {
11703       errmsg ("tunnel group address not multicast");
11704       return -99;
11705     }
11706   if (grp_set && mcast_sw_if_index == ~0)
11707     {
11708       errmsg ("tunnel nonexistent multicast device");
11709       return -99;
11710     }
11711   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11712     {
11713       errmsg ("tunnel dst address must be unicast");
11714       return -99;
11715     }
11716
11717
11718   if (ipv4_set && ipv6_set)
11719     {
11720       errmsg ("both IPv4 and IPv6 addresses specified");
11721       return -99;
11722     }
11723
11724   if ((vni == 0) || (vni >> 24))
11725     {
11726       errmsg ("vni not specified or out of range");
11727       return -99;
11728     }
11729
11730   M (VXLAN_ADD_DEL_TUNNEL, mp);
11731
11732   if (ipv6_set)
11733     {
11734       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11735       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11736     }
11737   else
11738     {
11739       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11740       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11741     }
11742   mp->src_address.af = ipv6_set;
11743   mp->dst_address.af = ipv6_set;
11744
11745   mp->instance = htonl (instance);
11746   mp->encap_vrf_id = ntohl (encap_vrf_id);
11747   mp->decap_next_index = ntohl (decap_next_index);
11748   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11749   mp->vni = ntohl (vni);
11750   mp->is_add = is_add;
11751
11752   S (mp);
11753   W (ret);
11754   return ret;
11755 }
11756
11757 static void vl_api_vxlan_tunnel_details_t_handler
11758   (vl_api_vxlan_tunnel_details_t * mp)
11759 {
11760   vat_main_t *vam = &vat_main;
11761   ip46_address_t src =
11762     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11763   ip46_address_t dst =
11764     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11765
11766   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11767          ntohl (mp->sw_if_index),
11768          ntohl (mp->instance),
11769          format_ip46_address, &src, IP46_TYPE_ANY,
11770          format_ip46_address, &dst, IP46_TYPE_ANY,
11771          ntohl (mp->encap_vrf_id),
11772          ntohl (mp->decap_next_index), ntohl (mp->vni),
11773          ntohl (mp->mcast_sw_if_index));
11774 }
11775
11776 static void vl_api_vxlan_tunnel_details_t_handler_json
11777   (vl_api_vxlan_tunnel_details_t * mp)
11778 {
11779   vat_main_t *vam = &vat_main;
11780   vat_json_node_t *node = NULL;
11781
11782   if (VAT_JSON_ARRAY != vam->json_tree.type)
11783     {
11784       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11785       vat_json_init_array (&vam->json_tree);
11786     }
11787   node = vat_json_array_add (&vam->json_tree);
11788
11789   vat_json_init_object (node);
11790   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11791
11792   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11793
11794   if (mp->src_address.af)
11795     {
11796       struct in6_addr ip6;
11797
11798       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11799       vat_json_object_add_ip6 (node, "src_address", ip6);
11800       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11801       vat_json_object_add_ip6 (node, "dst_address", ip6);
11802     }
11803   else
11804     {
11805       struct in_addr ip4;
11806
11807       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11808       vat_json_object_add_ip4 (node, "src_address", ip4);
11809       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11810       vat_json_object_add_ip4 (node, "dst_address", ip4);
11811     }
11812   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11813   vat_json_object_add_uint (node, "decap_next_index",
11814                             ntohl (mp->decap_next_index));
11815   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11816   vat_json_object_add_uint (node, "mcast_sw_if_index",
11817                             ntohl (mp->mcast_sw_if_index));
11818 }
11819
11820 static int
11821 api_vxlan_tunnel_dump (vat_main_t * vam)
11822 {
11823   unformat_input_t *i = vam->input;
11824   vl_api_vxlan_tunnel_dump_t *mp;
11825   vl_api_control_ping_t *mp_ping;
11826   u32 sw_if_index;
11827   u8 sw_if_index_set = 0;
11828   int ret;
11829
11830   /* Parse args required to build the message */
11831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (i, "sw_if_index %d", &sw_if_index))
11834         sw_if_index_set = 1;
11835       else
11836         break;
11837     }
11838
11839   if (sw_if_index_set == 0)
11840     {
11841       sw_if_index = ~0;
11842     }
11843
11844   if (!vam->json_output)
11845     {
11846       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11847              "sw_if_index", "instance", "src_address", "dst_address",
11848              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11849     }
11850
11851   /* Get list of vxlan-tunnel interfaces */
11852   M (VXLAN_TUNNEL_DUMP, mp);
11853
11854   mp->sw_if_index = htonl (sw_if_index);
11855
11856   S (mp);
11857
11858   /* Use a control ping for synchronization */
11859   MPING (CONTROL_PING, mp_ping);
11860   S (mp_ping);
11861
11862   W (ret);
11863   return ret;
11864 }
11865
11866 static uword unformat_geneve_decap_next
11867   (unformat_input_t * input, va_list * args)
11868 {
11869   u32 *result = va_arg (*args, u32 *);
11870   u32 tmp;
11871
11872   if (unformat (input, "l2"))
11873     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11874   else if (unformat (input, "%d", &tmp))
11875     *result = tmp;
11876   else
11877     return 0;
11878   return 1;
11879 }
11880
11881 static int
11882 api_geneve_add_del_tunnel (vat_main_t * vam)
11883 {
11884   unformat_input_t *line_input = vam->input;
11885   vl_api_geneve_add_del_tunnel_t *mp;
11886   ip46_address_t src, dst;
11887   u8 is_add = 1;
11888   u8 ipv4_set = 0, ipv6_set = 0;
11889   u8 src_set = 0;
11890   u8 dst_set = 0;
11891   u8 grp_set = 0;
11892   u32 mcast_sw_if_index = ~0;
11893   u32 encap_vrf_id = 0;
11894   u32 decap_next_index = ~0;
11895   u32 vni = 0;
11896   int ret;
11897
11898   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11899   clib_memset (&src, 0, sizeof src);
11900   clib_memset (&dst, 0, sizeof dst);
11901
11902   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11903     {
11904       if (unformat (line_input, "del"))
11905         is_add = 0;
11906       else
11907         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11908         {
11909           ipv4_set = 1;
11910           src_set = 1;
11911         }
11912       else
11913         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11914         {
11915           ipv4_set = 1;
11916           dst_set = 1;
11917         }
11918       else
11919         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11920         {
11921           ipv6_set = 1;
11922           src_set = 1;
11923         }
11924       else
11925         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11926         {
11927           ipv6_set = 1;
11928           dst_set = 1;
11929         }
11930       else if (unformat (line_input, "group %U %U",
11931                          unformat_ip4_address, &dst.ip4,
11932                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11933         {
11934           grp_set = dst_set = 1;
11935           ipv4_set = 1;
11936         }
11937       else if (unformat (line_input, "group %U",
11938                          unformat_ip4_address, &dst.ip4))
11939         {
11940           grp_set = dst_set = 1;
11941           ipv4_set = 1;
11942         }
11943       else if (unformat (line_input, "group %U %U",
11944                          unformat_ip6_address, &dst.ip6,
11945                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11946         {
11947           grp_set = dst_set = 1;
11948           ipv6_set = 1;
11949         }
11950       else if (unformat (line_input, "group %U",
11951                          unformat_ip6_address, &dst.ip6))
11952         {
11953           grp_set = dst_set = 1;
11954           ipv6_set = 1;
11955         }
11956       else
11957         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11958         ;
11959       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11960         ;
11961       else if (unformat (line_input, "decap-next %U",
11962                          unformat_geneve_decap_next, &decap_next_index))
11963         ;
11964       else if (unformat (line_input, "vni %d", &vni))
11965         ;
11966       else
11967         {
11968           errmsg ("parse error '%U'", format_unformat_error, line_input);
11969           return -99;
11970         }
11971     }
11972
11973   if (src_set == 0)
11974     {
11975       errmsg ("tunnel src address not specified");
11976       return -99;
11977     }
11978   if (dst_set == 0)
11979     {
11980       errmsg ("tunnel dst address not specified");
11981       return -99;
11982     }
11983
11984   if (grp_set && !ip46_address_is_multicast (&dst))
11985     {
11986       errmsg ("tunnel group address not multicast");
11987       return -99;
11988     }
11989   if (grp_set && mcast_sw_if_index == ~0)
11990     {
11991       errmsg ("tunnel nonexistent multicast device");
11992       return -99;
11993     }
11994   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11995     {
11996       errmsg ("tunnel dst address must be unicast");
11997       return -99;
11998     }
11999
12000
12001   if (ipv4_set && ipv6_set)
12002     {
12003       errmsg ("both IPv4 and IPv6 addresses specified");
12004       return -99;
12005     }
12006
12007   if ((vni == 0) || (vni >> 24))
12008     {
12009       errmsg ("vni not specified or out of range");
12010       return -99;
12011     }
12012
12013   M (GENEVE_ADD_DEL_TUNNEL, mp);
12014
12015   if (ipv6_set)
12016     {
12017       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12018       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12019     }
12020   else
12021     {
12022       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12023       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12024     }
12025   mp->encap_vrf_id = ntohl (encap_vrf_id);
12026   mp->decap_next_index = ntohl (decap_next_index);
12027   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12028   mp->vni = ntohl (vni);
12029   mp->is_add = is_add;
12030
12031   S (mp);
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static void vl_api_geneve_tunnel_details_t_handler
12037   (vl_api_geneve_tunnel_details_t * mp)
12038 {
12039   vat_main_t *vam = &vat_main;
12040   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12041   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12042
12043   if (mp->src_address.af == ADDRESS_IP6)
12044     {
12045       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12046       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12047     }
12048   else
12049     {
12050       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12051       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12052     }
12053
12054   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12055          ntohl (mp->sw_if_index),
12056          format_ip46_address, &src, IP46_TYPE_ANY,
12057          format_ip46_address, &dst, IP46_TYPE_ANY,
12058          ntohl (mp->encap_vrf_id),
12059          ntohl (mp->decap_next_index), ntohl (mp->vni),
12060          ntohl (mp->mcast_sw_if_index));
12061 }
12062
12063 static void vl_api_geneve_tunnel_details_t_handler_json
12064   (vl_api_geneve_tunnel_details_t * mp)
12065 {
12066   vat_main_t *vam = &vat_main;
12067   vat_json_node_t *node = NULL;
12068   bool is_ipv6;
12069
12070   if (VAT_JSON_ARRAY != vam->json_tree.type)
12071     {
12072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12073       vat_json_init_array (&vam->json_tree);
12074     }
12075   node = vat_json_array_add (&vam->json_tree);
12076
12077   vat_json_init_object (node);
12078   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12079   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12080   if (is_ipv6)
12081     {
12082       struct in6_addr ip6;
12083
12084       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12085       vat_json_object_add_ip6 (node, "src_address", ip6);
12086       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12087       vat_json_object_add_ip6 (node, "dst_address", ip6);
12088     }
12089   else
12090     {
12091       struct in_addr ip4;
12092
12093       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12094       vat_json_object_add_ip4 (node, "src_address", ip4);
12095       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12096       vat_json_object_add_ip4 (node, "dst_address", ip4);
12097     }
12098   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12099   vat_json_object_add_uint (node, "decap_next_index",
12100                             ntohl (mp->decap_next_index));
12101   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12102   vat_json_object_add_uint (node, "mcast_sw_if_index",
12103                             ntohl (mp->mcast_sw_if_index));
12104 }
12105
12106 static int
12107 api_geneve_tunnel_dump (vat_main_t * vam)
12108 {
12109   unformat_input_t *i = vam->input;
12110   vl_api_geneve_tunnel_dump_t *mp;
12111   vl_api_control_ping_t *mp_ping;
12112   u32 sw_if_index;
12113   u8 sw_if_index_set = 0;
12114   int ret;
12115
12116   /* Parse args required to build the message */
12117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12118     {
12119       if (unformat (i, "sw_if_index %d", &sw_if_index))
12120         sw_if_index_set = 1;
12121       else
12122         break;
12123     }
12124
12125   if (sw_if_index_set == 0)
12126     {
12127       sw_if_index = ~0;
12128     }
12129
12130   if (!vam->json_output)
12131     {
12132       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12133              "sw_if_index", "local_address", "remote_address",
12134              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12135     }
12136
12137   /* Get list of geneve-tunnel interfaces */
12138   M (GENEVE_TUNNEL_DUMP, mp);
12139
12140   mp->sw_if_index = htonl (sw_if_index);
12141
12142   S (mp);
12143
12144   /* Use a control ping for synchronization */
12145   M (CONTROL_PING, mp_ping);
12146   S (mp_ping);
12147
12148   W (ret);
12149   return ret;
12150 }
12151
12152 static int
12153 api_gre_tunnel_add_del (vat_main_t * vam)
12154 {
12155   unformat_input_t *line_input = vam->input;
12156   vl_api_address_t src = { }, dst =
12157   {
12158   };
12159   vl_api_gre_tunnel_add_del_t *mp;
12160   vl_api_gre_tunnel_type_t t_type;
12161   u8 is_add = 1;
12162   u8 src_set = 0;
12163   u8 dst_set = 0;
12164   u32 outer_table_id = 0;
12165   u32 session_id = 0;
12166   u32 instance = ~0;
12167   int ret;
12168
12169   t_type = GRE_API_TUNNEL_TYPE_L3;
12170
12171   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (line_input, "del"))
12174         is_add = 0;
12175       else if (unformat (line_input, "instance %d", &instance))
12176         ;
12177       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12178         {
12179           src_set = 1;
12180         }
12181       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12182         {
12183           dst_set = 1;
12184         }
12185       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12186         ;
12187       else if (unformat (line_input, "teb"))
12188         t_type = GRE_API_TUNNEL_TYPE_TEB;
12189       else if (unformat (line_input, "erspan %d", &session_id))
12190         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12191       else
12192         {
12193           errmsg ("parse error '%U'", format_unformat_error, line_input);
12194           return -99;
12195         }
12196     }
12197
12198   if (src_set == 0)
12199     {
12200       errmsg ("tunnel src address not specified");
12201       return -99;
12202     }
12203   if (dst_set == 0)
12204     {
12205       errmsg ("tunnel dst address not specified");
12206       return -99;
12207     }
12208
12209   M (GRE_TUNNEL_ADD_DEL, mp);
12210
12211   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12212   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12213
12214   mp->tunnel.instance = htonl (instance);
12215   mp->tunnel.outer_table_id = htonl (outer_table_id);
12216   mp->is_add = is_add;
12217   mp->tunnel.session_id = htons ((u16) session_id);
12218   mp->tunnel.type = htonl (t_type);
12219
12220   S (mp);
12221   W (ret);
12222   return ret;
12223 }
12224
12225 static void vl_api_gre_tunnel_details_t_handler
12226   (vl_api_gre_tunnel_details_t * mp)
12227 {
12228   vat_main_t *vam = &vat_main;
12229
12230   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12231          ntohl (mp->tunnel.sw_if_index),
12232          ntohl (mp->tunnel.instance),
12233          format_vl_api_address, &mp->tunnel.src,
12234          format_vl_api_address, &mp->tunnel.dst,
12235          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12236          ntohl (mp->tunnel.session_id));
12237 }
12238
12239 static void vl_api_gre_tunnel_details_t_handler_json
12240   (vl_api_gre_tunnel_details_t * mp)
12241 {
12242   vat_main_t *vam = &vat_main;
12243   vat_json_node_t *node = NULL;
12244
12245   if (VAT_JSON_ARRAY != vam->json_tree.type)
12246     {
12247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12248       vat_json_init_array (&vam->json_tree);
12249     }
12250   node = vat_json_array_add (&vam->json_tree);
12251
12252   vat_json_init_object (node);
12253   vat_json_object_add_uint (node, "sw_if_index",
12254                             ntohl (mp->tunnel.sw_if_index));
12255   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12256
12257   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12258   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12259   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12260   vat_json_object_add_uint (node, "outer_table_id",
12261                             ntohl (mp->tunnel.outer_table_id));
12262   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12263 }
12264
12265 static int
12266 api_gre_tunnel_dump (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_gre_tunnel_dump_t *mp;
12270   vl_api_control_ping_t *mp_ping;
12271   u32 sw_if_index;
12272   u8 sw_if_index_set = 0;
12273   int ret;
12274
12275   /* Parse args required to build the message */
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "sw_if_index %d", &sw_if_index))
12279         sw_if_index_set = 1;
12280       else
12281         break;
12282     }
12283
12284   if (sw_if_index_set == 0)
12285     {
12286       sw_if_index = ~0;
12287     }
12288
12289   if (!vam->json_output)
12290     {
12291       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12292              "sw_if_index", "instance", "src_address", "dst_address",
12293              "tunnel_type", "outer_fib_id", "session_id");
12294     }
12295
12296   /* Get list of gre-tunnel interfaces */
12297   M (GRE_TUNNEL_DUMP, mp);
12298
12299   mp->sw_if_index = htonl (sw_if_index);
12300
12301   S (mp);
12302
12303   /* Use a control ping for synchronization */
12304   MPING (CONTROL_PING, mp_ping);
12305   S (mp_ping);
12306
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static int
12312 api_l2_fib_clear_table (vat_main_t * vam)
12313 {
12314 //  unformat_input_t * i = vam->input;
12315   vl_api_l2_fib_clear_table_t *mp;
12316   int ret;
12317
12318   M (L2_FIB_CLEAR_TABLE, mp);
12319
12320   S (mp);
12321   W (ret);
12322   return ret;
12323 }
12324
12325 static int
12326 api_l2_interface_efp_filter (vat_main_t * vam)
12327 {
12328   unformat_input_t *i = vam->input;
12329   vl_api_l2_interface_efp_filter_t *mp;
12330   u32 sw_if_index;
12331   u8 enable = 1;
12332   u8 sw_if_index_set = 0;
12333   int ret;
12334
12335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12338         sw_if_index_set = 1;
12339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12340         sw_if_index_set = 1;
12341       else if (unformat (i, "enable"))
12342         enable = 1;
12343       else if (unformat (i, "disable"))
12344         enable = 0;
12345       else
12346         {
12347           clib_warning ("parse error '%U'", format_unformat_error, i);
12348           return -99;
12349         }
12350     }
12351
12352   if (sw_if_index_set == 0)
12353     {
12354       errmsg ("missing sw_if_index");
12355       return -99;
12356     }
12357
12358   M (L2_INTERFACE_EFP_FILTER, mp);
12359
12360   mp->sw_if_index = ntohl (sw_if_index);
12361   mp->enable_disable = enable;
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 #define foreach_vtr_op                          \
12369 _("disable",  L2_VTR_DISABLED)                  \
12370 _("push-1",  L2_VTR_PUSH_1)                     \
12371 _("push-2",  L2_VTR_PUSH_2)                     \
12372 _("pop-1",  L2_VTR_POP_1)                       \
12373 _("pop-2",  L2_VTR_POP_2)                       \
12374 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12375 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12376 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12377 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12378
12379 static int
12380 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12384   u32 sw_if_index;
12385   u8 sw_if_index_set = 0;
12386   u8 vtr_op_set = 0;
12387   u32 vtr_op = 0;
12388   u32 push_dot1q = 1;
12389   u32 tag1 = ~0;
12390   u32 tag2 = ~0;
12391   int ret;
12392
12393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12394     {
12395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12398         sw_if_index_set = 1;
12399       else if (unformat (i, "vtr_op %d", &vtr_op))
12400         vtr_op_set = 1;
12401 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12402       foreach_vtr_op
12403 #undef _
12404         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12405         ;
12406       else if (unformat (i, "tag1 %d", &tag1))
12407         ;
12408       else if (unformat (i, "tag2 %d", &tag2))
12409         ;
12410       else
12411         {
12412           clib_warning ("parse error '%U'", format_unformat_error, i);
12413           return -99;
12414         }
12415     }
12416
12417   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12418     {
12419       errmsg ("missing vtr operation or sw_if_index");
12420       return -99;
12421     }
12422
12423   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12424   mp->sw_if_index = ntohl (sw_if_index);
12425   mp->vtr_op = ntohl (vtr_op);
12426   mp->push_dot1q = ntohl (push_dot1q);
12427   mp->tag1 = ntohl (tag1);
12428   mp->tag2 = ntohl (tag2);
12429
12430   S (mp);
12431   W (ret);
12432   return ret;
12433 }
12434
12435 static int
12436 api_create_vhost_user_if (vat_main_t * vam)
12437 {
12438   unformat_input_t *i = vam->input;
12439   vl_api_create_vhost_user_if_t *mp;
12440   u8 *file_name;
12441   u8 is_server = 0;
12442   u8 file_name_set = 0;
12443   u32 custom_dev_instance = ~0;
12444   u8 hwaddr[6];
12445   u8 use_custom_mac = 0;
12446   u8 disable_mrg_rxbuf = 0;
12447   u8 disable_indirect_desc = 0;
12448   u8 *tag = 0;
12449   u8 enable_gso = 0;
12450   int ret;
12451
12452   /* Shut up coverity */
12453   clib_memset (hwaddr, 0, sizeof (hwaddr));
12454
12455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12456     {
12457       if (unformat (i, "socket %s", &file_name))
12458         {
12459           file_name_set = 1;
12460         }
12461       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12462         ;
12463       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12464         use_custom_mac = 1;
12465       else if (unformat (i, "server"))
12466         is_server = 1;
12467       else if (unformat (i, "disable_mrg_rxbuf"))
12468         disable_mrg_rxbuf = 1;
12469       else if (unformat (i, "disable_indirect_desc"))
12470         disable_indirect_desc = 1;
12471       else if (unformat (i, "gso"))
12472         enable_gso = 1;
12473       else if (unformat (i, "tag %s", &tag))
12474         ;
12475       else
12476         break;
12477     }
12478
12479   if (file_name_set == 0)
12480     {
12481       errmsg ("missing socket file name");
12482       return -99;
12483     }
12484
12485   if (vec_len (file_name) > 255)
12486     {
12487       errmsg ("socket file name too long");
12488       return -99;
12489     }
12490   vec_add1 (file_name, 0);
12491
12492   M (CREATE_VHOST_USER_IF, mp);
12493
12494   mp->is_server = is_server;
12495   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12496   mp->disable_indirect_desc = disable_indirect_desc;
12497   mp->enable_gso = enable_gso;
12498   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12499   vec_free (file_name);
12500   if (custom_dev_instance != ~0)
12501     {
12502       mp->renumber = 1;
12503       mp->custom_dev_instance = ntohl (custom_dev_instance);
12504     }
12505
12506   mp->use_custom_mac = use_custom_mac;
12507   clib_memcpy (mp->mac_address, hwaddr, 6);
12508   if (tag)
12509     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12510   vec_free (tag);
12511
12512   S (mp);
12513   W (ret);
12514   return ret;
12515 }
12516
12517 static int
12518 api_modify_vhost_user_if (vat_main_t * vam)
12519 {
12520   unformat_input_t *i = vam->input;
12521   vl_api_modify_vhost_user_if_t *mp;
12522   u8 *file_name;
12523   u8 is_server = 0;
12524   u8 file_name_set = 0;
12525   u32 custom_dev_instance = ~0;
12526   u8 sw_if_index_set = 0;
12527   u32 sw_if_index = (u32) ~ 0;
12528   u8 enable_gso = 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
12548         break;
12549     }
12550
12551   if (sw_if_index_set == 0)
12552     {
12553       errmsg ("missing sw_if_index or interface name");
12554       return -99;
12555     }
12556
12557   if (file_name_set == 0)
12558     {
12559       errmsg ("missing socket file name");
12560       return -99;
12561     }
12562
12563   if (vec_len (file_name) > 255)
12564     {
12565       errmsg ("socket file name too long");
12566       return -99;
12567     }
12568   vec_add1 (file_name, 0);
12569
12570   M (MODIFY_VHOST_USER_IF, mp);
12571
12572   mp->sw_if_index = ntohl (sw_if_index);
12573   mp->is_server = is_server;
12574   mp->enable_gso = enable_gso;
12575   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12576   vec_free (file_name);
12577   if (custom_dev_instance != ~0)
12578     {
12579       mp->renumber = 1;
12580       mp->custom_dev_instance = ntohl (custom_dev_instance);
12581     }
12582
12583   S (mp);
12584   W (ret);
12585   return ret;
12586 }
12587
12588 static int
12589 api_delete_vhost_user_if (vat_main_t * vam)
12590 {
12591   unformat_input_t *i = vam->input;
12592   vl_api_delete_vhost_user_if_t *mp;
12593   u32 sw_if_index = ~0;
12594   u8 sw_if_index_set = 0;
12595   int ret;
12596
12597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12598     {
12599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12600         sw_if_index_set = 1;
12601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12602         sw_if_index_set = 1;
12603       else
12604         break;
12605     }
12606
12607   if (sw_if_index_set == 0)
12608     {
12609       errmsg ("missing sw_if_index or interface name");
12610       return -99;
12611     }
12612
12613
12614   M (DELETE_VHOST_USER_IF, mp);
12615
12616   mp->sw_if_index = ntohl (sw_if_index);
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static void vl_api_sw_interface_vhost_user_details_t_handler
12624   (vl_api_sw_interface_vhost_user_details_t * mp)
12625 {
12626   vat_main_t *vam = &vat_main;
12627   u64 features;
12628
12629   features =
12630     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12631                                                     clib_net_to_host_u32
12632                                                     (mp->features_last_32) <<
12633                                                     32);
12634
12635   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12636          (char *) mp->interface_name,
12637          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12638          features, mp->is_server,
12639          ntohl (mp->num_regions), (char *) mp->sock_filename);
12640   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12641 }
12642
12643 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12644   (vl_api_sw_interface_vhost_user_details_t * mp)
12645 {
12646   vat_main_t *vam = &vat_main;
12647   vat_json_node_t *node = NULL;
12648
12649   if (VAT_JSON_ARRAY != vam->json_tree.type)
12650     {
12651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12652       vat_json_init_array (&vam->json_tree);
12653     }
12654   node = vat_json_array_add (&vam->json_tree);
12655
12656   vat_json_init_object (node);
12657   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12658   vat_json_object_add_string_copy (node, "interface_name",
12659                                    mp->interface_name);
12660   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12661                             ntohl (mp->virtio_net_hdr_sz));
12662   vat_json_object_add_uint (node, "features_first_32",
12663                             clib_net_to_host_u32 (mp->features_first_32));
12664   vat_json_object_add_uint (node, "features_last_32",
12665                             clib_net_to_host_u32 (mp->features_last_32));
12666   vat_json_object_add_uint (node, "is_server", mp->is_server);
12667   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12668   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12669   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12670 }
12671
12672 static int
12673 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12674 {
12675   vl_api_sw_interface_vhost_user_dump_t *mp;
12676   vl_api_control_ping_t *mp_ping;
12677   int ret;
12678   print (vam->ofp,
12679          "Interface name            idx hdr_sz features server regions filename");
12680
12681   /* Get list of vhost-user interfaces */
12682   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12683   mp->sw_if_index = ntohl (~0);
12684   S (mp);
12685
12686   /* Use a control ping for synchronization */
12687   MPING (CONTROL_PING, mp_ping);
12688   S (mp_ping);
12689
12690   W (ret);
12691   return ret;
12692 }
12693
12694 static int
12695 api_show_version (vat_main_t * vam)
12696 {
12697   vl_api_show_version_t *mp;
12698   int ret;
12699
12700   M (SHOW_VERSION, mp);
12701
12702   S (mp);
12703   W (ret);
12704   return ret;
12705 }
12706
12707
12708 static int
12709 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12710 {
12711   unformat_input_t *line_input = vam->input;
12712   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12713   ip46_address_t local, remote;
12714   u8 is_add = 1;
12715   u8 local_set = 0;
12716   u8 remote_set = 0;
12717   u8 grp_set = 0;
12718   u32 mcast_sw_if_index = ~0;
12719   u32 encap_vrf_id = 0;
12720   u32 decap_vrf_id = 0;
12721   u8 protocol = ~0;
12722   u32 vni;
12723   u8 vni_set = 0;
12724   int ret;
12725
12726   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12727     {
12728       if (unformat (line_input, "del"))
12729         is_add = 0;
12730       else if (unformat (line_input, "local %U",
12731                          unformat_ip46_address, &local))
12732         {
12733           local_set = 1;
12734         }
12735       else if (unformat (line_input, "remote %U",
12736                          unformat_ip46_address, &remote))
12737         {
12738           remote_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U %U",
12741                          unformat_ip46_address, &remote,
12742                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12743         {
12744           grp_set = remote_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U",
12747                          unformat_ip46_address, &remote))
12748         {
12749           grp_set = remote_set = 1;
12750         }
12751       else
12752         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12753         ;
12754       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12755         ;
12756       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12757         ;
12758       else if (unformat (line_input, "vni %d", &vni))
12759         vni_set = 1;
12760       else if (unformat (line_input, "next-ip4"))
12761         protocol = 1;
12762       else if (unformat (line_input, "next-ip6"))
12763         protocol = 2;
12764       else if (unformat (line_input, "next-ethernet"))
12765         protocol = 3;
12766       else if (unformat (line_input, "next-nsh"))
12767         protocol = 4;
12768       else
12769         {
12770           errmsg ("parse error '%U'", format_unformat_error, line_input);
12771           return -99;
12772         }
12773     }
12774
12775   if (local_set == 0)
12776     {
12777       errmsg ("tunnel local address not specified");
12778       return -99;
12779     }
12780   if (remote_set == 0)
12781     {
12782       errmsg ("tunnel remote address not specified");
12783       return -99;
12784     }
12785   if (grp_set && mcast_sw_if_index == ~0)
12786     {
12787       errmsg ("tunnel nonexistent multicast device");
12788       return -99;
12789     }
12790   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12791     {
12792       errmsg ("both IPv4 and IPv6 addresses specified");
12793       return -99;
12794     }
12795
12796   if (vni_set == 0)
12797     {
12798       errmsg ("vni not specified");
12799       return -99;
12800     }
12801
12802   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12803
12804   ip_address_encode (&local,
12805                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12806                      IP46_TYPE_IP6, &mp->local);
12807   ip_address_encode (&remote,
12808                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12809                      IP46_TYPE_IP6, &mp->remote);
12810
12811   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12812   mp->encap_vrf_id = ntohl (encap_vrf_id);
12813   mp->decap_vrf_id = ntohl (decap_vrf_id);
12814   mp->protocol = protocol;
12815   mp->vni = ntohl (vni);
12816   mp->is_add = is_add;
12817
12818   S (mp);
12819   W (ret);
12820   return ret;
12821 }
12822
12823 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12824   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12825 {
12826   vat_main_t *vam = &vat_main;
12827   ip46_address_t local, remote;
12828
12829   ip_address_decode (&mp->local, &local);
12830   ip_address_decode (&mp->remote, &remote);
12831
12832   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12833          ntohl (mp->sw_if_index),
12834          format_ip46_address, &local, IP46_TYPE_ANY,
12835          format_ip46_address, &remote, IP46_TYPE_ANY,
12836          ntohl (mp->vni), mp->protocol,
12837          ntohl (mp->mcast_sw_if_index),
12838          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12839 }
12840
12841
12842 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12843   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12844 {
12845   vat_main_t *vam = &vat_main;
12846   vat_json_node_t *node = NULL;
12847   struct in_addr ip4;
12848   struct in6_addr ip6;
12849   ip46_address_t local, remote;
12850
12851   ip_address_decode (&mp->local, &local);
12852   ip_address_decode (&mp->remote, &remote);
12853
12854   if (VAT_JSON_ARRAY != vam->json_tree.type)
12855     {
12856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12857       vat_json_init_array (&vam->json_tree);
12858     }
12859   node = vat_json_array_add (&vam->json_tree);
12860
12861   vat_json_init_object (node);
12862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12863   if (ip46_address_is_ip4 (&local))
12864     {
12865       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12866       vat_json_object_add_ip4 (node, "local", ip4);
12867       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12868       vat_json_object_add_ip4 (node, "remote", ip4);
12869     }
12870   else
12871     {
12872       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12873       vat_json_object_add_ip6 (node, "local", ip6);
12874       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12875       vat_json_object_add_ip6 (node, "remote", ip6);
12876     }
12877   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12878   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12879   vat_json_object_add_uint (node, "mcast_sw_if_index",
12880                             ntohl (mp->mcast_sw_if_index));
12881   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12882   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12883   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12884 }
12885
12886 static int
12887 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12888 {
12889   unformat_input_t *i = vam->input;
12890   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12891   vl_api_control_ping_t *mp_ping;
12892   u32 sw_if_index;
12893   u8 sw_if_index_set = 0;
12894   int ret;
12895
12896   /* Parse args required to build the message */
12897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12898     {
12899       if (unformat (i, "sw_if_index %d", &sw_if_index))
12900         sw_if_index_set = 1;
12901       else
12902         break;
12903     }
12904
12905   if (sw_if_index_set == 0)
12906     {
12907       sw_if_index = ~0;
12908     }
12909
12910   if (!vam->json_output)
12911     {
12912       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12913              "sw_if_index", "local", "remote", "vni",
12914              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12915     }
12916
12917   /* Get list of vxlan-tunnel interfaces */
12918   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12919
12920   mp->sw_if_index = htonl (sw_if_index);
12921
12922   S (mp);
12923
12924   /* Use a control ping for synchronization */
12925   MPING (CONTROL_PING, mp_ping);
12926   S (mp_ping);
12927
12928   W (ret);
12929   return ret;
12930 }
12931
12932 static void vl_api_l2_fib_table_details_t_handler
12933   (vl_api_l2_fib_table_details_t * mp)
12934 {
12935   vat_main_t *vam = &vat_main;
12936
12937   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12938          "       %d       %d     %d",
12939          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12940          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12941          mp->bvi_mac);
12942 }
12943
12944 static void vl_api_l2_fib_table_details_t_handler_json
12945   (vl_api_l2_fib_table_details_t * mp)
12946 {
12947   vat_main_t *vam = &vat_main;
12948   vat_json_node_t *node = NULL;
12949
12950   if (VAT_JSON_ARRAY != vam->json_tree.type)
12951     {
12952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12953       vat_json_init_array (&vam->json_tree);
12954     }
12955   node = vat_json_array_add (&vam->json_tree);
12956
12957   vat_json_init_object (node);
12958   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12959   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12960   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12961   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12962   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12963   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12964 }
12965
12966 static int
12967 api_l2_fib_table_dump (vat_main_t * vam)
12968 {
12969   unformat_input_t *i = vam->input;
12970   vl_api_l2_fib_table_dump_t *mp;
12971   vl_api_control_ping_t *mp_ping;
12972   u32 bd_id;
12973   u8 bd_id_set = 0;
12974   int ret;
12975
12976   /* Parse args required to build the message */
12977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (i, "bd_id %d", &bd_id))
12980         bd_id_set = 1;
12981       else
12982         break;
12983     }
12984
12985   if (bd_id_set == 0)
12986     {
12987       errmsg ("missing bridge domain");
12988       return -99;
12989     }
12990
12991   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12992
12993   /* Get list of l2 fib entries */
12994   M (L2_FIB_TABLE_DUMP, mp);
12995
12996   mp->bd_id = ntohl (bd_id);
12997   S (mp);
12998
12999   /* Use a control ping for synchronization */
13000   MPING (CONTROL_PING, mp_ping);
13001   S (mp_ping);
13002
13003   W (ret);
13004   return ret;
13005 }
13006
13007
13008 static int
13009 api_interface_name_renumber (vat_main_t * vam)
13010 {
13011   unformat_input_t *line_input = vam->input;
13012   vl_api_interface_name_renumber_t *mp;
13013   u32 sw_if_index = ~0;
13014   u32 new_show_dev_instance = ~0;
13015   int ret;
13016
13017   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13018     {
13019       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13020                     &sw_if_index))
13021         ;
13022       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13023         ;
13024       else if (unformat (line_input, "new_show_dev_instance %d",
13025                          &new_show_dev_instance))
13026         ;
13027       else
13028         break;
13029     }
13030
13031   if (sw_if_index == ~0)
13032     {
13033       errmsg ("missing interface name or sw_if_index");
13034       return -99;
13035     }
13036
13037   if (new_show_dev_instance == ~0)
13038     {
13039       errmsg ("missing new_show_dev_instance");
13040       return -99;
13041     }
13042
13043   M (INTERFACE_NAME_RENUMBER, mp);
13044
13045   mp->sw_if_index = ntohl (sw_if_index);
13046   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13047
13048   S (mp);
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_want_l2_macs_events (vat_main_t * vam)
13055 {
13056   unformat_input_t *line_input = vam->input;
13057   vl_api_want_l2_macs_events_t *mp;
13058   u8 enable_disable = 1;
13059   u32 scan_delay = 0;
13060   u32 max_macs_in_event = 0;
13061   u32 learn_limit = 0;
13062   int ret;
13063
13064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13065     {
13066       if (unformat (line_input, "learn-limit %d", &learn_limit))
13067         ;
13068       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13069         ;
13070       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13071         ;
13072       else if (unformat (line_input, "disable"))
13073         enable_disable = 0;
13074       else
13075         break;
13076     }
13077
13078   M (WANT_L2_MACS_EVENTS, mp);
13079   mp->enable_disable = enable_disable;
13080   mp->pid = htonl (getpid ());
13081   mp->learn_limit = htonl (learn_limit);
13082   mp->scan_delay = (u8) scan_delay;
13083   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13084   S (mp);
13085   W (ret);
13086   return ret;
13087 }
13088
13089 static int
13090 api_input_acl_set_interface (vat_main_t * vam)
13091 {
13092   unformat_input_t *i = vam->input;
13093   vl_api_input_acl_set_interface_t *mp;
13094   u32 sw_if_index;
13095   int sw_if_index_set;
13096   u32 ip4_table_index = ~0;
13097   u32 ip6_table_index = ~0;
13098   u32 l2_table_index = ~0;
13099   u8 is_add = 1;
13100   int ret;
13101
13102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13105         sw_if_index_set = 1;
13106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13107         sw_if_index_set = 1;
13108       else if (unformat (i, "del"))
13109         is_add = 0;
13110       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13111         ;
13112       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13113         ;
13114       else if (unformat (i, "l2-table %d", &l2_table_index))
13115         ;
13116       else
13117         {
13118           clib_warning ("parse error '%U'", format_unformat_error, i);
13119           return -99;
13120         }
13121     }
13122
13123   if (sw_if_index_set == 0)
13124     {
13125       errmsg ("missing interface name or sw_if_index");
13126       return -99;
13127     }
13128
13129   M (INPUT_ACL_SET_INTERFACE, mp);
13130
13131   mp->sw_if_index = ntohl (sw_if_index);
13132   mp->ip4_table_index = ntohl (ip4_table_index);
13133   mp->ip6_table_index = ntohl (ip6_table_index);
13134   mp->l2_table_index = ntohl (l2_table_index);
13135   mp->is_add = is_add;
13136
13137   S (mp);
13138   W (ret);
13139   return ret;
13140 }
13141
13142 static int
13143 api_output_acl_set_interface (vat_main_t * vam)
13144 {
13145   unformat_input_t *i = vam->input;
13146   vl_api_output_acl_set_interface_t *mp;
13147   u32 sw_if_index;
13148   int sw_if_index_set;
13149   u32 ip4_table_index = ~0;
13150   u32 ip6_table_index = ~0;
13151   u32 l2_table_index = ~0;
13152   u8 is_add = 1;
13153   int ret;
13154
13155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13156     {
13157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13158         sw_if_index_set = 1;
13159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13160         sw_if_index_set = 1;
13161       else if (unformat (i, "del"))
13162         is_add = 0;
13163       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13164         ;
13165       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13166         ;
13167       else if (unformat (i, "l2-table %d", &l2_table_index))
13168         ;
13169       else
13170         {
13171           clib_warning ("parse error '%U'", format_unformat_error, i);
13172           return -99;
13173         }
13174     }
13175
13176   if (sw_if_index_set == 0)
13177     {
13178       errmsg ("missing interface name or sw_if_index");
13179       return -99;
13180     }
13181
13182   M (OUTPUT_ACL_SET_INTERFACE, mp);
13183
13184   mp->sw_if_index = ntohl (sw_if_index);
13185   mp->ip4_table_index = ntohl (ip4_table_index);
13186   mp->ip6_table_index = ntohl (ip6_table_index);
13187   mp->l2_table_index = ntohl (l2_table_index);
13188   mp->is_add = is_add;
13189
13190   S (mp);
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_ip_address_dump (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_ip_address_dump_t *mp;
13200   vl_api_control_ping_t *mp_ping;
13201   u32 sw_if_index = ~0;
13202   u8 sw_if_index_set = 0;
13203   u8 ipv4_set = 0;
13204   u8 ipv6_set = 0;
13205   int ret;
13206
13207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13208     {
13209       if (unformat (i, "sw_if_index %d", &sw_if_index))
13210         sw_if_index_set = 1;
13211       else
13212         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13213         sw_if_index_set = 1;
13214       else if (unformat (i, "ipv4"))
13215         ipv4_set = 1;
13216       else if (unformat (i, "ipv6"))
13217         ipv6_set = 1;
13218       else
13219         break;
13220     }
13221
13222   if (ipv4_set && ipv6_set)
13223     {
13224       errmsg ("ipv4 and ipv6 flags cannot be both set");
13225       return -99;
13226     }
13227
13228   if ((!ipv4_set) && (!ipv6_set))
13229     {
13230       errmsg ("no ipv4 nor ipv6 flag set");
13231       return -99;
13232     }
13233
13234   if (sw_if_index_set == 0)
13235     {
13236       errmsg ("missing interface name or sw_if_index");
13237       return -99;
13238     }
13239
13240   vam->current_sw_if_index = sw_if_index;
13241   vam->is_ipv6 = ipv6_set;
13242
13243   M (IP_ADDRESS_DUMP, mp);
13244   mp->sw_if_index = ntohl (sw_if_index);
13245   mp->is_ipv6 = ipv6_set;
13246   S (mp);
13247
13248   /* Use a control ping for synchronization */
13249   MPING (CONTROL_PING, mp_ping);
13250   S (mp_ping);
13251
13252   W (ret);
13253   return ret;
13254 }
13255
13256 static int
13257 api_ip_dump (vat_main_t * vam)
13258 {
13259   vl_api_ip_dump_t *mp;
13260   vl_api_control_ping_t *mp_ping;
13261   unformat_input_t *in = vam->input;
13262   int ipv4_set = 0;
13263   int ipv6_set = 0;
13264   int is_ipv6;
13265   int i;
13266   int ret;
13267
13268   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (in, "ipv4"))
13271         ipv4_set = 1;
13272       else if (unformat (in, "ipv6"))
13273         ipv6_set = 1;
13274       else
13275         break;
13276     }
13277
13278   if (ipv4_set && ipv6_set)
13279     {
13280       errmsg ("ipv4 and ipv6 flags cannot be both set");
13281       return -99;
13282     }
13283
13284   if ((!ipv4_set) && (!ipv6_set))
13285     {
13286       errmsg ("no ipv4 nor ipv6 flag set");
13287       return -99;
13288     }
13289
13290   is_ipv6 = ipv6_set;
13291   vam->is_ipv6 = is_ipv6;
13292
13293   /* free old data */
13294   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13295     {
13296       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13297     }
13298   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13299
13300   M (IP_DUMP, mp);
13301   mp->is_ipv6 = ipv6_set;
13302   S (mp);
13303
13304   /* Use a control ping for synchronization */
13305   MPING (CONTROL_PING, mp_ping);
13306   S (mp_ping);
13307
13308   W (ret);
13309   return ret;
13310 }
13311
13312 static int
13313 api_ipsec_spd_add_del (vat_main_t * vam)
13314 {
13315   unformat_input_t *i = vam->input;
13316   vl_api_ipsec_spd_add_del_t *mp;
13317   u32 spd_id = ~0;
13318   u8 is_add = 1;
13319   int ret;
13320
13321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (i, "spd_id %d", &spd_id))
13324         ;
13325       else if (unformat (i, "del"))
13326         is_add = 0;
13327       else
13328         {
13329           clib_warning ("parse error '%U'", format_unformat_error, i);
13330           return -99;
13331         }
13332     }
13333   if (spd_id == ~0)
13334     {
13335       errmsg ("spd_id must be set");
13336       return -99;
13337     }
13338
13339   M (IPSEC_SPD_ADD_DEL, mp);
13340
13341   mp->spd_id = ntohl (spd_id);
13342   mp->is_add = is_add;
13343
13344   S (mp);
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_ipsec_interface_add_del_spd_t *mp;
13354   u32 sw_if_index;
13355   u8 sw_if_index_set = 0;
13356   u32 spd_id = (u32) ~ 0;
13357   u8 is_add = 1;
13358   int ret;
13359
13360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13361     {
13362       if (unformat (i, "del"))
13363         is_add = 0;
13364       else if (unformat (i, "spd_id %d", &spd_id))
13365         ;
13366       else
13367         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13368         sw_if_index_set = 1;
13369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13370         sw_if_index_set = 1;
13371       else
13372         {
13373           clib_warning ("parse error '%U'", format_unformat_error, i);
13374           return -99;
13375         }
13376
13377     }
13378
13379   if (spd_id == (u32) ~ 0)
13380     {
13381       errmsg ("spd_id must be set");
13382       return -99;
13383     }
13384
13385   if (sw_if_index_set == 0)
13386     {
13387       errmsg ("missing interface name or sw_if_index");
13388       return -99;
13389     }
13390
13391   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13392
13393   mp->spd_id = ntohl (spd_id);
13394   mp->sw_if_index = ntohl (sw_if_index);
13395   mp->is_add = is_add;
13396
13397   S (mp);
13398   W (ret);
13399   return ret;
13400 }
13401
13402 static int
13403 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13404 {
13405   unformat_input_t *i = vam->input;
13406   vl_api_ipsec_spd_entry_add_del_t *mp;
13407   u8 is_add = 1, is_outbound = 0;
13408   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13409   i32 priority = 0;
13410   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13411   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13412   vl_api_address_t laddr_start = { }, laddr_stop =
13413   {
13414   }, raddr_start =
13415   {
13416   }, raddr_stop =
13417   {
13418   };
13419   int ret;
13420
13421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (i, "del"))
13424         is_add = 0;
13425       if (unformat (i, "outbound"))
13426         is_outbound = 1;
13427       if (unformat (i, "inbound"))
13428         is_outbound = 0;
13429       else if (unformat (i, "spd_id %d", &spd_id))
13430         ;
13431       else if (unformat (i, "sa_id %d", &sa_id))
13432         ;
13433       else if (unformat (i, "priority %d", &priority))
13434         ;
13435       else if (unformat (i, "protocol %d", &protocol))
13436         ;
13437       else if (unformat (i, "lport_start %d", &lport_start))
13438         ;
13439       else if (unformat (i, "lport_stop %d", &lport_stop))
13440         ;
13441       else if (unformat (i, "rport_start %d", &rport_start))
13442         ;
13443       else if (unformat (i, "rport_stop %d", &rport_stop))
13444         ;
13445       else if (unformat (i, "laddr_start %U",
13446                          unformat_vl_api_address, &laddr_start))
13447         ;
13448       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13449                          &laddr_stop))
13450         ;
13451       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13452                          &raddr_start))
13453         ;
13454       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13455                          &raddr_stop))
13456         ;
13457       else
13458         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13459         {
13460           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13461             {
13462               clib_warning ("unsupported action: 'resolve'");
13463               return -99;
13464             }
13465         }
13466       else
13467         {
13468           clib_warning ("parse error '%U'", format_unformat_error, i);
13469           return -99;
13470         }
13471
13472     }
13473
13474   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13475
13476   mp->is_add = is_add;
13477
13478   mp->entry.spd_id = ntohl (spd_id);
13479   mp->entry.priority = ntohl (priority);
13480   mp->entry.is_outbound = is_outbound;
13481
13482   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13483                sizeof (vl_api_address_t));
13484   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13485                sizeof (vl_api_address_t));
13486   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13487                sizeof (vl_api_address_t));
13488   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13489                sizeof (vl_api_address_t));
13490
13491   mp->entry.protocol = (u8) protocol;
13492   mp->entry.local_port_start = ntohs ((u16) lport_start);
13493   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13494   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13495   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13496   mp->entry.policy = (u8) policy;
13497   mp->entry.sa_id = ntohl (sa_id);
13498
13499   S (mp);
13500   W (ret);
13501   return ret;
13502 }
13503
13504 static int
13505 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13506 {
13507   unformat_input_t *i = vam->input;
13508   vl_api_ipsec_sad_entry_add_del_t *mp;
13509   u32 sad_id = 0, spi = 0;
13510   u8 *ck = 0, *ik = 0;
13511   u8 is_add = 1;
13512
13513   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13514   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13515   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13516   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13517   vl_api_address_t tun_src, tun_dst;
13518   int ret;
13519
13520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13521     {
13522       if (unformat (i, "del"))
13523         is_add = 0;
13524       else if (unformat (i, "sad_id %d", &sad_id))
13525         ;
13526       else if (unformat (i, "spi %d", &spi))
13527         ;
13528       else if (unformat (i, "esp"))
13529         protocol = IPSEC_API_PROTO_ESP;
13530       else
13531         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13532         {
13533           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13534           if (ADDRESS_IP6 == tun_src.af)
13535             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13536         }
13537       else
13538         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13539         {
13540           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13541           if (ADDRESS_IP6 == tun_src.af)
13542             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13543         }
13544       else
13545         if (unformat (i, "crypto_alg %U",
13546                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13547         ;
13548       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13549         ;
13550       else if (unformat (i, "integ_alg %U",
13551                          unformat_ipsec_api_integ_alg, &integ_alg))
13552         ;
13553       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13554         ;
13555       else
13556         {
13557           clib_warning ("parse error '%U'", format_unformat_error, i);
13558           return -99;
13559         }
13560
13561     }
13562
13563   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13564
13565   mp->is_add = is_add;
13566   mp->entry.sad_id = ntohl (sad_id);
13567   mp->entry.protocol = protocol;
13568   mp->entry.spi = ntohl (spi);
13569   mp->entry.flags = flags;
13570
13571   mp->entry.crypto_algorithm = crypto_alg;
13572   mp->entry.integrity_algorithm = integ_alg;
13573   mp->entry.crypto_key.length = vec_len (ck);
13574   mp->entry.integrity_key.length = vec_len (ik);
13575
13576   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13577     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13578
13579   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13580     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13581
13582   if (ck)
13583     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13584   if (ik)
13585     clib_memcpy (mp->entry.integrity_key.data, ik,
13586                  mp->entry.integrity_key.length);
13587
13588   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13589     {
13590       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13591                    sizeof (mp->entry.tunnel_src));
13592       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13593                    sizeof (mp->entry.tunnel_dst));
13594     }
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13603 {
13604   unformat_input_t *i = vam->input;
13605   vl_api_ipsec_tunnel_if_add_del_t *mp;
13606   u32 local_spi = 0, remote_spi = 0;
13607   u32 crypto_alg = 0, integ_alg = 0;
13608   u8 *lck = NULL, *rck = NULL;
13609   u8 *lik = NULL, *rik = NULL;
13610   vl_api_address_t local_ip = { 0 };
13611   vl_api_address_t remote_ip = { 0 };
13612   f64 before = 0;
13613   u8 is_add = 1;
13614   u8 esn = 0;
13615   u8 anti_replay = 0;
13616   u8 renumber = 0;
13617   u32 instance = ~0;
13618   u32 count = 1, jj;
13619   int ret = -1;
13620
13621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (i, "del"))
13624         is_add = 0;
13625       else if (unformat (i, "esn"))
13626         esn = 1;
13627       else if (unformat (i, "anti-replay"))
13628         anti_replay = 1;
13629       else if (unformat (i, "count %d", &count))
13630         ;
13631       else if (unformat (i, "local_spi %d", &local_spi))
13632         ;
13633       else if (unformat (i, "remote_spi %d", &remote_spi))
13634         ;
13635       else
13636         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13637         ;
13638       else
13639         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13640         ;
13641       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13642         ;
13643       else
13644         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13645         ;
13646       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13647         ;
13648       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13649         ;
13650       else
13651         if (unformat
13652             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13653         {
13654           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13655             {
13656               errmsg ("unsupported crypto-alg: '%U'\n",
13657                       format_ipsec_crypto_alg, crypto_alg);
13658               return -99;
13659             }
13660         }
13661       else
13662         if (unformat
13663             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13664         {
13665           if (integ_alg >= IPSEC_INTEG_N_ALG)
13666             {
13667               errmsg ("unsupported integ-alg: '%U'\n",
13668                       format_ipsec_integ_alg, integ_alg);
13669               return -99;
13670             }
13671         }
13672       else if (unformat (i, "instance %u", &instance))
13673         renumber = 1;
13674       else
13675         {
13676           errmsg ("parse error '%U'\n", format_unformat_error, i);
13677           return -99;
13678         }
13679     }
13680
13681   if (count > 1)
13682     {
13683       /* Turn on async mode */
13684       vam->async_mode = 1;
13685       vam->async_errors = 0;
13686       before = vat_time_now (vam);
13687     }
13688
13689   for (jj = 0; jj < count; jj++)
13690     {
13691       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13692
13693       mp->is_add = is_add;
13694       mp->esn = esn;
13695       mp->anti_replay = anti_replay;
13696
13697       if (jj > 0)
13698         increment_address (&remote_ip);
13699
13700       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13701       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13702
13703       mp->local_spi = htonl (local_spi + jj);
13704       mp->remote_spi = htonl (remote_spi + jj);
13705       mp->crypto_alg = (u8) crypto_alg;
13706
13707       mp->local_crypto_key_len = 0;
13708       if (lck)
13709         {
13710           mp->local_crypto_key_len = vec_len (lck);
13711           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13712             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13713           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13714         }
13715
13716       mp->remote_crypto_key_len = 0;
13717       if (rck)
13718         {
13719           mp->remote_crypto_key_len = vec_len (rck);
13720           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13721             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13722           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13723         }
13724
13725       mp->integ_alg = (u8) integ_alg;
13726
13727       mp->local_integ_key_len = 0;
13728       if (lik)
13729         {
13730           mp->local_integ_key_len = vec_len (lik);
13731           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13732             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13733           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13734         }
13735
13736       mp->remote_integ_key_len = 0;
13737       if (rik)
13738         {
13739           mp->remote_integ_key_len = vec_len (rik);
13740           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13741             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13742           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13743         }
13744
13745       if (renumber)
13746         {
13747           mp->renumber = renumber;
13748           mp->show_instance = ntohl (instance);
13749         }
13750       S (mp);
13751     }
13752
13753   /* When testing multiple add/del ops, use a control-ping to sync */
13754   if (count > 1)
13755     {
13756       vl_api_control_ping_t *mp_ping;
13757       f64 after;
13758       f64 timeout;
13759
13760       /* Shut off async mode */
13761       vam->async_mode = 0;
13762
13763       MPING (CONTROL_PING, mp_ping);
13764       S (mp_ping);
13765
13766       timeout = vat_time_now (vam) + 1.0;
13767       while (vat_time_now (vam) < timeout)
13768         if (vam->result_ready == 1)
13769           goto out;
13770       vam->retval = -99;
13771
13772     out:
13773       if (vam->retval == -99)
13774         errmsg ("timeout");
13775
13776       if (vam->async_errors > 0)
13777         {
13778           errmsg ("%d asynchronous errors", vam->async_errors);
13779           vam->retval = -98;
13780         }
13781       vam->async_errors = 0;
13782       after = vat_time_now (vam);
13783
13784       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13785       if (jj > 0)
13786         count = jj;
13787
13788       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13789              count, after - before, count / (after - before));
13790     }
13791   else
13792     {
13793       /* Wait for a reply... */
13794       W (ret);
13795       return ret;
13796     }
13797
13798   return ret;
13799 }
13800
13801 static void
13802 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805
13806   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13807          "crypto_key %U integ_alg %u integ_key %U flags %x "
13808          "tunnel_src_addr %U tunnel_dst_addr %U "
13809          "salt %u seq_outbound %lu last_seq_inbound %lu "
13810          "replay_window %lu stat_index %u\n",
13811          ntohl (mp->entry.sad_id),
13812          ntohl (mp->sw_if_index),
13813          ntohl (mp->entry.spi),
13814          ntohl (mp->entry.protocol),
13815          ntohl (mp->entry.crypto_algorithm),
13816          format_hex_bytes, mp->entry.crypto_key.data,
13817          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13818          format_hex_bytes, mp->entry.integrity_key.data,
13819          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13820          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13821          &mp->entry.tunnel_dst, ntohl (mp->salt),
13822          clib_net_to_host_u64 (mp->seq_outbound),
13823          clib_net_to_host_u64 (mp->last_seq_inbound),
13824          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13825 }
13826
13827 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13828 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13829
13830 static void vl_api_ipsec_sa_details_t_handler_json
13831   (vl_api_ipsec_sa_details_t * mp)
13832 {
13833   vat_main_t *vam = &vat_main;
13834   vat_json_node_t *node = NULL;
13835   vl_api_ipsec_sad_flags_t flags;
13836
13837   if (VAT_JSON_ARRAY != vam->json_tree.type)
13838     {
13839       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13840       vat_json_init_array (&vam->json_tree);
13841     }
13842   node = vat_json_array_add (&vam->json_tree);
13843
13844   vat_json_init_object (node);
13845   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13847   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13848   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13849   vat_json_object_add_uint (node, "crypto_alg",
13850                             ntohl (mp->entry.crypto_algorithm));
13851   vat_json_object_add_uint (node, "integ_alg",
13852                             ntohl (mp->entry.integrity_algorithm));
13853   flags = ntohl (mp->entry.flags);
13854   vat_json_object_add_uint (node, "use_esn",
13855                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13856   vat_json_object_add_uint (node, "use_anti_replay",
13857                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13858   vat_json_object_add_uint (node, "is_tunnel",
13859                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13860   vat_json_object_add_uint (node, "is_tunnel_ip6",
13861                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13862   vat_json_object_add_uint (node, "udp_encap",
13863                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13864   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13865                              mp->entry.crypto_key.length);
13866   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13867                              mp->entry.integrity_key.length);
13868   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13869   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13870   vat_json_object_add_uint (node, "replay_window",
13871                             clib_net_to_host_u64 (mp->replay_window));
13872   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13873 }
13874
13875 static int
13876 api_ipsec_sa_dump (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_ipsec_sa_dump_t *mp;
13880   vl_api_control_ping_t *mp_ping;
13881   u32 sa_id = ~0;
13882   int ret;
13883
13884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (i, "sa_id %d", &sa_id))
13887         ;
13888       else
13889         {
13890           clib_warning ("parse error '%U'", format_unformat_error, i);
13891           return -99;
13892         }
13893     }
13894
13895   M (IPSEC_SA_DUMP, mp);
13896
13897   mp->sa_id = ntohl (sa_id);
13898
13899   S (mp);
13900
13901   /* Use a control ping for synchronization */
13902   M (CONTROL_PING, mp_ping);
13903   S (mp_ping);
13904
13905   W (ret);
13906   return ret;
13907 }
13908
13909 static int
13910 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13911 {
13912   unformat_input_t *i = vam->input;
13913   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13914   u32 sw_if_index = ~0;
13915   u32 sa_id = ~0;
13916   u8 is_outbound = (u8) ~ 0;
13917   int ret;
13918
13919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13920     {
13921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13922         ;
13923       else if (unformat (i, "sa_id %d", &sa_id))
13924         ;
13925       else if (unformat (i, "outbound"))
13926         is_outbound = 1;
13927       else if (unformat (i, "inbound"))
13928         is_outbound = 0;
13929       else
13930         {
13931           clib_warning ("parse error '%U'", format_unformat_error, i);
13932           return -99;
13933         }
13934     }
13935
13936   if (sw_if_index == ~0)
13937     {
13938       errmsg ("interface must be specified");
13939       return -99;
13940     }
13941
13942   if (sa_id == ~0)
13943     {
13944       errmsg ("SA ID must be specified");
13945       return -99;
13946     }
13947
13948   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13949
13950   mp->sw_if_index = htonl (sw_if_index);
13951   mp->sa_id = htonl (sa_id);
13952   mp->is_outbound = is_outbound;
13953
13954   S (mp);
13955   W (ret);
13956
13957   return ret;
13958 }
13959
13960 static int
13961 api_get_first_msg_id (vat_main_t * vam)
13962 {
13963   vl_api_get_first_msg_id_t *mp;
13964   unformat_input_t *i = vam->input;
13965   u8 *name;
13966   u8 name_set = 0;
13967   int ret;
13968
13969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13970     {
13971       if (unformat (i, "client %s", &name))
13972         name_set = 1;
13973       else
13974         break;
13975     }
13976
13977   if (name_set == 0)
13978     {
13979       errmsg ("missing client name");
13980       return -99;
13981     }
13982   vec_add1 (name, 0);
13983
13984   if (vec_len (name) > 63)
13985     {
13986       errmsg ("client name too long");
13987       return -99;
13988     }
13989
13990   M (GET_FIRST_MSG_ID, mp);
13991   clib_memcpy (mp->name, name, vec_len (name));
13992   S (mp);
13993   W (ret);
13994   return ret;
13995 }
13996
13997 static int
13998 api_cop_interface_enable_disable (vat_main_t * vam)
13999 {
14000   unformat_input_t *line_input = vam->input;
14001   vl_api_cop_interface_enable_disable_t *mp;
14002   u32 sw_if_index = ~0;
14003   u8 enable_disable = 1;
14004   int ret;
14005
14006   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (line_input, "disable"))
14009         enable_disable = 0;
14010       if (unformat (line_input, "enable"))
14011         enable_disable = 1;
14012       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14013                          vam, &sw_if_index))
14014         ;
14015       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14016         ;
14017       else
14018         break;
14019     }
14020
14021   if (sw_if_index == ~0)
14022     {
14023       errmsg ("missing interface name or sw_if_index");
14024       return -99;
14025     }
14026
14027   /* Construct the API message */
14028   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14029   mp->sw_if_index = ntohl (sw_if_index);
14030   mp->enable_disable = enable_disable;
14031
14032   /* send it... */
14033   S (mp);
14034   /* Wait for the reply */
14035   W (ret);
14036   return ret;
14037 }
14038
14039 static int
14040 api_cop_whitelist_enable_disable (vat_main_t * vam)
14041 {
14042   unformat_input_t *line_input = vam->input;
14043   vl_api_cop_whitelist_enable_disable_t *mp;
14044   u32 sw_if_index = ~0;
14045   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14046   u32 fib_id = 0;
14047   int ret;
14048
14049   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14050     {
14051       if (unformat (line_input, "ip4"))
14052         ip4 = 1;
14053       else if (unformat (line_input, "ip6"))
14054         ip6 = 1;
14055       else if (unformat (line_input, "default"))
14056         default_cop = 1;
14057       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14058                          vam, &sw_if_index))
14059         ;
14060       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14061         ;
14062       else if (unformat (line_input, "fib-id %d", &fib_id))
14063         ;
14064       else
14065         break;
14066     }
14067
14068   if (sw_if_index == ~0)
14069     {
14070       errmsg ("missing interface name or sw_if_index");
14071       return -99;
14072     }
14073
14074   /* Construct the API message */
14075   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14076   mp->sw_if_index = ntohl (sw_if_index);
14077   mp->fib_id = ntohl (fib_id);
14078   mp->ip4 = ip4;
14079   mp->ip6 = ip6;
14080   mp->default_cop = default_cop;
14081
14082   /* send it... */
14083   S (mp);
14084   /* Wait for the reply */
14085   W (ret);
14086   return ret;
14087 }
14088
14089 static int
14090 api_get_node_graph (vat_main_t * vam)
14091 {
14092   vl_api_get_node_graph_t *mp;
14093   int ret;
14094
14095   M (GET_NODE_GRAPH, mp);
14096
14097   /* send it... */
14098   S (mp);
14099   /* Wait for the reply */
14100   W (ret);
14101   return ret;
14102 }
14103
14104 /* *INDENT-OFF* */
14105 /** Used for parsing LISP eids */
14106 typedef CLIB_PACKED(struct{
14107   u8 addr[16];   /**< eid address */
14108   u32 len;       /**< prefix length if IP */
14109   u8 type;      /**< type of eid */
14110 }) lisp_eid_vat_t;
14111 /* *INDENT-ON* */
14112
14113 static uword
14114 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14115 {
14116   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14117
14118   clib_memset (a, 0, sizeof (a[0]));
14119
14120   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14121     {
14122       a->type = 0;              /* ipv4 type */
14123     }
14124   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14125     {
14126       a->type = 1;              /* ipv6 type */
14127     }
14128   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14129     {
14130       a->type = 2;              /* mac type */
14131     }
14132   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14133     {
14134       a->type = 3;              /* NSH type */
14135       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14136       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14137     }
14138   else
14139     {
14140       return 0;
14141     }
14142
14143   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14144     {
14145       return 0;
14146     }
14147
14148   return 1;
14149 }
14150
14151 static int
14152 lisp_eid_size_vat (u8 type)
14153 {
14154   switch (type)
14155     {
14156     case 0:
14157       return 4;
14158     case 1:
14159       return 16;
14160     case 2:
14161       return 6;
14162     case 3:
14163       return 5;
14164     }
14165   return 0;
14166 }
14167
14168 static void
14169 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14170 {
14171   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14172 }
14173
14174 static int
14175 api_one_add_del_locator_set (vat_main_t * vam)
14176 {
14177   unformat_input_t *input = vam->input;
14178   vl_api_one_add_del_locator_set_t *mp;
14179   u8 is_add = 1;
14180   u8 *locator_set_name = NULL;
14181   u8 locator_set_name_set = 0;
14182   vl_api_local_locator_t locator, *locators = 0;
14183   u32 sw_if_index, priority, weight;
14184   u32 data_len = 0;
14185
14186   int ret;
14187   /* Parse args required to build the message */
14188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14189     {
14190       if (unformat (input, "del"))
14191         {
14192           is_add = 0;
14193         }
14194       else if (unformat (input, "locator-set %s", &locator_set_name))
14195         {
14196           locator_set_name_set = 1;
14197         }
14198       else if (unformat (input, "sw_if_index %u p %u w %u",
14199                          &sw_if_index, &priority, &weight))
14200         {
14201           locator.sw_if_index = htonl (sw_if_index);
14202           locator.priority = priority;
14203           locator.weight = weight;
14204           vec_add1 (locators, locator);
14205         }
14206       else
14207         if (unformat
14208             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14209              &sw_if_index, &priority, &weight))
14210         {
14211           locator.sw_if_index = htonl (sw_if_index);
14212           locator.priority = priority;
14213           locator.weight = weight;
14214           vec_add1 (locators, locator);
14215         }
14216       else
14217         break;
14218     }
14219
14220   if (locator_set_name_set == 0)
14221     {
14222       errmsg ("missing locator-set name");
14223       vec_free (locators);
14224       return -99;
14225     }
14226
14227   if (vec_len (locator_set_name) > 64)
14228     {
14229       errmsg ("locator-set name too long");
14230       vec_free (locator_set_name);
14231       vec_free (locators);
14232       return -99;
14233     }
14234   vec_add1 (locator_set_name, 0);
14235
14236   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14237
14238   /* Construct the API message */
14239   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14240
14241   mp->is_add = is_add;
14242   clib_memcpy (mp->locator_set_name, locator_set_name,
14243                vec_len (locator_set_name));
14244   vec_free (locator_set_name);
14245
14246   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14247   if (locators)
14248     clib_memcpy (mp->locators, locators, data_len);
14249   vec_free (locators);
14250
14251   /* send it... */
14252   S (mp);
14253
14254   /* Wait for a reply... */
14255   W (ret);
14256   return ret;
14257 }
14258
14259 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14260
14261 static int
14262 api_one_add_del_locator (vat_main_t * vam)
14263 {
14264   unformat_input_t *input = vam->input;
14265   vl_api_one_add_del_locator_t *mp;
14266   u32 tmp_if_index = ~0;
14267   u32 sw_if_index = ~0;
14268   u8 sw_if_index_set = 0;
14269   u8 sw_if_index_if_name_set = 0;
14270   u32 priority = ~0;
14271   u8 priority_set = 0;
14272   u32 weight = ~0;
14273   u8 weight_set = 0;
14274   u8 is_add = 1;
14275   u8 *locator_set_name = NULL;
14276   u8 locator_set_name_set = 0;
14277   int ret;
14278
14279   /* Parse args required to build the message */
14280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14281     {
14282       if (unformat (input, "del"))
14283         {
14284           is_add = 0;
14285         }
14286       else if (unformat (input, "locator-set %s", &locator_set_name))
14287         {
14288           locator_set_name_set = 1;
14289         }
14290       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14291                          &tmp_if_index))
14292         {
14293           sw_if_index_if_name_set = 1;
14294           sw_if_index = tmp_if_index;
14295         }
14296       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14297         {
14298           sw_if_index_set = 1;
14299           sw_if_index = tmp_if_index;
14300         }
14301       else if (unformat (input, "p %d", &priority))
14302         {
14303           priority_set = 1;
14304         }
14305       else if (unformat (input, "w %d", &weight))
14306         {
14307           weight_set = 1;
14308         }
14309       else
14310         break;
14311     }
14312
14313   if (locator_set_name_set == 0)
14314     {
14315       errmsg ("missing locator-set name");
14316       return -99;
14317     }
14318
14319   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14320     {
14321       errmsg ("missing sw_if_index");
14322       vec_free (locator_set_name);
14323       return -99;
14324     }
14325
14326   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14327     {
14328       errmsg ("cannot use both params interface name and sw_if_index");
14329       vec_free (locator_set_name);
14330       return -99;
14331     }
14332
14333   if (priority_set == 0)
14334     {
14335       errmsg ("missing locator-set priority");
14336       vec_free (locator_set_name);
14337       return -99;
14338     }
14339
14340   if (weight_set == 0)
14341     {
14342       errmsg ("missing locator-set weight");
14343       vec_free (locator_set_name);
14344       return -99;
14345     }
14346
14347   if (vec_len (locator_set_name) > 64)
14348     {
14349       errmsg ("locator-set name too long");
14350       vec_free (locator_set_name);
14351       return -99;
14352     }
14353   vec_add1 (locator_set_name, 0);
14354
14355   /* Construct the API message */
14356   M (ONE_ADD_DEL_LOCATOR, mp);
14357
14358   mp->is_add = is_add;
14359   mp->sw_if_index = ntohl (sw_if_index);
14360   mp->priority = priority;
14361   mp->weight = weight;
14362   clib_memcpy (mp->locator_set_name, locator_set_name,
14363                vec_len (locator_set_name));
14364   vec_free (locator_set_name);
14365
14366   /* send it... */
14367   S (mp);
14368
14369   /* Wait for a reply... */
14370   W (ret);
14371   return ret;
14372 }
14373
14374 #define api_lisp_add_del_locator api_one_add_del_locator
14375
14376 uword
14377 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14378 {
14379   u32 *key_id = va_arg (*args, u32 *);
14380   u8 *s = 0;
14381
14382   if (unformat (input, "%s", &s))
14383     {
14384       if (!strcmp ((char *) s, "sha1"))
14385         key_id[0] = HMAC_SHA_1_96;
14386       else if (!strcmp ((char *) s, "sha256"))
14387         key_id[0] = HMAC_SHA_256_128;
14388       else
14389         {
14390           clib_warning ("invalid key_id: '%s'", s);
14391           key_id[0] = HMAC_NO_KEY;
14392         }
14393     }
14394   else
14395     return 0;
14396
14397   vec_free (s);
14398   return 1;
14399 }
14400
14401 static int
14402 api_one_add_del_local_eid (vat_main_t * vam)
14403 {
14404   unformat_input_t *input = vam->input;
14405   vl_api_one_add_del_local_eid_t *mp;
14406   u8 is_add = 1;
14407   u8 eid_set = 0;
14408   lisp_eid_vat_t _eid, *eid = &_eid;
14409   u8 *locator_set_name = 0;
14410   u8 locator_set_name_set = 0;
14411   u32 vni = 0;
14412   u16 key_id = 0;
14413   u8 *key = 0;
14414   int ret;
14415
14416   /* Parse args required to build the message */
14417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14418     {
14419       if (unformat (input, "del"))
14420         {
14421           is_add = 0;
14422         }
14423       else if (unformat (input, "vni %d", &vni))
14424         {
14425           ;
14426         }
14427       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14428         {
14429           eid_set = 1;
14430         }
14431       else if (unformat (input, "locator-set %s", &locator_set_name))
14432         {
14433           locator_set_name_set = 1;
14434         }
14435       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14436         ;
14437       else if (unformat (input, "secret-key %_%v%_", &key))
14438         ;
14439       else
14440         break;
14441     }
14442
14443   if (locator_set_name_set == 0)
14444     {
14445       errmsg ("missing locator-set name");
14446       return -99;
14447     }
14448
14449   if (0 == eid_set)
14450     {
14451       errmsg ("EID address not set!");
14452       vec_free (locator_set_name);
14453       return -99;
14454     }
14455
14456   if (key && (0 == key_id))
14457     {
14458       errmsg ("invalid key_id!");
14459       return -99;
14460     }
14461
14462   if (vec_len (key) > 64)
14463     {
14464       errmsg ("key too long");
14465       vec_free (key);
14466       return -99;
14467     }
14468
14469   if (vec_len (locator_set_name) > 64)
14470     {
14471       errmsg ("locator-set name too long");
14472       vec_free (locator_set_name);
14473       return -99;
14474     }
14475   vec_add1 (locator_set_name, 0);
14476
14477   /* Construct the API message */
14478   M (ONE_ADD_DEL_LOCAL_EID, mp);
14479
14480   mp->is_add = is_add;
14481   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14482   mp->eid_type = eid->type;
14483   mp->prefix_len = eid->len;
14484   mp->vni = clib_host_to_net_u32 (vni);
14485   mp->key_id = clib_host_to_net_u16 (key_id);
14486   clib_memcpy (mp->locator_set_name, locator_set_name,
14487                vec_len (locator_set_name));
14488   clib_memcpy (mp->key, key, vec_len (key));
14489
14490   vec_free (locator_set_name);
14491   vec_free (key);
14492
14493   /* send it... */
14494   S (mp);
14495
14496   /* Wait for a reply... */
14497   W (ret);
14498   return ret;
14499 }
14500
14501 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14502
14503 static int
14504 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14505 {
14506   u32 dp_table = 0, vni = 0;;
14507   unformat_input_t *input = vam->input;
14508   vl_api_gpe_add_del_fwd_entry_t *mp;
14509   u8 is_add = 1;
14510   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14511   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14512   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14513   u32 action = ~0, w;
14514   ip4_address_t rmt_rloc4, lcl_rloc4;
14515   ip6_address_t rmt_rloc6, lcl_rloc6;
14516   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14517   int ret;
14518
14519   clib_memset (&rloc, 0, sizeof (rloc));
14520
14521   /* Parse args required to build the message */
14522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (input, "del"))
14525         is_add = 0;
14526       else if (unformat (input, "add"))
14527         is_add = 1;
14528       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14529         {
14530           rmt_eid_set = 1;
14531         }
14532       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14533         {
14534           lcl_eid_set = 1;
14535         }
14536       else if (unformat (input, "vrf %d", &dp_table))
14537         ;
14538       else if (unformat (input, "bd %d", &dp_table))
14539         ;
14540       else if (unformat (input, "vni %d", &vni))
14541         ;
14542       else if (unformat (input, "w %d", &w))
14543         {
14544           if (!curr_rloc)
14545             {
14546               errmsg ("No RLOC configured for setting priority/weight!");
14547               return -99;
14548             }
14549           curr_rloc->weight = w;
14550         }
14551       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14552                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14553         {
14554           rloc.is_ip4 = 1;
14555
14556           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14557           rloc.weight = 0;
14558           vec_add1 (lcl_locs, rloc);
14559
14560           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14561           vec_add1 (rmt_locs, rloc);
14562           /* weight saved in rmt loc */
14563           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14564         }
14565       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14566                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14567         {
14568           rloc.is_ip4 = 0;
14569           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14570           rloc.weight = 0;
14571           vec_add1 (lcl_locs, rloc);
14572
14573           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14574           vec_add1 (rmt_locs, rloc);
14575           /* weight saved in rmt loc */
14576           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14577         }
14578       else if (unformat (input, "action %d", &action))
14579         {
14580           ;
14581         }
14582       else
14583         {
14584           clib_warning ("parse error '%U'", format_unformat_error, input);
14585           return -99;
14586         }
14587     }
14588
14589   if (!rmt_eid_set)
14590     {
14591       errmsg ("remote eid addresses not set");
14592       return -99;
14593     }
14594
14595   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14596     {
14597       errmsg ("eid types don't match");
14598       return -99;
14599     }
14600
14601   if (0 == rmt_locs && (u32) ~ 0 == action)
14602     {
14603       errmsg ("action not set for negative mapping");
14604       return -99;
14605     }
14606
14607   /* Construct the API message */
14608   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14609       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14610
14611   mp->is_add = is_add;
14612   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14613   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14614   mp->eid_type = rmt_eid->type;
14615   mp->dp_table = clib_host_to_net_u32 (dp_table);
14616   mp->vni = clib_host_to_net_u32 (vni);
14617   mp->rmt_len = rmt_eid->len;
14618   mp->lcl_len = lcl_eid->len;
14619   mp->action = action;
14620
14621   if (0 != rmt_locs && 0 != lcl_locs)
14622     {
14623       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14624       clib_memcpy (mp->locs, lcl_locs,
14625                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14626
14627       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14628       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14629                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14630     }
14631   vec_free (lcl_locs);
14632   vec_free (rmt_locs);
14633
14634   /* send it... */
14635   S (mp);
14636
14637   /* Wait for a reply... */
14638   W (ret);
14639   return ret;
14640 }
14641
14642 static int
14643 api_one_add_del_map_server (vat_main_t * vam)
14644 {
14645   unformat_input_t *input = vam->input;
14646   vl_api_one_add_del_map_server_t *mp;
14647   u8 is_add = 1;
14648   u8 ipv4_set = 0;
14649   u8 ipv6_set = 0;
14650   ip4_address_t ipv4;
14651   ip6_address_t ipv6;
14652   int ret;
14653
14654   /* Parse args required to build the message */
14655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14656     {
14657       if (unformat (input, "del"))
14658         {
14659           is_add = 0;
14660         }
14661       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14662         {
14663           ipv4_set = 1;
14664         }
14665       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14666         {
14667           ipv6_set = 1;
14668         }
14669       else
14670         break;
14671     }
14672
14673   if (ipv4_set && ipv6_set)
14674     {
14675       errmsg ("both eid v4 and v6 addresses set");
14676       return -99;
14677     }
14678
14679   if (!ipv4_set && !ipv6_set)
14680     {
14681       errmsg ("eid addresses not set");
14682       return -99;
14683     }
14684
14685   /* Construct the API message */
14686   M (ONE_ADD_DEL_MAP_SERVER, mp);
14687
14688   mp->is_add = is_add;
14689   if (ipv6_set)
14690     {
14691       mp->is_ipv6 = 1;
14692       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14693     }
14694   else
14695     {
14696       mp->is_ipv6 = 0;
14697       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14698     }
14699
14700   /* send it... */
14701   S (mp);
14702
14703   /* Wait for a reply... */
14704   W (ret);
14705   return ret;
14706 }
14707
14708 #define api_lisp_add_del_map_server api_one_add_del_map_server
14709
14710 static int
14711 api_one_add_del_map_resolver (vat_main_t * vam)
14712 {
14713   unformat_input_t *input = vam->input;
14714   vl_api_one_add_del_map_resolver_t *mp;
14715   u8 is_add = 1;
14716   u8 ipv4_set = 0;
14717   u8 ipv6_set = 0;
14718   ip4_address_t ipv4;
14719   ip6_address_t ipv6;
14720   int ret;
14721
14722   /* Parse args required to build the message */
14723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (input, "del"))
14726         {
14727           is_add = 0;
14728         }
14729       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14730         {
14731           ipv4_set = 1;
14732         }
14733       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14734         {
14735           ipv6_set = 1;
14736         }
14737       else
14738         break;
14739     }
14740
14741   if (ipv4_set && ipv6_set)
14742     {
14743       errmsg ("both eid v4 and v6 addresses set");
14744       return -99;
14745     }
14746
14747   if (!ipv4_set && !ipv6_set)
14748     {
14749       errmsg ("eid addresses not set");
14750       return -99;
14751     }
14752
14753   /* Construct the API message */
14754   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14755
14756   mp->is_add = is_add;
14757   if (ipv6_set)
14758     {
14759       mp->is_ipv6 = 1;
14760       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14761     }
14762   else
14763     {
14764       mp->is_ipv6 = 0;
14765       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14766     }
14767
14768   /* send it... */
14769   S (mp);
14770
14771   /* Wait for a reply... */
14772   W (ret);
14773   return ret;
14774 }
14775
14776 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14777
14778 static int
14779 api_lisp_gpe_enable_disable (vat_main_t * vam)
14780 {
14781   unformat_input_t *input = vam->input;
14782   vl_api_gpe_enable_disable_t *mp;
14783   u8 is_set = 0;
14784   u8 is_en = 1;
14785   int ret;
14786
14787   /* Parse args required to build the message */
14788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14789     {
14790       if (unformat (input, "enable"))
14791         {
14792           is_set = 1;
14793           is_en = 1;
14794         }
14795       else if (unformat (input, "disable"))
14796         {
14797           is_set = 1;
14798           is_en = 0;
14799         }
14800       else
14801         break;
14802     }
14803
14804   if (is_set == 0)
14805     {
14806       errmsg ("Value not set");
14807       return -99;
14808     }
14809
14810   /* Construct the API message */
14811   M (GPE_ENABLE_DISABLE, mp);
14812
14813   mp->is_en = is_en;
14814
14815   /* send it... */
14816   S (mp);
14817
14818   /* Wait for a reply... */
14819   W (ret);
14820   return ret;
14821 }
14822
14823 static int
14824 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14825 {
14826   unformat_input_t *input = vam->input;
14827   vl_api_one_rloc_probe_enable_disable_t *mp;
14828   u8 is_set = 0;
14829   u8 is_en = 0;
14830   int ret;
14831
14832   /* Parse args required to build the message */
14833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14834     {
14835       if (unformat (input, "enable"))
14836         {
14837           is_set = 1;
14838           is_en = 1;
14839         }
14840       else if (unformat (input, "disable"))
14841         is_set = 1;
14842       else
14843         break;
14844     }
14845
14846   if (!is_set)
14847     {
14848       errmsg ("Value not set");
14849       return -99;
14850     }
14851
14852   /* Construct the API message */
14853   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14854
14855   mp->is_enabled = is_en;
14856
14857   /* send it... */
14858   S (mp);
14859
14860   /* Wait for a reply... */
14861   W (ret);
14862   return ret;
14863 }
14864
14865 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14866
14867 static int
14868 api_one_map_register_enable_disable (vat_main_t * vam)
14869 {
14870   unformat_input_t *input = vam->input;
14871   vl_api_one_map_register_enable_disable_t *mp;
14872   u8 is_set = 0;
14873   u8 is_en = 0;
14874   int ret;
14875
14876   /* Parse args required to build the message */
14877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14878     {
14879       if (unformat (input, "enable"))
14880         {
14881           is_set = 1;
14882           is_en = 1;
14883         }
14884       else if (unformat (input, "disable"))
14885         is_set = 1;
14886       else
14887         break;
14888     }
14889
14890   if (!is_set)
14891     {
14892       errmsg ("Value not set");
14893       return -99;
14894     }
14895
14896   /* Construct the API message */
14897   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14898
14899   mp->is_enabled = is_en;
14900
14901   /* send it... */
14902   S (mp);
14903
14904   /* Wait for a reply... */
14905   W (ret);
14906   return ret;
14907 }
14908
14909 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14910
14911 static int
14912 api_one_enable_disable (vat_main_t * vam)
14913 {
14914   unformat_input_t *input = vam->input;
14915   vl_api_one_enable_disable_t *mp;
14916   u8 is_set = 0;
14917   u8 is_en = 0;
14918   int ret;
14919
14920   /* Parse args required to build the message */
14921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (input, "enable"))
14924         {
14925           is_set = 1;
14926           is_en = 1;
14927         }
14928       else if (unformat (input, "disable"))
14929         {
14930           is_set = 1;
14931         }
14932       else
14933         break;
14934     }
14935
14936   if (!is_set)
14937     {
14938       errmsg ("Value not set");
14939       return -99;
14940     }
14941
14942   /* Construct the API message */
14943   M (ONE_ENABLE_DISABLE, mp);
14944
14945   mp->is_en = is_en;
14946
14947   /* send it... */
14948   S (mp);
14949
14950   /* Wait for a reply... */
14951   W (ret);
14952   return ret;
14953 }
14954
14955 #define api_lisp_enable_disable api_one_enable_disable
14956
14957 static int
14958 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14959 {
14960   unformat_input_t *input = vam->input;
14961   vl_api_one_enable_disable_xtr_mode_t *mp;
14962   u8 is_set = 0;
14963   u8 is_en = 0;
14964   int ret;
14965
14966   /* Parse args required to build the message */
14967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14968     {
14969       if (unformat (input, "enable"))
14970         {
14971           is_set = 1;
14972           is_en = 1;
14973         }
14974       else if (unformat (input, "disable"))
14975         {
14976           is_set = 1;
14977         }
14978       else
14979         break;
14980     }
14981
14982   if (!is_set)
14983     {
14984       errmsg ("Value not set");
14985       return -99;
14986     }
14987
14988   /* Construct the API message */
14989   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14990
14991   mp->is_en = is_en;
14992
14993   /* send it... */
14994   S (mp);
14995
14996   /* Wait for a reply... */
14997   W (ret);
14998   return ret;
14999 }
15000
15001 static int
15002 api_one_show_xtr_mode (vat_main_t * vam)
15003 {
15004   vl_api_one_show_xtr_mode_t *mp;
15005   int ret;
15006
15007   /* Construct the API message */
15008   M (ONE_SHOW_XTR_MODE, mp);
15009
15010   /* send it... */
15011   S (mp);
15012
15013   /* Wait for a reply... */
15014   W (ret);
15015   return ret;
15016 }
15017
15018 static int
15019 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15020 {
15021   unformat_input_t *input = vam->input;
15022   vl_api_one_enable_disable_pitr_mode_t *mp;
15023   u8 is_set = 0;
15024   u8 is_en = 0;
15025   int ret;
15026
15027   /* Parse args required to build the message */
15028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15029     {
15030       if (unformat (input, "enable"))
15031         {
15032           is_set = 1;
15033           is_en = 1;
15034         }
15035       else if (unformat (input, "disable"))
15036         {
15037           is_set = 1;
15038         }
15039       else
15040         break;
15041     }
15042
15043   if (!is_set)
15044     {
15045       errmsg ("Value not set");
15046       return -99;
15047     }
15048
15049   /* Construct the API message */
15050   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15051
15052   mp->is_en = is_en;
15053
15054   /* send it... */
15055   S (mp);
15056
15057   /* Wait for a reply... */
15058   W (ret);
15059   return ret;
15060 }
15061
15062 static int
15063 api_one_show_pitr_mode (vat_main_t * vam)
15064 {
15065   vl_api_one_show_pitr_mode_t *mp;
15066   int ret;
15067
15068   /* Construct the API message */
15069   M (ONE_SHOW_PITR_MODE, mp);
15070
15071   /* send it... */
15072   S (mp);
15073
15074   /* Wait for a reply... */
15075   W (ret);
15076   return ret;
15077 }
15078
15079 static int
15080 api_one_enable_disable_petr_mode (vat_main_t * vam)
15081 {
15082   unformat_input_t *input = vam->input;
15083   vl_api_one_enable_disable_petr_mode_t *mp;
15084   u8 is_set = 0;
15085   u8 is_en = 0;
15086   int ret;
15087
15088   /* Parse args required to build the message */
15089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15090     {
15091       if (unformat (input, "enable"))
15092         {
15093           is_set = 1;
15094           is_en = 1;
15095         }
15096       else if (unformat (input, "disable"))
15097         {
15098           is_set = 1;
15099         }
15100       else
15101         break;
15102     }
15103
15104   if (!is_set)
15105     {
15106       errmsg ("Value not set");
15107       return -99;
15108     }
15109
15110   /* Construct the API message */
15111   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15112
15113   mp->is_en = is_en;
15114
15115   /* send it... */
15116   S (mp);
15117
15118   /* Wait for a reply... */
15119   W (ret);
15120   return ret;
15121 }
15122
15123 static int
15124 api_one_show_petr_mode (vat_main_t * vam)
15125 {
15126   vl_api_one_show_petr_mode_t *mp;
15127   int ret;
15128
15129   /* Construct the API message */
15130   M (ONE_SHOW_PETR_MODE, mp);
15131
15132   /* send it... */
15133   S (mp);
15134
15135   /* Wait for a reply... */
15136   W (ret);
15137   return ret;
15138 }
15139
15140 static int
15141 api_show_one_map_register_state (vat_main_t * vam)
15142 {
15143   vl_api_show_one_map_register_state_t *mp;
15144   int ret;
15145
15146   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15147
15148   /* send */
15149   S (mp);
15150
15151   /* wait for reply */
15152   W (ret);
15153   return ret;
15154 }
15155
15156 #define api_show_lisp_map_register_state api_show_one_map_register_state
15157
15158 static int
15159 api_show_one_rloc_probe_state (vat_main_t * vam)
15160 {
15161   vl_api_show_one_rloc_probe_state_t *mp;
15162   int ret;
15163
15164   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15165
15166   /* send */
15167   S (mp);
15168
15169   /* wait for reply */
15170   W (ret);
15171   return ret;
15172 }
15173
15174 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15175
15176 static int
15177 api_one_add_del_ndp_entry (vat_main_t * vam)
15178 {
15179   vl_api_one_add_del_ndp_entry_t *mp;
15180   unformat_input_t *input = vam->input;
15181   u8 is_add = 1;
15182   u8 mac_set = 0;
15183   u8 bd_set = 0;
15184   u8 ip_set = 0;
15185   u8 mac[6] = { 0, };
15186   u8 ip6[16] = { 0, };
15187   u32 bd = ~0;
15188   int ret;
15189
15190   /* Parse args required to build the message */
15191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15192     {
15193       if (unformat (input, "del"))
15194         is_add = 0;
15195       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15196         mac_set = 1;
15197       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15198         ip_set = 1;
15199       else if (unformat (input, "bd %d", &bd))
15200         bd_set = 1;
15201       else
15202         {
15203           errmsg ("parse error '%U'", format_unformat_error, input);
15204           return -99;
15205         }
15206     }
15207
15208   if (!bd_set || !ip_set || (!mac_set && is_add))
15209     {
15210       errmsg ("Missing BD, IP or MAC!");
15211       return -99;
15212     }
15213
15214   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15215   mp->is_add = is_add;
15216   clib_memcpy (mp->mac, mac, 6);
15217   mp->bd = clib_host_to_net_u32 (bd);
15218   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15219
15220   /* send */
15221   S (mp);
15222
15223   /* wait for reply */
15224   W (ret);
15225   return ret;
15226 }
15227
15228 static int
15229 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15230 {
15231   vl_api_one_add_del_l2_arp_entry_t *mp;
15232   unformat_input_t *input = vam->input;
15233   u8 is_add = 1;
15234   u8 mac_set = 0;
15235   u8 bd_set = 0;
15236   u8 ip_set = 0;
15237   u8 mac[6] = { 0, };
15238   u32 ip4 = 0, bd = ~0;
15239   int ret;
15240
15241   /* Parse args required to build the message */
15242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15243     {
15244       if (unformat (input, "del"))
15245         is_add = 0;
15246       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15247         mac_set = 1;
15248       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15249         ip_set = 1;
15250       else if (unformat (input, "bd %d", &bd))
15251         bd_set = 1;
15252       else
15253         {
15254           errmsg ("parse error '%U'", format_unformat_error, input);
15255           return -99;
15256         }
15257     }
15258
15259   if (!bd_set || !ip_set || (!mac_set && is_add))
15260     {
15261       errmsg ("Missing BD, IP or MAC!");
15262       return -99;
15263     }
15264
15265   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15266   mp->is_add = is_add;
15267   clib_memcpy (mp->mac, mac, 6);
15268   mp->bd = clib_host_to_net_u32 (bd);
15269   mp->ip4 = ip4;
15270
15271   /* send */
15272   S (mp);
15273
15274   /* wait for reply */
15275   W (ret);
15276   return ret;
15277 }
15278
15279 static int
15280 api_one_ndp_bd_get (vat_main_t * vam)
15281 {
15282   vl_api_one_ndp_bd_get_t *mp;
15283   int ret;
15284
15285   M (ONE_NDP_BD_GET, mp);
15286
15287   /* send */
15288   S (mp);
15289
15290   /* wait for reply */
15291   W (ret);
15292   return ret;
15293 }
15294
15295 static int
15296 api_one_ndp_entries_get (vat_main_t * vam)
15297 {
15298   vl_api_one_ndp_entries_get_t *mp;
15299   unformat_input_t *input = vam->input;
15300   u8 bd_set = 0;
15301   u32 bd = ~0;
15302   int ret;
15303
15304   /* Parse args required to build the message */
15305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15306     {
15307       if (unformat (input, "bd %d", &bd))
15308         bd_set = 1;
15309       else
15310         {
15311           errmsg ("parse error '%U'", format_unformat_error, input);
15312           return -99;
15313         }
15314     }
15315
15316   if (!bd_set)
15317     {
15318       errmsg ("Expected bridge domain!");
15319       return -99;
15320     }
15321
15322   M (ONE_NDP_ENTRIES_GET, mp);
15323   mp->bd = clib_host_to_net_u32 (bd);
15324
15325   /* send */
15326   S (mp);
15327
15328   /* wait for reply */
15329   W (ret);
15330   return ret;
15331 }
15332
15333 static int
15334 api_one_l2_arp_bd_get (vat_main_t * vam)
15335 {
15336   vl_api_one_l2_arp_bd_get_t *mp;
15337   int ret;
15338
15339   M (ONE_L2_ARP_BD_GET, mp);
15340
15341   /* send */
15342   S (mp);
15343
15344   /* wait for reply */
15345   W (ret);
15346   return ret;
15347 }
15348
15349 static int
15350 api_one_l2_arp_entries_get (vat_main_t * vam)
15351 {
15352   vl_api_one_l2_arp_entries_get_t *mp;
15353   unformat_input_t *input = vam->input;
15354   u8 bd_set = 0;
15355   u32 bd = ~0;
15356   int ret;
15357
15358   /* Parse args required to build the message */
15359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15360     {
15361       if (unformat (input, "bd %d", &bd))
15362         bd_set = 1;
15363       else
15364         {
15365           errmsg ("parse error '%U'", format_unformat_error, input);
15366           return -99;
15367         }
15368     }
15369
15370   if (!bd_set)
15371     {
15372       errmsg ("Expected bridge domain!");
15373       return -99;
15374     }
15375
15376   M (ONE_L2_ARP_ENTRIES_GET, mp);
15377   mp->bd = clib_host_to_net_u32 (bd);
15378
15379   /* send */
15380   S (mp);
15381
15382   /* wait for reply */
15383   W (ret);
15384   return ret;
15385 }
15386
15387 static int
15388 api_one_stats_enable_disable (vat_main_t * vam)
15389 {
15390   vl_api_one_stats_enable_disable_t *mp;
15391   unformat_input_t *input = vam->input;
15392   u8 is_set = 0;
15393   u8 is_en = 0;
15394   int ret;
15395
15396   /* Parse args required to build the message */
15397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15398     {
15399       if (unformat (input, "enable"))
15400         {
15401           is_set = 1;
15402           is_en = 1;
15403         }
15404       else if (unformat (input, "disable"))
15405         {
15406           is_set = 1;
15407         }
15408       else
15409         break;
15410     }
15411
15412   if (!is_set)
15413     {
15414       errmsg ("Value not set");
15415       return -99;
15416     }
15417
15418   M (ONE_STATS_ENABLE_DISABLE, mp);
15419   mp->is_en = is_en;
15420
15421   /* send */
15422   S (mp);
15423
15424   /* wait for reply */
15425   W (ret);
15426   return ret;
15427 }
15428
15429 static int
15430 api_show_one_stats_enable_disable (vat_main_t * vam)
15431 {
15432   vl_api_show_one_stats_enable_disable_t *mp;
15433   int ret;
15434
15435   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15436
15437   /* send */
15438   S (mp);
15439
15440   /* wait for reply */
15441   W (ret);
15442   return ret;
15443 }
15444
15445 static int
15446 api_show_one_map_request_mode (vat_main_t * vam)
15447 {
15448   vl_api_show_one_map_request_mode_t *mp;
15449   int ret;
15450
15451   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15452
15453   /* send */
15454   S (mp);
15455
15456   /* wait for reply */
15457   W (ret);
15458   return ret;
15459 }
15460
15461 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15462
15463 static int
15464 api_one_map_request_mode (vat_main_t * vam)
15465 {
15466   unformat_input_t *input = vam->input;
15467   vl_api_one_map_request_mode_t *mp;
15468   u8 mode = 0;
15469   int ret;
15470
15471   /* Parse args required to build the message */
15472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15473     {
15474       if (unformat (input, "dst-only"))
15475         mode = 0;
15476       else if (unformat (input, "src-dst"))
15477         mode = 1;
15478       else
15479         {
15480           errmsg ("parse error '%U'", format_unformat_error, input);
15481           return -99;
15482         }
15483     }
15484
15485   M (ONE_MAP_REQUEST_MODE, mp);
15486
15487   mp->mode = mode;
15488
15489   /* send */
15490   S (mp);
15491
15492   /* wait for reply */
15493   W (ret);
15494   return ret;
15495 }
15496
15497 #define api_lisp_map_request_mode api_one_map_request_mode
15498
15499 /**
15500  * Enable/disable ONE proxy ITR.
15501  *
15502  * @param vam vpp API test context
15503  * @return return code
15504  */
15505 static int
15506 api_one_pitr_set_locator_set (vat_main_t * vam)
15507 {
15508   u8 ls_name_set = 0;
15509   unformat_input_t *input = vam->input;
15510   vl_api_one_pitr_set_locator_set_t *mp;
15511   u8 is_add = 1;
15512   u8 *ls_name = 0;
15513   int ret;
15514
15515   /* Parse args required to build the message */
15516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15517     {
15518       if (unformat (input, "del"))
15519         is_add = 0;
15520       else if (unformat (input, "locator-set %s", &ls_name))
15521         ls_name_set = 1;
15522       else
15523         {
15524           errmsg ("parse error '%U'", format_unformat_error, input);
15525           return -99;
15526         }
15527     }
15528
15529   if (!ls_name_set)
15530     {
15531       errmsg ("locator-set name not set!");
15532       return -99;
15533     }
15534
15535   M (ONE_PITR_SET_LOCATOR_SET, mp);
15536
15537   mp->is_add = is_add;
15538   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15539   vec_free (ls_name);
15540
15541   /* send */
15542   S (mp);
15543
15544   /* wait for reply */
15545   W (ret);
15546   return ret;
15547 }
15548
15549 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15550
15551 static int
15552 api_one_nsh_set_locator_set (vat_main_t * vam)
15553 {
15554   u8 ls_name_set = 0;
15555   unformat_input_t *input = vam->input;
15556   vl_api_one_nsh_set_locator_set_t *mp;
15557   u8 is_add = 1;
15558   u8 *ls_name = 0;
15559   int ret;
15560
15561   /* Parse args required to build the message */
15562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15563     {
15564       if (unformat (input, "del"))
15565         is_add = 0;
15566       else if (unformat (input, "ls %s", &ls_name))
15567         ls_name_set = 1;
15568       else
15569         {
15570           errmsg ("parse error '%U'", format_unformat_error, input);
15571           return -99;
15572         }
15573     }
15574
15575   if (!ls_name_set && is_add)
15576     {
15577       errmsg ("locator-set name not set!");
15578       return -99;
15579     }
15580
15581   M (ONE_NSH_SET_LOCATOR_SET, mp);
15582
15583   mp->is_add = is_add;
15584   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15585   vec_free (ls_name);
15586
15587   /* send */
15588   S (mp);
15589
15590   /* wait for reply */
15591   W (ret);
15592   return ret;
15593 }
15594
15595 static int
15596 api_show_one_pitr (vat_main_t * vam)
15597 {
15598   vl_api_show_one_pitr_t *mp;
15599   int ret;
15600
15601   if (!vam->json_output)
15602     {
15603       print (vam->ofp, "%=20s", "lisp status:");
15604     }
15605
15606   M (SHOW_ONE_PITR, mp);
15607   /* send it... */
15608   S (mp);
15609
15610   /* Wait for a reply... */
15611   W (ret);
15612   return ret;
15613 }
15614
15615 #define api_show_lisp_pitr api_show_one_pitr
15616
15617 static int
15618 api_one_use_petr (vat_main_t * vam)
15619 {
15620   unformat_input_t *input = vam->input;
15621   vl_api_one_use_petr_t *mp;
15622   u8 is_add = 0;
15623   ip_address_t ip;
15624   int ret;
15625
15626   clib_memset (&ip, 0, sizeof (ip));
15627
15628   /* Parse args required to build the message */
15629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (input, "disable"))
15632         is_add = 0;
15633       else
15634         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15635         {
15636           is_add = 1;
15637           ip_addr_version (&ip) = AF_IP4;
15638         }
15639       else
15640         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15641         {
15642           is_add = 1;
15643           ip_addr_version (&ip) = AF_IP6;
15644         }
15645       else
15646         {
15647           errmsg ("parse error '%U'", format_unformat_error, input);
15648           return -99;
15649         }
15650     }
15651
15652   M (ONE_USE_PETR, mp);
15653
15654   mp->is_add = is_add;
15655   if (is_add)
15656     {
15657       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15658       if (mp->is_ip4)
15659         clib_memcpy (mp->address, &ip, 4);
15660       else
15661         clib_memcpy (mp->address, &ip, 16);
15662     }
15663
15664   /* send */
15665   S (mp);
15666
15667   /* wait for reply */
15668   W (ret);
15669   return ret;
15670 }
15671
15672 #define api_lisp_use_petr api_one_use_petr
15673
15674 static int
15675 api_show_one_nsh_mapping (vat_main_t * vam)
15676 {
15677   vl_api_show_one_use_petr_t *mp;
15678   int ret;
15679
15680   if (!vam->json_output)
15681     {
15682       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15683     }
15684
15685   M (SHOW_ONE_NSH_MAPPING, mp);
15686   /* send it... */
15687   S (mp);
15688
15689   /* Wait for a reply... */
15690   W (ret);
15691   return ret;
15692 }
15693
15694 static int
15695 api_show_one_use_petr (vat_main_t * vam)
15696 {
15697   vl_api_show_one_use_petr_t *mp;
15698   int ret;
15699
15700   if (!vam->json_output)
15701     {
15702       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15703     }
15704
15705   M (SHOW_ONE_USE_PETR, mp);
15706   /* send it... */
15707   S (mp);
15708
15709   /* Wait for a reply... */
15710   W (ret);
15711   return ret;
15712 }
15713
15714 #define api_show_lisp_use_petr api_show_one_use_petr
15715
15716 /**
15717  * Add/delete mapping between vni and vrf
15718  */
15719 static int
15720 api_one_eid_table_add_del_map (vat_main_t * vam)
15721 {
15722   unformat_input_t *input = vam->input;
15723   vl_api_one_eid_table_add_del_map_t *mp;
15724   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15725   u32 vni, vrf, bd_index;
15726   int ret;
15727
15728   /* Parse args required to build the message */
15729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15730     {
15731       if (unformat (input, "del"))
15732         is_add = 0;
15733       else if (unformat (input, "vrf %d", &vrf))
15734         vrf_set = 1;
15735       else if (unformat (input, "bd_index %d", &bd_index))
15736         bd_index_set = 1;
15737       else if (unformat (input, "vni %d", &vni))
15738         vni_set = 1;
15739       else
15740         break;
15741     }
15742
15743   if (!vni_set || (!vrf_set && !bd_index_set))
15744     {
15745       errmsg ("missing arguments!");
15746       return -99;
15747     }
15748
15749   if (vrf_set && bd_index_set)
15750     {
15751       errmsg ("error: both vrf and bd entered!");
15752       return -99;
15753     }
15754
15755   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15756
15757   mp->is_add = is_add;
15758   mp->vni = htonl (vni);
15759   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15760   mp->is_l2 = bd_index_set;
15761
15762   /* send */
15763   S (mp);
15764
15765   /* wait for reply */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15771
15772 uword
15773 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15774 {
15775   u32 *action = va_arg (*args, u32 *);
15776   u8 *s = 0;
15777
15778   if (unformat (input, "%s", &s))
15779     {
15780       if (!strcmp ((char *) s, "no-action"))
15781         action[0] = 0;
15782       else if (!strcmp ((char *) s, "natively-forward"))
15783         action[0] = 1;
15784       else if (!strcmp ((char *) s, "send-map-request"))
15785         action[0] = 2;
15786       else if (!strcmp ((char *) s, "drop"))
15787         action[0] = 3;
15788       else
15789         {
15790           clib_warning ("invalid action: '%s'", s);
15791           action[0] = 3;
15792         }
15793     }
15794   else
15795     return 0;
15796
15797   vec_free (s);
15798   return 1;
15799 }
15800
15801 /**
15802  * Add/del remote mapping to/from ONE control plane
15803  *
15804  * @param vam vpp API test context
15805  * @return return code
15806  */
15807 static int
15808 api_one_add_del_remote_mapping (vat_main_t * vam)
15809 {
15810   unformat_input_t *input = vam->input;
15811   vl_api_one_add_del_remote_mapping_t *mp;
15812   u32 vni = 0;
15813   lisp_eid_vat_t _eid, *eid = &_eid;
15814   lisp_eid_vat_t _seid, *seid = &_seid;
15815   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15816   u32 action = ~0, p, w, data_len;
15817   ip4_address_t rloc4;
15818   ip6_address_t rloc6;
15819   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15820   int ret;
15821
15822   clib_memset (&rloc, 0, sizeof (rloc));
15823
15824   /* Parse args required to build the message */
15825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (input, "del-all"))
15828         {
15829           del_all = 1;
15830         }
15831       else if (unformat (input, "del"))
15832         {
15833           is_add = 0;
15834         }
15835       else if (unformat (input, "add"))
15836         {
15837           is_add = 1;
15838         }
15839       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15840         {
15841           eid_set = 1;
15842         }
15843       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15844         {
15845           seid_set = 1;
15846         }
15847       else if (unformat (input, "vni %d", &vni))
15848         {
15849           ;
15850         }
15851       else if (unformat (input, "p %d w %d", &p, &w))
15852         {
15853           if (!curr_rloc)
15854             {
15855               errmsg ("No RLOC configured for setting priority/weight!");
15856               return -99;
15857             }
15858           curr_rloc->priority = p;
15859           curr_rloc->weight = w;
15860         }
15861       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15862         {
15863           rloc.is_ip4 = 1;
15864           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15865           vec_add1 (rlocs, rloc);
15866           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15867         }
15868       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15869         {
15870           rloc.is_ip4 = 0;
15871           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15872           vec_add1 (rlocs, rloc);
15873           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15874         }
15875       else if (unformat (input, "action %U",
15876                          unformat_negative_mapping_action, &action))
15877         {
15878           ;
15879         }
15880       else
15881         {
15882           clib_warning ("parse error '%U'", format_unformat_error, input);
15883           return -99;
15884         }
15885     }
15886
15887   if (0 == eid_set)
15888     {
15889       errmsg ("missing params!");
15890       return -99;
15891     }
15892
15893   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15894     {
15895       errmsg ("no action set for negative map-reply!");
15896       return -99;
15897     }
15898
15899   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15900
15901   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15902   mp->is_add = is_add;
15903   mp->vni = htonl (vni);
15904   mp->action = (u8) action;
15905   mp->is_src_dst = seid_set;
15906   mp->eid_len = eid->len;
15907   mp->seid_len = seid->len;
15908   mp->del_all = del_all;
15909   mp->eid_type = eid->type;
15910   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15911   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15912
15913   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15914   clib_memcpy (mp->rlocs, rlocs, data_len);
15915   vec_free (rlocs);
15916
15917   /* send it... */
15918   S (mp);
15919
15920   /* Wait for a reply... */
15921   W (ret);
15922   return ret;
15923 }
15924
15925 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15926
15927 /**
15928  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15929  * forwarding entries in data-plane accordingly.
15930  *
15931  * @param vam vpp API test context
15932  * @return return code
15933  */
15934 static int
15935 api_one_add_del_adjacency (vat_main_t * vam)
15936 {
15937   unformat_input_t *input = vam->input;
15938   vl_api_one_add_del_adjacency_t *mp;
15939   u32 vni = 0;
15940   ip4_address_t leid4, reid4;
15941   ip6_address_t leid6, reid6;
15942   u8 reid_mac[6] = { 0 };
15943   u8 leid_mac[6] = { 0 };
15944   u8 reid_type, leid_type;
15945   u32 leid_len = 0, reid_len = 0, len;
15946   u8 is_add = 1;
15947   int ret;
15948
15949   leid_type = reid_type = (u8) ~ 0;
15950
15951   /* Parse args required to build the message */
15952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15953     {
15954       if (unformat (input, "del"))
15955         {
15956           is_add = 0;
15957         }
15958       else if (unformat (input, "add"))
15959         {
15960           is_add = 1;
15961         }
15962       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15963                          &reid4, &len))
15964         {
15965           reid_type = 0;        /* ipv4 */
15966           reid_len = len;
15967         }
15968       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15969                          &reid6, &len))
15970         {
15971           reid_type = 1;        /* ipv6 */
15972           reid_len = len;
15973         }
15974       else if (unformat (input, "reid %U", unformat_ethernet_address,
15975                          reid_mac))
15976         {
15977           reid_type = 2;        /* mac */
15978         }
15979       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15980                          &leid4, &len))
15981         {
15982           leid_type = 0;        /* ipv4 */
15983           leid_len = len;
15984         }
15985       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15986                          &leid6, &len))
15987         {
15988           leid_type = 1;        /* ipv6 */
15989           leid_len = len;
15990         }
15991       else if (unformat (input, "leid %U", unformat_ethernet_address,
15992                          leid_mac))
15993         {
15994           leid_type = 2;        /* mac */
15995         }
15996       else if (unformat (input, "vni %d", &vni))
15997         {
15998           ;
15999         }
16000       else
16001         {
16002           errmsg ("parse error '%U'", format_unformat_error, input);
16003           return -99;
16004         }
16005     }
16006
16007   if ((u8) ~ 0 == reid_type)
16008     {
16009       errmsg ("missing params!");
16010       return -99;
16011     }
16012
16013   if (leid_type != reid_type)
16014     {
16015       errmsg ("remote and local EIDs are of different types!");
16016       return -99;
16017     }
16018
16019   M (ONE_ADD_DEL_ADJACENCY, mp);
16020   mp->is_add = is_add;
16021   mp->vni = htonl (vni);
16022   mp->leid_len = leid_len;
16023   mp->reid_len = reid_len;
16024   mp->eid_type = reid_type;
16025
16026   switch (mp->eid_type)
16027     {
16028     case 0:
16029       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16030       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16031       break;
16032     case 1:
16033       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16034       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16035       break;
16036     case 2:
16037       clib_memcpy (mp->leid, leid_mac, 6);
16038       clib_memcpy (mp->reid, reid_mac, 6);
16039       break;
16040     default:
16041       errmsg ("unknown EID type %d!", mp->eid_type);
16042       return 0;
16043     }
16044
16045   /* send it... */
16046   S (mp);
16047
16048   /* Wait for a reply... */
16049   W (ret);
16050   return ret;
16051 }
16052
16053 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16054
16055 uword
16056 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16057 {
16058   u32 *mode = va_arg (*args, u32 *);
16059
16060   if (unformat (input, "lisp"))
16061     *mode = 0;
16062   else if (unformat (input, "vxlan"))
16063     *mode = 1;
16064   else
16065     return 0;
16066
16067   return 1;
16068 }
16069
16070 static int
16071 api_gpe_get_encap_mode (vat_main_t * vam)
16072 {
16073   vl_api_gpe_get_encap_mode_t *mp;
16074   int ret;
16075
16076   /* Construct the API message */
16077   M (GPE_GET_ENCAP_MODE, mp);
16078
16079   /* send it... */
16080   S (mp);
16081
16082   /* Wait for a reply... */
16083   W (ret);
16084   return ret;
16085 }
16086
16087 static int
16088 api_gpe_set_encap_mode (vat_main_t * vam)
16089 {
16090   unformat_input_t *input = vam->input;
16091   vl_api_gpe_set_encap_mode_t *mp;
16092   int ret;
16093   u32 mode = 0;
16094
16095   /* Parse args required to build the message */
16096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16097     {
16098       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16099         ;
16100       else
16101         break;
16102     }
16103
16104   /* Construct the API message */
16105   M (GPE_SET_ENCAP_MODE, mp);
16106
16107   mp->mode = mode;
16108
16109   /* send it... */
16110   S (mp);
16111
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16119 {
16120   unformat_input_t *input = vam->input;
16121   vl_api_gpe_add_del_iface_t *mp;
16122   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16123   u32 dp_table = 0, vni = 0;
16124   int ret;
16125
16126   /* Parse args required to build the message */
16127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (input, "up"))
16130         {
16131           action_set = 1;
16132           is_add = 1;
16133         }
16134       else if (unformat (input, "down"))
16135         {
16136           action_set = 1;
16137           is_add = 0;
16138         }
16139       else if (unformat (input, "table_id %d", &dp_table))
16140         {
16141           dp_table_set = 1;
16142         }
16143       else if (unformat (input, "bd_id %d", &dp_table))
16144         {
16145           dp_table_set = 1;
16146           is_l2 = 1;
16147         }
16148       else if (unformat (input, "vni %d", &vni))
16149         {
16150           vni_set = 1;
16151         }
16152       else
16153         break;
16154     }
16155
16156   if (action_set == 0)
16157     {
16158       errmsg ("Action not set");
16159       return -99;
16160     }
16161   if (dp_table_set == 0 || vni_set == 0)
16162     {
16163       errmsg ("vni and dp_table must be set");
16164       return -99;
16165     }
16166
16167   /* Construct the API message */
16168   M (GPE_ADD_DEL_IFACE, mp);
16169
16170   mp->is_add = is_add;
16171   mp->dp_table = clib_host_to_net_u32 (dp_table);
16172   mp->is_l2 = is_l2;
16173   mp->vni = clib_host_to_net_u32 (vni);
16174
16175   /* send it... */
16176   S (mp);
16177
16178   /* Wait for a reply... */
16179   W (ret);
16180   return ret;
16181 }
16182
16183 static int
16184 api_one_map_register_fallback_threshold (vat_main_t * vam)
16185 {
16186   unformat_input_t *input = vam->input;
16187   vl_api_one_map_register_fallback_threshold_t *mp;
16188   u32 value = 0;
16189   u8 is_set = 0;
16190   int ret;
16191
16192   /* Parse args required to build the message */
16193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16194     {
16195       if (unformat (input, "%u", &value))
16196         is_set = 1;
16197       else
16198         {
16199           clib_warning ("parse error '%U'", format_unformat_error, input);
16200           return -99;
16201         }
16202     }
16203
16204   if (!is_set)
16205     {
16206       errmsg ("fallback threshold value is missing!");
16207       return -99;
16208     }
16209
16210   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16211   mp->value = clib_host_to_net_u32 (value);
16212
16213   /* send it... */
16214   S (mp);
16215
16216   /* Wait for a reply... */
16217   W (ret);
16218   return ret;
16219 }
16220
16221 static int
16222 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16223 {
16224   vl_api_show_one_map_register_fallback_threshold_t *mp;
16225   int ret;
16226
16227   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16228
16229   /* send it... */
16230   S (mp);
16231
16232   /* Wait for a reply... */
16233   W (ret);
16234   return ret;
16235 }
16236
16237 uword
16238 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16239 {
16240   u32 *proto = va_arg (*args, u32 *);
16241
16242   if (unformat (input, "udp"))
16243     *proto = 1;
16244   else if (unformat (input, "api"))
16245     *proto = 2;
16246   else
16247     return 0;
16248
16249   return 1;
16250 }
16251
16252 static int
16253 api_one_set_transport_protocol (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_one_set_transport_protocol_t *mp;
16257   u8 is_set = 0;
16258   u32 protocol = 0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16265         is_set = 1;
16266       else
16267         {
16268           clib_warning ("parse error '%U'", format_unformat_error, input);
16269           return -99;
16270         }
16271     }
16272
16273   if (!is_set)
16274     {
16275       errmsg ("Transport protocol missing!");
16276       return -99;
16277     }
16278
16279   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16280   mp->protocol = (u8) protocol;
16281
16282   /* send it... */
16283   S (mp);
16284
16285   /* Wait for a reply... */
16286   W (ret);
16287   return ret;
16288 }
16289
16290 static int
16291 api_one_get_transport_protocol (vat_main_t * vam)
16292 {
16293   vl_api_one_get_transport_protocol_t *mp;
16294   int ret;
16295
16296   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16297
16298   /* send it... */
16299   S (mp);
16300
16301   /* Wait for a reply... */
16302   W (ret);
16303   return ret;
16304 }
16305
16306 static int
16307 api_one_map_register_set_ttl (vat_main_t * vam)
16308 {
16309   unformat_input_t *input = vam->input;
16310   vl_api_one_map_register_set_ttl_t *mp;
16311   u32 ttl = 0;
16312   u8 is_set = 0;
16313   int ret;
16314
16315   /* Parse args required to build the message */
16316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16317     {
16318       if (unformat (input, "%u", &ttl))
16319         is_set = 1;
16320       else
16321         {
16322           clib_warning ("parse error '%U'", format_unformat_error, input);
16323           return -99;
16324         }
16325     }
16326
16327   if (!is_set)
16328     {
16329       errmsg ("TTL value missing!");
16330       return -99;
16331     }
16332
16333   M (ONE_MAP_REGISTER_SET_TTL, mp);
16334   mp->ttl = clib_host_to_net_u32 (ttl);
16335
16336   /* send it... */
16337   S (mp);
16338
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_show_one_map_register_ttl (vat_main_t * vam)
16346 {
16347   vl_api_show_one_map_register_ttl_t *mp;
16348   int ret;
16349
16350   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Wait for a reply... */
16356   W (ret);
16357   return ret;
16358 }
16359
16360 /**
16361  * Add/del map request itr rlocs from ONE control plane and updates
16362  *
16363  * @param vam vpp API test context
16364  * @return return code
16365  */
16366 static int
16367 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16368 {
16369   unformat_input_t *input = vam->input;
16370   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16371   u8 *locator_set_name = 0;
16372   u8 locator_set_name_set = 0;
16373   u8 is_add = 1;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "del"))
16380         {
16381           is_add = 0;
16382         }
16383       else if (unformat (input, "%_%v%_", &locator_set_name))
16384         {
16385           locator_set_name_set = 1;
16386         }
16387       else
16388         {
16389           clib_warning ("parse error '%U'", format_unformat_error, input);
16390           return -99;
16391         }
16392     }
16393
16394   if (is_add && !locator_set_name_set)
16395     {
16396       errmsg ("itr-rloc is not set!");
16397       return -99;
16398     }
16399
16400   if (is_add && vec_len (locator_set_name) > 64)
16401     {
16402       errmsg ("itr-rloc locator-set name too long");
16403       vec_free (locator_set_name);
16404       return -99;
16405     }
16406
16407   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16408   mp->is_add = is_add;
16409   if (is_add)
16410     {
16411       clib_memcpy (mp->locator_set_name, locator_set_name,
16412                    vec_len (locator_set_name));
16413     }
16414   else
16415     {
16416       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16417     }
16418   vec_free (locator_set_name);
16419
16420   /* send it... */
16421   S (mp);
16422
16423   /* Wait for a reply... */
16424   W (ret);
16425   return ret;
16426 }
16427
16428 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16429
16430 static int
16431 api_one_locator_dump (vat_main_t * vam)
16432 {
16433   unformat_input_t *input = vam->input;
16434   vl_api_one_locator_dump_t *mp;
16435   vl_api_control_ping_t *mp_ping;
16436   u8 is_index_set = 0, is_name_set = 0;
16437   u8 *ls_name = 0;
16438   u32 ls_index = ~0;
16439   int ret;
16440
16441   /* Parse args required to build the message */
16442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16443     {
16444       if (unformat (input, "ls_name %_%v%_", &ls_name))
16445         {
16446           is_name_set = 1;
16447         }
16448       else if (unformat (input, "ls_index %d", &ls_index))
16449         {
16450           is_index_set = 1;
16451         }
16452       else
16453         {
16454           errmsg ("parse error '%U'", format_unformat_error, input);
16455           return -99;
16456         }
16457     }
16458
16459   if (!is_index_set && !is_name_set)
16460     {
16461       errmsg ("error: expected one of index or name!");
16462       return -99;
16463     }
16464
16465   if (is_index_set && is_name_set)
16466     {
16467       errmsg ("error: only one param expected!");
16468       return -99;
16469     }
16470
16471   if (vec_len (ls_name) > 62)
16472     {
16473       errmsg ("error: locator set name too long!");
16474       return -99;
16475     }
16476
16477   if (!vam->json_output)
16478     {
16479       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16480     }
16481
16482   M (ONE_LOCATOR_DUMP, mp);
16483   mp->is_index_set = is_index_set;
16484
16485   if (is_index_set)
16486     mp->ls_index = clib_host_to_net_u32 (ls_index);
16487   else
16488     {
16489       vec_add1 (ls_name, 0);
16490       strncpy ((char *) mp->ls_name, (char *) ls_name,
16491                sizeof (mp->ls_name) - 1);
16492     }
16493
16494   /* send it... */
16495   S (mp);
16496
16497   /* Use a control ping for synchronization */
16498   MPING (CONTROL_PING, mp_ping);
16499   S (mp_ping);
16500
16501   /* Wait for a reply... */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 #define api_lisp_locator_dump api_one_locator_dump
16507
16508 static int
16509 api_one_locator_set_dump (vat_main_t * vam)
16510 {
16511   vl_api_one_locator_set_dump_t *mp;
16512   vl_api_control_ping_t *mp_ping;
16513   unformat_input_t *input = vam->input;
16514   u8 filter = 0;
16515   int ret;
16516
16517   /* Parse args required to build the message */
16518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16519     {
16520       if (unformat (input, "local"))
16521         {
16522           filter = 1;
16523         }
16524       else if (unformat (input, "remote"))
16525         {
16526           filter = 2;
16527         }
16528       else
16529         {
16530           errmsg ("parse error '%U'", format_unformat_error, input);
16531           return -99;
16532         }
16533     }
16534
16535   if (!vam->json_output)
16536     {
16537       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16538     }
16539
16540   M (ONE_LOCATOR_SET_DUMP, mp);
16541
16542   mp->filter = filter;
16543
16544   /* send it... */
16545   S (mp);
16546
16547   /* Use a control ping for synchronization */
16548   MPING (CONTROL_PING, mp_ping);
16549   S (mp_ping);
16550
16551   /* Wait for a reply... */
16552   W (ret);
16553   return ret;
16554 }
16555
16556 #define api_lisp_locator_set_dump api_one_locator_set_dump
16557
16558 static int
16559 api_one_eid_table_map_dump (vat_main_t * vam)
16560 {
16561   u8 is_l2 = 0;
16562   u8 mode_set = 0;
16563   unformat_input_t *input = vam->input;
16564   vl_api_one_eid_table_map_dump_t *mp;
16565   vl_api_control_ping_t *mp_ping;
16566   int ret;
16567
16568   /* Parse args required to build the message */
16569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (input, "l2"))
16572         {
16573           is_l2 = 1;
16574           mode_set = 1;
16575         }
16576       else if (unformat (input, "l3"))
16577         {
16578           is_l2 = 0;
16579           mode_set = 1;
16580         }
16581       else
16582         {
16583           errmsg ("parse error '%U'", format_unformat_error, input);
16584           return -99;
16585         }
16586     }
16587
16588   if (!mode_set)
16589     {
16590       errmsg ("expected one of 'l2' or 'l3' parameter!");
16591       return -99;
16592     }
16593
16594   if (!vam->json_output)
16595     {
16596       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16597     }
16598
16599   M (ONE_EID_TABLE_MAP_DUMP, mp);
16600   mp->is_l2 = is_l2;
16601
16602   /* send it... */
16603   S (mp);
16604
16605   /* Use a control ping for synchronization */
16606   MPING (CONTROL_PING, mp_ping);
16607   S (mp_ping);
16608
16609   /* Wait for a reply... */
16610   W (ret);
16611   return ret;
16612 }
16613
16614 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16615
16616 static int
16617 api_one_eid_table_vni_dump (vat_main_t * vam)
16618 {
16619   vl_api_one_eid_table_vni_dump_t *mp;
16620   vl_api_control_ping_t *mp_ping;
16621   int ret;
16622
16623   if (!vam->json_output)
16624     {
16625       print (vam->ofp, "VNI");
16626     }
16627
16628   M (ONE_EID_TABLE_VNI_DUMP, mp);
16629
16630   /* send it... */
16631   S (mp);
16632
16633   /* Use a control ping for synchronization */
16634   MPING (CONTROL_PING, mp_ping);
16635   S (mp_ping);
16636
16637   /* Wait for a reply... */
16638   W (ret);
16639   return ret;
16640 }
16641
16642 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16643
16644 static int
16645 api_one_eid_table_dump (vat_main_t * vam)
16646 {
16647   unformat_input_t *i = vam->input;
16648   vl_api_one_eid_table_dump_t *mp;
16649   vl_api_control_ping_t *mp_ping;
16650   struct in_addr ip4;
16651   struct in6_addr ip6;
16652   u8 mac[6];
16653   u8 eid_type = ~0, eid_set = 0;
16654   u32 prefix_length = ~0, t, vni = 0;
16655   u8 filter = 0;
16656   int ret;
16657   lisp_nsh_api_t nsh;
16658
16659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16660     {
16661       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16662         {
16663           eid_set = 1;
16664           eid_type = 0;
16665           prefix_length = t;
16666         }
16667       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16668         {
16669           eid_set = 1;
16670           eid_type = 1;
16671           prefix_length = t;
16672         }
16673       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16674         {
16675           eid_set = 1;
16676           eid_type = 2;
16677         }
16678       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16679         {
16680           eid_set = 1;
16681           eid_type = 3;
16682         }
16683       else if (unformat (i, "vni %d", &t))
16684         {
16685           vni = t;
16686         }
16687       else if (unformat (i, "local"))
16688         {
16689           filter = 1;
16690         }
16691       else if (unformat (i, "remote"))
16692         {
16693           filter = 2;
16694         }
16695       else
16696         {
16697           errmsg ("parse error '%U'", format_unformat_error, i);
16698           return -99;
16699         }
16700     }
16701
16702   if (!vam->json_output)
16703     {
16704       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16705              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16706     }
16707
16708   M (ONE_EID_TABLE_DUMP, mp);
16709
16710   mp->filter = filter;
16711   if (eid_set)
16712     {
16713       mp->eid_set = 1;
16714       mp->vni = htonl (vni);
16715       mp->eid_type = eid_type;
16716       switch (eid_type)
16717         {
16718         case 0:
16719           mp->prefix_length = prefix_length;
16720           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16721           break;
16722         case 1:
16723           mp->prefix_length = prefix_length;
16724           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16725           break;
16726         case 2:
16727           clib_memcpy (mp->eid, mac, sizeof (mac));
16728           break;
16729         case 3:
16730           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16731           break;
16732         default:
16733           errmsg ("unknown EID type %d!", eid_type);
16734           return -99;
16735         }
16736     }
16737
16738   /* send it... */
16739   S (mp);
16740
16741   /* Use a control ping for synchronization */
16742   MPING (CONTROL_PING, mp_ping);
16743   S (mp_ping);
16744
16745   /* Wait for a reply... */
16746   W (ret);
16747   return ret;
16748 }
16749
16750 #define api_lisp_eid_table_dump api_one_eid_table_dump
16751
16752 static int
16753 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16754 {
16755   unformat_input_t *i = vam->input;
16756   vl_api_gpe_fwd_entries_get_t *mp;
16757   u8 vni_set = 0;
16758   u32 vni = ~0;
16759   int ret;
16760
16761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16762     {
16763       if (unformat (i, "vni %d", &vni))
16764         {
16765           vni_set = 1;
16766         }
16767       else
16768         {
16769           errmsg ("parse error '%U'", format_unformat_error, i);
16770           return -99;
16771         }
16772     }
16773
16774   if (!vni_set)
16775     {
16776       errmsg ("vni not set!");
16777       return -99;
16778     }
16779
16780   if (!vam->json_output)
16781     {
16782       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16783              "leid", "reid");
16784     }
16785
16786   M (GPE_FWD_ENTRIES_GET, mp);
16787   mp->vni = clib_host_to_net_u32 (vni);
16788
16789   /* send it... */
16790   S (mp);
16791
16792   /* Wait for a reply... */
16793   W (ret);
16794   return ret;
16795 }
16796
16797 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16798 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16799 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16800 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16801 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16802 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16803 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16804 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16805
16806 static int
16807 api_one_adjacencies_get (vat_main_t * vam)
16808 {
16809   unformat_input_t *i = vam->input;
16810   vl_api_one_adjacencies_get_t *mp;
16811   u8 vni_set = 0;
16812   u32 vni = ~0;
16813   int ret;
16814
16815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (i, "vni %d", &vni))
16818         {
16819           vni_set = 1;
16820         }
16821       else
16822         {
16823           errmsg ("parse error '%U'", format_unformat_error, i);
16824           return -99;
16825         }
16826     }
16827
16828   if (!vni_set)
16829     {
16830       errmsg ("vni not set!");
16831       return -99;
16832     }
16833
16834   if (!vam->json_output)
16835     {
16836       print (vam->ofp, "%s %40s", "leid", "reid");
16837     }
16838
16839   M (ONE_ADJACENCIES_GET, mp);
16840   mp->vni = clib_host_to_net_u32 (vni);
16841
16842   /* send it... */
16843   S (mp);
16844
16845   /* Wait for a reply... */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 #define api_lisp_adjacencies_get api_one_adjacencies_get
16851
16852 static int
16853 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16854 {
16855   unformat_input_t *i = vam->input;
16856   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16857   int ret;
16858   u8 ip_family_set = 0, is_ip4 = 1;
16859
16860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16861     {
16862       if (unformat (i, "ip4"))
16863         {
16864           ip_family_set = 1;
16865           is_ip4 = 1;
16866         }
16867       else if (unformat (i, "ip6"))
16868         {
16869           ip_family_set = 1;
16870           is_ip4 = 0;
16871         }
16872       else
16873         {
16874           errmsg ("parse error '%U'", format_unformat_error, i);
16875           return -99;
16876         }
16877     }
16878
16879   if (!ip_family_set)
16880     {
16881       errmsg ("ip family not set!");
16882       return -99;
16883     }
16884
16885   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16886   mp->is_ip4 = is_ip4;
16887
16888   /* send it... */
16889   S (mp);
16890
16891   /* Wait for a reply... */
16892   W (ret);
16893   return ret;
16894 }
16895
16896 static int
16897 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16898 {
16899   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16900   int ret;
16901
16902   if (!vam->json_output)
16903     {
16904       print (vam->ofp, "VNIs");
16905     }
16906
16907   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16908
16909   /* send it... */
16910   S (mp);
16911
16912   /* Wait for a reply... */
16913   W (ret);
16914   return ret;
16915 }
16916
16917 static int
16918 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16919 {
16920   unformat_input_t *i = vam->input;
16921   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16922   int ret = 0;
16923   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16924   struct in_addr ip4;
16925   struct in6_addr ip6;
16926   u32 table_id = 0, nh_sw_if_index = ~0;
16927
16928   clib_memset (&ip4, 0, sizeof (ip4));
16929   clib_memset (&ip6, 0, sizeof (ip6));
16930
16931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16932     {
16933       if (unformat (i, "del"))
16934         is_add = 0;
16935       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16936                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16937         {
16938           ip_set = 1;
16939           is_ip4 = 1;
16940         }
16941       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16942                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16943         {
16944           ip_set = 1;
16945           is_ip4 = 0;
16946         }
16947       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16948         {
16949           ip_set = 1;
16950           is_ip4 = 1;
16951           nh_sw_if_index = ~0;
16952         }
16953       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16954         {
16955           ip_set = 1;
16956           is_ip4 = 0;
16957           nh_sw_if_index = ~0;
16958         }
16959       else if (unformat (i, "table %d", &table_id))
16960         ;
16961       else
16962         {
16963           errmsg ("parse error '%U'", format_unformat_error, i);
16964           return -99;
16965         }
16966     }
16967
16968   if (!ip_set)
16969     {
16970       errmsg ("nh addr not set!");
16971       return -99;
16972     }
16973
16974   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16975   mp->is_add = is_add;
16976   mp->table_id = clib_host_to_net_u32 (table_id);
16977   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16978   mp->is_ip4 = is_ip4;
16979   if (is_ip4)
16980     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16981   else
16982     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16983
16984   /* send it... */
16985   S (mp);
16986
16987   /* Wait for a reply... */
16988   W (ret);
16989   return ret;
16990 }
16991
16992 static int
16993 api_one_map_server_dump (vat_main_t * vam)
16994 {
16995   vl_api_one_map_server_dump_t *mp;
16996   vl_api_control_ping_t *mp_ping;
16997   int ret;
16998
16999   if (!vam->json_output)
17000     {
17001       print (vam->ofp, "%=20s", "Map server");
17002     }
17003
17004   M (ONE_MAP_SERVER_DUMP, mp);
17005   /* send it... */
17006   S (mp);
17007
17008   /* Use a control ping for synchronization */
17009   MPING (CONTROL_PING, mp_ping);
17010   S (mp_ping);
17011
17012   /* Wait for a reply... */
17013   W (ret);
17014   return ret;
17015 }
17016
17017 #define api_lisp_map_server_dump api_one_map_server_dump
17018
17019 static int
17020 api_one_map_resolver_dump (vat_main_t * vam)
17021 {
17022   vl_api_one_map_resolver_dump_t *mp;
17023   vl_api_control_ping_t *mp_ping;
17024   int ret;
17025
17026   if (!vam->json_output)
17027     {
17028       print (vam->ofp, "%=20s", "Map resolver");
17029     }
17030
17031   M (ONE_MAP_RESOLVER_DUMP, mp);
17032   /* send it... */
17033   S (mp);
17034
17035   /* Use a control ping for synchronization */
17036   MPING (CONTROL_PING, mp_ping);
17037   S (mp_ping);
17038
17039   /* Wait for a reply... */
17040   W (ret);
17041   return ret;
17042 }
17043
17044 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17045
17046 static int
17047 api_one_stats_flush (vat_main_t * vam)
17048 {
17049   vl_api_one_stats_flush_t *mp;
17050   int ret = 0;
17051
17052   M (ONE_STATS_FLUSH, mp);
17053   S (mp);
17054   W (ret);
17055   return ret;
17056 }
17057
17058 static int
17059 api_one_stats_dump (vat_main_t * vam)
17060 {
17061   vl_api_one_stats_dump_t *mp;
17062   vl_api_control_ping_t *mp_ping;
17063   int ret;
17064
17065   M (ONE_STATS_DUMP, mp);
17066   /* send it... */
17067   S (mp);
17068
17069   /* Use a control ping for synchronization */
17070   MPING (CONTROL_PING, mp_ping);
17071   S (mp_ping);
17072
17073   /* Wait for a reply... */
17074   W (ret);
17075   return ret;
17076 }
17077
17078 static int
17079 api_show_one_status (vat_main_t * vam)
17080 {
17081   vl_api_show_one_status_t *mp;
17082   int ret;
17083
17084   if (!vam->json_output)
17085     {
17086       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17087     }
17088
17089   M (SHOW_ONE_STATUS, mp);
17090   /* send it... */
17091   S (mp);
17092   /* Wait for a reply... */
17093   W (ret);
17094   return ret;
17095 }
17096
17097 #define api_show_lisp_status api_show_one_status
17098
17099 static int
17100 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17101 {
17102   vl_api_gpe_fwd_entry_path_dump_t *mp;
17103   vl_api_control_ping_t *mp_ping;
17104   unformat_input_t *i = vam->input;
17105   u32 fwd_entry_index = ~0;
17106   int ret;
17107
17108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17109     {
17110       if (unformat (i, "index %d", &fwd_entry_index))
17111         ;
17112       else
17113         break;
17114     }
17115
17116   if (~0 == fwd_entry_index)
17117     {
17118       errmsg ("no index specified!");
17119       return -99;
17120     }
17121
17122   if (!vam->json_output)
17123     {
17124       print (vam->ofp, "first line");
17125     }
17126
17127   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17128
17129   /* send it... */
17130   S (mp);
17131   /* Use a control ping for synchronization */
17132   MPING (CONTROL_PING, mp_ping);
17133   S (mp_ping);
17134
17135   /* Wait for a reply... */
17136   W (ret);
17137   return ret;
17138 }
17139
17140 static int
17141 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17142 {
17143   vl_api_one_get_map_request_itr_rlocs_t *mp;
17144   int ret;
17145
17146   if (!vam->json_output)
17147     {
17148       print (vam->ofp, "%=20s", "itr-rlocs:");
17149     }
17150
17151   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17152   /* send it... */
17153   S (mp);
17154   /* Wait for a reply... */
17155   W (ret);
17156   return ret;
17157 }
17158
17159 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17160
17161 static int
17162 api_af_packet_create (vat_main_t * vam)
17163 {
17164   unformat_input_t *i = vam->input;
17165   vl_api_af_packet_create_t *mp;
17166   u8 *host_if_name = 0;
17167   u8 hw_addr[6];
17168   u8 random_hw_addr = 1;
17169   int ret;
17170
17171   clib_memset (hw_addr, 0, sizeof (hw_addr));
17172
17173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17174     {
17175       if (unformat (i, "name %s", &host_if_name))
17176         vec_add1 (host_if_name, 0);
17177       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17178         random_hw_addr = 0;
17179       else
17180         break;
17181     }
17182
17183   if (!vec_len (host_if_name))
17184     {
17185       errmsg ("host-interface name must be specified");
17186       return -99;
17187     }
17188
17189   if (vec_len (host_if_name) > 64)
17190     {
17191       errmsg ("host-interface name too long");
17192       return -99;
17193     }
17194
17195   M (AF_PACKET_CREATE, mp);
17196
17197   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17198   clib_memcpy (mp->hw_addr, hw_addr, 6);
17199   mp->use_random_hw_addr = random_hw_addr;
17200   vec_free (host_if_name);
17201
17202   S (mp);
17203
17204   /* *INDENT-OFF* */
17205   W2 (ret,
17206       ({
17207         if (ret == 0)
17208           fprintf (vam->ofp ? vam->ofp : stderr,
17209                    " new sw_if_index = %d\n", vam->sw_if_index);
17210       }));
17211   /* *INDENT-ON* */
17212   return ret;
17213 }
17214
17215 static int
17216 api_af_packet_delete (vat_main_t * vam)
17217 {
17218   unformat_input_t *i = vam->input;
17219   vl_api_af_packet_delete_t *mp;
17220   u8 *host_if_name = 0;
17221   int ret;
17222
17223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17224     {
17225       if (unformat (i, "name %s", &host_if_name))
17226         vec_add1 (host_if_name, 0);
17227       else
17228         break;
17229     }
17230
17231   if (!vec_len (host_if_name))
17232     {
17233       errmsg ("host-interface name must be specified");
17234       return -99;
17235     }
17236
17237   if (vec_len (host_if_name) > 64)
17238     {
17239       errmsg ("host-interface name too long");
17240       return -99;
17241     }
17242
17243   M (AF_PACKET_DELETE, mp);
17244
17245   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17246   vec_free (host_if_name);
17247
17248   S (mp);
17249   W (ret);
17250   return ret;
17251 }
17252
17253 static void vl_api_af_packet_details_t_handler
17254   (vl_api_af_packet_details_t * mp)
17255 {
17256   vat_main_t *vam = &vat_main;
17257
17258   print (vam->ofp, "%-16s %d",
17259          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17260 }
17261
17262 static void vl_api_af_packet_details_t_handler_json
17263   (vl_api_af_packet_details_t * mp)
17264 {
17265   vat_main_t *vam = &vat_main;
17266   vat_json_node_t *node = NULL;
17267
17268   if (VAT_JSON_ARRAY != vam->json_tree.type)
17269     {
17270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17271       vat_json_init_array (&vam->json_tree);
17272     }
17273   node = vat_json_array_add (&vam->json_tree);
17274
17275   vat_json_init_object (node);
17276   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17277   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17278 }
17279
17280 static int
17281 api_af_packet_dump (vat_main_t * vam)
17282 {
17283   vl_api_af_packet_dump_t *mp;
17284   vl_api_control_ping_t *mp_ping;
17285   int ret;
17286
17287   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17288   /* Get list of tap interfaces */
17289   M (AF_PACKET_DUMP, mp);
17290   S (mp);
17291
17292   /* Use a control ping for synchronization */
17293   MPING (CONTROL_PING, mp_ping);
17294   S (mp_ping);
17295
17296   W (ret);
17297   return ret;
17298 }
17299
17300 static int
17301 api_policer_add_del (vat_main_t * vam)
17302 {
17303   unformat_input_t *i = vam->input;
17304   vl_api_policer_add_del_t *mp;
17305   u8 is_add = 1;
17306   u8 *name = 0;
17307   u32 cir = 0;
17308   u32 eir = 0;
17309   u64 cb = 0;
17310   u64 eb = 0;
17311   u8 rate_type = 0;
17312   u8 round_type = 0;
17313   u8 type = 0;
17314   u8 color_aware = 0;
17315   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17316   int ret;
17317
17318   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17319   conform_action.dscp = 0;
17320   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17321   exceed_action.dscp = 0;
17322   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17323   violate_action.dscp = 0;
17324
17325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17326     {
17327       if (unformat (i, "del"))
17328         is_add = 0;
17329       else if (unformat (i, "name %s", &name))
17330         vec_add1 (name, 0);
17331       else if (unformat (i, "cir %u", &cir))
17332         ;
17333       else if (unformat (i, "eir %u", &eir))
17334         ;
17335       else if (unformat (i, "cb %u", &cb))
17336         ;
17337       else if (unformat (i, "eb %u", &eb))
17338         ;
17339       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17340                          &rate_type))
17341         ;
17342       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17343                          &round_type))
17344         ;
17345       else if (unformat (i, "type %U", unformat_policer_type, &type))
17346         ;
17347       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17348                          &conform_action))
17349         ;
17350       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17351                          &exceed_action))
17352         ;
17353       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17354                          &violate_action))
17355         ;
17356       else if (unformat (i, "color-aware"))
17357         color_aware = 1;
17358       else
17359         break;
17360     }
17361
17362   if (!vec_len (name))
17363     {
17364       errmsg ("policer name must be specified");
17365       return -99;
17366     }
17367
17368   if (vec_len (name) > 64)
17369     {
17370       errmsg ("policer name too long");
17371       return -99;
17372     }
17373
17374   M (POLICER_ADD_DEL, mp);
17375
17376   clib_memcpy (mp->name, name, vec_len (name));
17377   vec_free (name);
17378   mp->is_add = is_add;
17379   mp->cir = ntohl (cir);
17380   mp->eir = ntohl (eir);
17381   mp->cb = clib_net_to_host_u64 (cb);
17382   mp->eb = clib_net_to_host_u64 (eb);
17383   mp->rate_type = rate_type;
17384   mp->round_type = round_type;
17385   mp->type = type;
17386   mp->conform_action.type = conform_action.action_type;
17387   mp->conform_action.dscp = conform_action.dscp;
17388   mp->exceed_action.type = exceed_action.action_type;
17389   mp->exceed_action.dscp = exceed_action.dscp;
17390   mp->violate_action.type = violate_action.action_type;
17391   mp->violate_action.dscp = violate_action.dscp;
17392   mp->color_aware = color_aware;
17393
17394   S (mp);
17395   W (ret);
17396   return ret;
17397 }
17398
17399 static int
17400 api_policer_dump (vat_main_t * vam)
17401 {
17402   unformat_input_t *i = vam->input;
17403   vl_api_policer_dump_t *mp;
17404   vl_api_control_ping_t *mp_ping;
17405   u8 *match_name = 0;
17406   u8 match_name_valid = 0;
17407   int ret;
17408
17409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17410     {
17411       if (unformat (i, "name %s", &match_name))
17412         {
17413           vec_add1 (match_name, 0);
17414           match_name_valid = 1;
17415         }
17416       else
17417         break;
17418     }
17419
17420   M (POLICER_DUMP, mp);
17421   mp->match_name_valid = match_name_valid;
17422   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17423   vec_free (match_name);
17424   /* send it... */
17425   S (mp);
17426
17427   /* Use a control ping for synchronization */
17428   MPING (CONTROL_PING, mp_ping);
17429   S (mp_ping);
17430
17431   /* Wait for a reply... */
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_policer_classify_set_interface (vat_main_t * vam)
17438 {
17439   unformat_input_t *i = vam->input;
17440   vl_api_policer_classify_set_interface_t *mp;
17441   u32 sw_if_index;
17442   int sw_if_index_set;
17443   u32 ip4_table_index = ~0;
17444   u32 ip6_table_index = ~0;
17445   u32 l2_table_index = ~0;
17446   u8 is_add = 1;
17447   int ret;
17448
17449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17450     {
17451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17452         sw_if_index_set = 1;
17453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17454         sw_if_index_set = 1;
17455       else if (unformat (i, "del"))
17456         is_add = 0;
17457       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17458         ;
17459       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17460         ;
17461       else if (unformat (i, "l2-table %d", &l2_table_index))
17462         ;
17463       else
17464         {
17465           clib_warning ("parse error '%U'", format_unformat_error, i);
17466           return -99;
17467         }
17468     }
17469
17470   if (sw_if_index_set == 0)
17471     {
17472       errmsg ("missing interface name or sw_if_index");
17473       return -99;
17474     }
17475
17476   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17477
17478   mp->sw_if_index = ntohl (sw_if_index);
17479   mp->ip4_table_index = ntohl (ip4_table_index);
17480   mp->ip6_table_index = ntohl (ip6_table_index);
17481   mp->l2_table_index = ntohl (l2_table_index);
17482   mp->is_add = is_add;
17483
17484   S (mp);
17485   W (ret);
17486   return ret;
17487 }
17488
17489 static int
17490 api_policer_classify_dump (vat_main_t * vam)
17491 {
17492   unformat_input_t *i = vam->input;
17493   vl_api_policer_classify_dump_t *mp;
17494   vl_api_control_ping_t *mp_ping;
17495   u8 type = POLICER_CLASSIFY_N_TABLES;
17496   int ret;
17497
17498   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17499     ;
17500   else
17501     {
17502       errmsg ("classify table type must be specified");
17503       return -99;
17504     }
17505
17506   if (!vam->json_output)
17507     {
17508       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17509     }
17510
17511   M (POLICER_CLASSIFY_DUMP, mp);
17512   mp->type = type;
17513   /* send it... */
17514   S (mp);
17515
17516   /* Use a control ping for synchronization */
17517   MPING (CONTROL_PING, mp_ping);
17518   S (mp_ping);
17519
17520   /* Wait for a reply... */
17521   W (ret);
17522   return ret;
17523 }
17524
17525 static u8 *
17526 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17527 {
17528   vl_api_fib_path_nh_proto_t proto =
17529     va_arg (*args, vl_api_fib_path_nh_proto_t);
17530
17531   switch (proto)
17532     {
17533     case FIB_API_PATH_NH_PROTO_IP4:
17534       s = format (s, "ip4");
17535       break;
17536     case FIB_API_PATH_NH_PROTO_IP6:
17537       s = format (s, "ip6");
17538       break;
17539     case FIB_API_PATH_NH_PROTO_MPLS:
17540       s = format (s, "mpls");
17541       break;
17542     case FIB_API_PATH_NH_PROTO_BIER:
17543       s = format (s, "bier");
17544       break;
17545     case FIB_API_PATH_NH_PROTO_ETHERNET:
17546       s = format (s, "ethernet");
17547       break;
17548     }
17549
17550   return (s);
17551 }
17552
17553 static u8 *
17554 format_vl_api_ip_address_union (u8 * s, va_list * args)
17555 {
17556   vl_api_address_family_t af = va_arg (*args, int);
17557   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17558
17559   switch (af)
17560     {
17561     case ADDRESS_IP4:
17562       s = format (s, "%U", format_ip4_address, u->ip4);
17563       break;
17564     case ADDRESS_IP6:
17565       s = format (s, "%U", format_ip6_address, u->ip6);
17566       break;
17567     }
17568   return (s);
17569 }
17570
17571 static u8 *
17572 format_vl_api_fib_path_type (u8 * s, va_list * args)
17573 {
17574   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17575
17576   switch (t)
17577     {
17578     case FIB_API_PATH_TYPE_NORMAL:
17579       s = format (s, "normal");
17580       break;
17581     case FIB_API_PATH_TYPE_LOCAL:
17582       s = format (s, "local");
17583       break;
17584     case FIB_API_PATH_TYPE_DROP:
17585       s = format (s, "drop");
17586       break;
17587     case FIB_API_PATH_TYPE_UDP_ENCAP:
17588       s = format (s, "udp-encap");
17589       break;
17590     case FIB_API_PATH_TYPE_BIER_IMP:
17591       s = format (s, "bier-imp");
17592       break;
17593     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17594       s = format (s, "unreach");
17595       break;
17596     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17597       s = format (s, "prohibit");
17598       break;
17599     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17600       s = format (s, "src-lookup");
17601       break;
17602     case FIB_API_PATH_TYPE_DVR:
17603       s = format (s, "dvr");
17604       break;
17605     case FIB_API_PATH_TYPE_INTERFACE_RX:
17606       s = format (s, "interface-rx");
17607       break;
17608     case FIB_API_PATH_TYPE_CLASSIFY:
17609       s = format (s, "classify");
17610       break;
17611     }
17612
17613   return (s);
17614 }
17615
17616 static void
17617 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17618 {
17619   print (vam->ofp,
17620          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17621          ntohl (fp->weight), ntohl (fp->sw_if_index),
17622          format_vl_api_fib_path_type, fp->type,
17623          format_fib_api_path_nh_proto, fp->proto,
17624          format_vl_api_ip_address_union, &fp->nh.address);
17625 }
17626
17627 static void
17628 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17629                                  vl_api_fib_path_t * fp)
17630 {
17631   struct in_addr ip4;
17632   struct in6_addr ip6;
17633
17634   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17635   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17636   vat_json_object_add_uint (node, "type", fp->type);
17637   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17638   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17639     {
17640       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17641       vat_json_object_add_ip4 (node, "next_hop", ip4);
17642     }
17643   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17644     {
17645       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17646       vat_json_object_add_ip6 (node, "next_hop", ip6);
17647     }
17648 }
17649
17650 static void
17651 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17652 {
17653   vat_main_t *vam = &vat_main;
17654   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17655   vl_api_fib_path_t *fp;
17656   i32 i;
17657
17658   print (vam->ofp, "sw_if_index %d via:",
17659          ntohl (mp->mt_tunnel.mt_sw_if_index));
17660   fp = mp->mt_tunnel.mt_paths;
17661   for (i = 0; i < count; i++)
17662     {
17663       vl_api_fib_path_print (vam, fp);
17664       fp++;
17665     }
17666
17667   print (vam->ofp, "");
17668 }
17669
17670 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17671 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17672
17673 static void
17674 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17675 {
17676   vat_main_t *vam = &vat_main;
17677   vat_json_node_t *node = NULL;
17678   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17679   vl_api_fib_path_t *fp;
17680   i32 i;
17681
17682   if (VAT_JSON_ARRAY != vam->json_tree.type)
17683     {
17684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17685       vat_json_init_array (&vam->json_tree);
17686     }
17687   node = vat_json_array_add (&vam->json_tree);
17688
17689   vat_json_init_object (node);
17690   vat_json_object_add_uint (node, "sw_if_index",
17691                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17692
17693   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17694
17695   fp = mp->mt_tunnel.mt_paths;
17696   for (i = 0; i < count; i++)
17697     {
17698       vl_api_mpls_fib_path_json_print (node, fp);
17699       fp++;
17700     }
17701 }
17702
17703 static int
17704 api_mpls_tunnel_dump (vat_main_t * vam)
17705 {
17706   vl_api_mpls_tunnel_dump_t *mp;
17707   vl_api_control_ping_t *mp_ping;
17708   int ret;
17709
17710   M (MPLS_TUNNEL_DUMP, mp);
17711
17712   S (mp);
17713
17714   /* Use a control ping for synchronization */
17715   MPING (CONTROL_PING, mp_ping);
17716   S (mp_ping);
17717
17718   W (ret);
17719   return ret;
17720 }
17721
17722 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17723 #define vl_api_mpls_table_details_t_print vl_noop_handler
17724
17725
17726 static void
17727 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17728 {
17729   vat_main_t *vam = &vat_main;
17730
17731   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17732 }
17733
17734 static void vl_api_mpls_table_details_t_handler_json
17735   (vl_api_mpls_table_details_t * mp)
17736 {
17737   vat_main_t *vam = &vat_main;
17738   vat_json_node_t *node = NULL;
17739
17740   if (VAT_JSON_ARRAY != vam->json_tree.type)
17741     {
17742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17743       vat_json_init_array (&vam->json_tree);
17744     }
17745   node = vat_json_array_add (&vam->json_tree);
17746
17747   vat_json_init_object (node);
17748   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17749 }
17750
17751 static int
17752 api_mpls_table_dump (vat_main_t * vam)
17753 {
17754   vl_api_mpls_table_dump_t *mp;
17755   vl_api_control_ping_t *mp_ping;
17756   int ret;
17757
17758   M (MPLS_TABLE_DUMP, mp);
17759   S (mp);
17760
17761   /* Use a control ping for synchronization */
17762   MPING (CONTROL_PING, mp_ping);
17763   S (mp_ping);
17764
17765   W (ret);
17766   return ret;
17767 }
17768
17769 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17770 #define vl_api_mpls_route_details_t_print vl_noop_handler
17771
17772 static void
17773 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17774 {
17775   vat_main_t *vam = &vat_main;
17776   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17777   vl_api_fib_path_t *fp;
17778   int i;
17779
17780   print (vam->ofp,
17781          "table-id %d, label %u, ess_bit %u",
17782          ntohl (mp->mr_route.mr_table_id),
17783          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17784   fp = mp->mr_route.mr_paths;
17785   for (i = 0; i < count; i++)
17786     {
17787       vl_api_fib_path_print (vam, fp);
17788       fp++;
17789     }
17790 }
17791
17792 static void vl_api_mpls_route_details_t_handler_json
17793   (vl_api_mpls_route_details_t * mp)
17794 {
17795   vat_main_t *vam = &vat_main;
17796   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17797   vat_json_node_t *node = NULL;
17798   vl_api_fib_path_t *fp;
17799   int i;
17800
17801   if (VAT_JSON_ARRAY != vam->json_tree.type)
17802     {
17803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17804       vat_json_init_array (&vam->json_tree);
17805     }
17806   node = vat_json_array_add (&vam->json_tree);
17807
17808   vat_json_init_object (node);
17809   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17810   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17811   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17812   vat_json_object_add_uint (node, "path_count", count);
17813   fp = mp->mr_route.mr_paths;
17814   for (i = 0; i < count; i++)
17815     {
17816       vl_api_mpls_fib_path_json_print (node, fp);
17817       fp++;
17818     }
17819 }
17820
17821 static int
17822 api_mpls_route_dump (vat_main_t * vam)
17823 {
17824   unformat_input_t *input = vam->input;
17825   vl_api_mpls_route_dump_t *mp;
17826   vl_api_control_ping_t *mp_ping;
17827   u32 table_id;
17828   int ret;
17829
17830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17831     {
17832       if (unformat (input, "table_id %d", &table_id))
17833         ;
17834       else
17835         break;
17836     }
17837   if (table_id == ~0)
17838     {
17839       errmsg ("missing table id");
17840       return -99;
17841     }
17842
17843   M (MPLS_ROUTE_DUMP, mp);
17844
17845   mp->table.mt_table_id = ntohl (table_id);
17846   S (mp);
17847
17848   /* Use a control ping for synchronization */
17849   MPING (CONTROL_PING, mp_ping);
17850   S (mp_ping);
17851
17852   W (ret);
17853   return ret;
17854 }
17855
17856 #define vl_api_ip_table_details_t_endian vl_noop_handler
17857 #define vl_api_ip_table_details_t_print vl_noop_handler
17858
17859 static void
17860 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17861 {
17862   vat_main_t *vam = &vat_main;
17863
17864   print (vam->ofp,
17865          "%s; table-id %d, prefix %U/%d",
17866          mp->table.name, ntohl (mp->table.table_id));
17867 }
17868
17869
17870 static void vl_api_ip_table_details_t_handler_json
17871   (vl_api_ip_table_details_t * mp)
17872 {
17873   vat_main_t *vam = &vat_main;
17874   vat_json_node_t *node = NULL;
17875
17876   if (VAT_JSON_ARRAY != vam->json_tree.type)
17877     {
17878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17879       vat_json_init_array (&vam->json_tree);
17880     }
17881   node = vat_json_array_add (&vam->json_tree);
17882
17883   vat_json_init_object (node);
17884   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17885 }
17886
17887 static int
17888 api_ip_table_dump (vat_main_t * vam)
17889 {
17890   vl_api_ip_table_dump_t *mp;
17891   vl_api_control_ping_t *mp_ping;
17892   int ret;
17893
17894   M (IP_TABLE_DUMP, mp);
17895   S (mp);
17896
17897   /* Use a control ping for synchronization */
17898   MPING (CONTROL_PING, mp_ping);
17899   S (mp_ping);
17900
17901   W (ret);
17902   return ret;
17903 }
17904
17905 static int
17906 api_ip_mtable_dump (vat_main_t * vam)
17907 {
17908   vl_api_ip_mtable_dump_t *mp;
17909   vl_api_control_ping_t *mp_ping;
17910   int ret;
17911
17912   M (IP_MTABLE_DUMP, mp);
17913   S (mp);
17914
17915   /* Use a control ping for synchronization */
17916   MPING (CONTROL_PING, mp_ping);
17917   S (mp_ping);
17918
17919   W (ret);
17920   return ret;
17921 }
17922
17923 static int
17924 api_ip_mroute_dump (vat_main_t * vam)
17925 {
17926   unformat_input_t *input = vam->input;
17927   vl_api_control_ping_t *mp_ping;
17928   vl_api_ip_mroute_dump_t *mp;
17929   int ret, is_ip6;
17930   u32 table_id;
17931
17932   is_ip6 = 0;
17933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17934     {
17935       if (unformat (input, "table_id %d", &table_id))
17936         ;
17937       else if (unformat (input, "ip6"))
17938         is_ip6 = 1;
17939       else if (unformat (input, "ip4"))
17940         is_ip6 = 0;
17941       else
17942         break;
17943     }
17944   if (table_id == ~0)
17945     {
17946       errmsg ("missing table id");
17947       return -99;
17948     }
17949
17950   M (IP_MROUTE_DUMP, mp);
17951   mp->table.table_id = table_id;
17952   mp->table.is_ip6 = is_ip6;
17953   S (mp);
17954
17955   /* Use a control ping for synchronization */
17956   MPING (CONTROL_PING, mp_ping);
17957   S (mp_ping);
17958
17959   W (ret);
17960   return ret;
17961 }
17962
17963 #define vl_api_ip_route_details_t_endian vl_noop_handler
17964 #define vl_api_ip_route_details_t_print vl_noop_handler
17965
17966 static void
17967 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17968 {
17969   vat_main_t *vam = &vat_main;
17970   u8 count = mp->route.n_paths;
17971   vl_api_fib_path_t *fp;
17972   int i;
17973
17974   print (vam->ofp,
17975          "table-id %d, prefix %U/%d",
17976          ntohl (mp->route.table_id),
17977          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17978   for (i = 0; i < count; i++)
17979     {
17980       fp = &mp->route.paths[i];
17981
17982       vl_api_fib_path_print (vam, fp);
17983       fp++;
17984     }
17985 }
17986
17987 static void vl_api_ip_route_details_t_handler_json
17988   (vl_api_ip_route_details_t * mp)
17989 {
17990   vat_main_t *vam = &vat_main;
17991   u8 count = mp->route.n_paths;
17992   vat_json_node_t *node = NULL;
17993   struct in_addr ip4;
17994   struct in6_addr ip6;
17995   vl_api_fib_path_t *fp;
17996   int i;
17997
17998   if (VAT_JSON_ARRAY != vam->json_tree.type)
17999     {
18000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18001       vat_json_init_array (&vam->json_tree);
18002     }
18003   node = vat_json_array_add (&vam->json_tree);
18004
18005   vat_json_init_object (node);
18006   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18007   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18008     {
18009       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18010       vat_json_object_add_ip6 (node, "prefix", ip6);
18011     }
18012   else
18013     {
18014       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18015       vat_json_object_add_ip4 (node, "prefix", ip4);
18016     }
18017   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18018   vat_json_object_add_uint (node, "path_count", count);
18019   for (i = 0; i < count; i++)
18020     {
18021       fp = &mp->route.paths[i];
18022       vl_api_mpls_fib_path_json_print (node, fp);
18023     }
18024 }
18025
18026 static int
18027 api_ip_route_dump (vat_main_t * vam)
18028 {
18029   unformat_input_t *input = vam->input;
18030   vl_api_ip_route_dump_t *mp;
18031   vl_api_control_ping_t *mp_ping;
18032   u32 table_id;
18033   u8 is_ip6;
18034   int ret;
18035
18036   is_ip6 = 0;
18037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18038     {
18039       if (unformat (input, "table_id %d", &table_id))
18040         ;
18041       else if (unformat (input, "ip6"))
18042         is_ip6 = 1;
18043       else if (unformat (input, "ip4"))
18044         is_ip6 = 0;
18045       else
18046         break;
18047     }
18048   if (table_id == ~0)
18049     {
18050       errmsg ("missing table id");
18051       return -99;
18052     }
18053
18054   M (IP_ROUTE_DUMP, mp);
18055
18056   mp->table.table_id = table_id;
18057   mp->table.is_ip6 = is_ip6;
18058
18059   S (mp);
18060
18061   /* Use a control ping for synchronization */
18062   MPING (CONTROL_PING, mp_ping);
18063   S (mp_ping);
18064
18065   W (ret);
18066   return ret;
18067 }
18068
18069 int
18070 api_classify_table_ids (vat_main_t * vam)
18071 {
18072   vl_api_classify_table_ids_t *mp;
18073   int ret;
18074
18075   /* Construct the API message */
18076   M (CLASSIFY_TABLE_IDS, mp);
18077   mp->context = 0;
18078
18079   S (mp);
18080   W (ret);
18081   return ret;
18082 }
18083
18084 int
18085 api_classify_table_by_interface (vat_main_t * vam)
18086 {
18087   unformat_input_t *input = vam->input;
18088   vl_api_classify_table_by_interface_t *mp;
18089
18090   u32 sw_if_index = ~0;
18091   int ret;
18092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18093     {
18094       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18095         ;
18096       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18097         ;
18098       else
18099         break;
18100     }
18101   if (sw_if_index == ~0)
18102     {
18103       errmsg ("missing interface name or sw_if_index");
18104       return -99;
18105     }
18106
18107   /* Construct the API message */
18108   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18109   mp->context = 0;
18110   mp->sw_if_index = ntohl (sw_if_index);
18111
18112   S (mp);
18113   W (ret);
18114   return ret;
18115 }
18116
18117 int
18118 api_classify_table_info (vat_main_t * vam)
18119 {
18120   unformat_input_t *input = vam->input;
18121   vl_api_classify_table_info_t *mp;
18122
18123   u32 table_id = ~0;
18124   int ret;
18125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18126     {
18127       if (unformat (input, "table_id %d", &table_id))
18128         ;
18129       else
18130         break;
18131     }
18132   if (table_id == ~0)
18133     {
18134       errmsg ("missing table id");
18135       return -99;
18136     }
18137
18138   /* Construct the API message */
18139   M (CLASSIFY_TABLE_INFO, mp);
18140   mp->context = 0;
18141   mp->table_id = ntohl (table_id);
18142
18143   S (mp);
18144   W (ret);
18145   return ret;
18146 }
18147
18148 int
18149 api_classify_session_dump (vat_main_t * vam)
18150 {
18151   unformat_input_t *input = vam->input;
18152   vl_api_classify_session_dump_t *mp;
18153   vl_api_control_ping_t *mp_ping;
18154
18155   u32 table_id = ~0;
18156   int ret;
18157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18158     {
18159       if (unformat (input, "table_id %d", &table_id))
18160         ;
18161       else
18162         break;
18163     }
18164   if (table_id == ~0)
18165     {
18166       errmsg ("missing table id");
18167       return -99;
18168     }
18169
18170   /* Construct the API message */
18171   M (CLASSIFY_SESSION_DUMP, mp);
18172   mp->context = 0;
18173   mp->table_id = ntohl (table_id);
18174   S (mp);
18175
18176   /* Use a control ping for synchronization */
18177   MPING (CONTROL_PING, mp_ping);
18178   S (mp_ping);
18179
18180   W (ret);
18181   return ret;
18182 }
18183
18184 static void
18185 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18186 {
18187   vat_main_t *vam = &vat_main;
18188
18189   print (vam->ofp, "collector_address %U, collector_port %d, "
18190          "src_address %U, vrf_id %d, path_mtu %u, "
18191          "template_interval %u, udp_checksum %d",
18192          format_ip4_address, mp->collector_address,
18193          ntohs (mp->collector_port),
18194          format_ip4_address, mp->src_address,
18195          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18196          ntohl (mp->template_interval), mp->udp_checksum);
18197
18198   vam->retval = 0;
18199   vam->result_ready = 1;
18200 }
18201
18202 static void
18203   vl_api_ipfix_exporter_details_t_handler_json
18204   (vl_api_ipfix_exporter_details_t * mp)
18205 {
18206   vat_main_t *vam = &vat_main;
18207   vat_json_node_t node;
18208   struct in_addr collector_address;
18209   struct in_addr src_address;
18210
18211   vat_json_init_object (&node);
18212   clib_memcpy (&collector_address, &mp->collector_address,
18213                sizeof (collector_address));
18214   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18215   vat_json_object_add_uint (&node, "collector_port",
18216                             ntohs (mp->collector_port));
18217   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18218   vat_json_object_add_ip4 (&node, "src_address", src_address);
18219   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18220   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18221   vat_json_object_add_uint (&node, "template_interval",
18222                             ntohl (mp->template_interval));
18223   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18224
18225   vat_json_print (vam->ofp, &node);
18226   vat_json_free (&node);
18227   vam->retval = 0;
18228   vam->result_ready = 1;
18229 }
18230
18231 int
18232 api_ipfix_exporter_dump (vat_main_t * vam)
18233 {
18234   vl_api_ipfix_exporter_dump_t *mp;
18235   int ret;
18236
18237   /* Construct the API message */
18238   M (IPFIX_EXPORTER_DUMP, mp);
18239   mp->context = 0;
18240
18241   S (mp);
18242   W (ret);
18243   return ret;
18244 }
18245
18246 static int
18247 api_ipfix_classify_stream_dump (vat_main_t * vam)
18248 {
18249   vl_api_ipfix_classify_stream_dump_t *mp;
18250   int ret;
18251
18252   /* Construct the API message */
18253   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18254   mp->context = 0;
18255
18256   S (mp);
18257   W (ret);
18258   return ret;
18259   /* NOTREACHED */
18260   return 0;
18261 }
18262
18263 static void
18264   vl_api_ipfix_classify_stream_details_t_handler
18265   (vl_api_ipfix_classify_stream_details_t * mp)
18266 {
18267   vat_main_t *vam = &vat_main;
18268   print (vam->ofp, "domain_id %d, src_port %d",
18269          ntohl (mp->domain_id), ntohs (mp->src_port));
18270   vam->retval = 0;
18271   vam->result_ready = 1;
18272 }
18273
18274 static void
18275   vl_api_ipfix_classify_stream_details_t_handler_json
18276   (vl_api_ipfix_classify_stream_details_t * mp)
18277 {
18278   vat_main_t *vam = &vat_main;
18279   vat_json_node_t node;
18280
18281   vat_json_init_object (&node);
18282   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18283   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18284
18285   vat_json_print (vam->ofp, &node);
18286   vat_json_free (&node);
18287   vam->retval = 0;
18288   vam->result_ready = 1;
18289 }
18290
18291 static int
18292 api_ipfix_classify_table_dump (vat_main_t * vam)
18293 {
18294   vl_api_ipfix_classify_table_dump_t *mp;
18295   vl_api_control_ping_t *mp_ping;
18296   int ret;
18297
18298   if (!vam->json_output)
18299     {
18300       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18301              "transport_protocol");
18302     }
18303
18304   /* Construct the API message */
18305   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18306
18307   /* send it... */
18308   S (mp);
18309
18310   /* Use a control ping for synchronization */
18311   MPING (CONTROL_PING, mp_ping);
18312   S (mp_ping);
18313
18314   W (ret);
18315   return ret;
18316 }
18317
18318 static void
18319   vl_api_ipfix_classify_table_details_t_handler
18320   (vl_api_ipfix_classify_table_details_t * mp)
18321 {
18322   vat_main_t *vam = &vat_main;
18323   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18324          mp->transport_protocol);
18325 }
18326
18327 static void
18328   vl_api_ipfix_classify_table_details_t_handler_json
18329   (vl_api_ipfix_classify_table_details_t * mp)
18330 {
18331   vat_json_node_t *node = NULL;
18332   vat_main_t *vam = &vat_main;
18333
18334   if (VAT_JSON_ARRAY != vam->json_tree.type)
18335     {
18336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18337       vat_json_init_array (&vam->json_tree);
18338     }
18339
18340   node = vat_json_array_add (&vam->json_tree);
18341   vat_json_init_object (node);
18342
18343   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18344   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18345   vat_json_object_add_uint (node, "transport_protocol",
18346                             mp->transport_protocol);
18347 }
18348
18349 static int
18350 api_sw_interface_span_enable_disable (vat_main_t * vam)
18351 {
18352   unformat_input_t *i = vam->input;
18353   vl_api_sw_interface_span_enable_disable_t *mp;
18354   u32 src_sw_if_index = ~0;
18355   u32 dst_sw_if_index = ~0;
18356   u8 state = 3;
18357   int ret;
18358   u8 is_l2 = 0;
18359
18360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18361     {
18362       if (unformat
18363           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18364         ;
18365       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18366         ;
18367       else
18368         if (unformat
18369             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18370         ;
18371       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18372         ;
18373       else if (unformat (i, "disable"))
18374         state = 0;
18375       else if (unformat (i, "rx"))
18376         state = 1;
18377       else if (unformat (i, "tx"))
18378         state = 2;
18379       else if (unformat (i, "both"))
18380         state = 3;
18381       else if (unformat (i, "l2"))
18382         is_l2 = 1;
18383       else
18384         break;
18385     }
18386
18387   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18388
18389   mp->sw_if_index_from = htonl (src_sw_if_index);
18390   mp->sw_if_index_to = htonl (dst_sw_if_index);
18391   mp->state = state;
18392   mp->is_l2 = is_l2;
18393
18394   S (mp);
18395   W (ret);
18396   return ret;
18397 }
18398
18399 static void
18400 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18401                                             * mp)
18402 {
18403   vat_main_t *vam = &vat_main;
18404   u8 *sw_if_from_name = 0;
18405   u8 *sw_if_to_name = 0;
18406   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18407   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18408   char *states[] = { "none", "rx", "tx", "both" };
18409   hash_pair_t *p;
18410
18411   /* *INDENT-OFF* */
18412   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18413   ({
18414     if ((u32) p->value[0] == sw_if_index_from)
18415       {
18416         sw_if_from_name = (u8 *)(p->key);
18417         if (sw_if_to_name)
18418           break;
18419       }
18420     if ((u32) p->value[0] == sw_if_index_to)
18421       {
18422         sw_if_to_name = (u8 *)(p->key);
18423         if (sw_if_from_name)
18424           break;
18425       }
18426   }));
18427   /* *INDENT-ON* */
18428   print (vam->ofp, "%20s => %20s (%s) %s",
18429          sw_if_from_name, sw_if_to_name, states[mp->state],
18430          mp->is_l2 ? "l2" : "device");
18431 }
18432
18433 static void
18434   vl_api_sw_interface_span_details_t_handler_json
18435   (vl_api_sw_interface_span_details_t * mp)
18436 {
18437   vat_main_t *vam = &vat_main;
18438   vat_json_node_t *node = NULL;
18439   u8 *sw_if_from_name = 0;
18440   u8 *sw_if_to_name = 0;
18441   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18442   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18443   hash_pair_t *p;
18444
18445   /* *INDENT-OFF* */
18446   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18447   ({
18448     if ((u32) p->value[0] == sw_if_index_from)
18449       {
18450         sw_if_from_name = (u8 *)(p->key);
18451         if (sw_if_to_name)
18452           break;
18453       }
18454     if ((u32) p->value[0] == sw_if_index_to)
18455       {
18456         sw_if_to_name = (u8 *)(p->key);
18457         if (sw_if_from_name)
18458           break;
18459       }
18460   }));
18461   /* *INDENT-ON* */
18462
18463   if (VAT_JSON_ARRAY != vam->json_tree.type)
18464     {
18465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18466       vat_json_init_array (&vam->json_tree);
18467     }
18468   node = vat_json_array_add (&vam->json_tree);
18469
18470   vat_json_init_object (node);
18471   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18472   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18473   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18474   if (0 != sw_if_to_name)
18475     {
18476       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18477     }
18478   vat_json_object_add_uint (node, "state", mp->state);
18479   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18480 }
18481
18482 static int
18483 api_sw_interface_span_dump (vat_main_t * vam)
18484 {
18485   unformat_input_t *input = vam->input;
18486   vl_api_sw_interface_span_dump_t *mp;
18487   vl_api_control_ping_t *mp_ping;
18488   u8 is_l2 = 0;
18489   int ret;
18490
18491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18492     {
18493       if (unformat (input, "l2"))
18494         is_l2 = 1;
18495       else
18496         break;
18497     }
18498
18499   M (SW_INTERFACE_SPAN_DUMP, mp);
18500   mp->is_l2 = is_l2;
18501   S (mp);
18502
18503   /* Use a control ping for synchronization */
18504   MPING (CONTROL_PING, mp_ping);
18505   S (mp_ping);
18506
18507   W (ret);
18508   return ret;
18509 }
18510
18511 int
18512 api_pg_create_interface (vat_main_t * vam)
18513 {
18514   unformat_input_t *input = vam->input;
18515   vl_api_pg_create_interface_t *mp;
18516
18517   u32 if_id = ~0, gso_size = 0;
18518   u8 gso_enabled = 0;
18519   int ret;
18520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18521     {
18522       if (unformat (input, "if_id %d", &if_id))
18523         ;
18524       else if (unformat (input, "gso-enabled"))
18525         {
18526           gso_enabled = 1;
18527           if (unformat (input, "gso-size %u", &gso_size))
18528             ;
18529           else
18530             {
18531               errmsg ("missing gso-size");
18532               return -99;
18533             }
18534         }
18535       else
18536         break;
18537     }
18538   if (if_id == ~0)
18539     {
18540       errmsg ("missing pg interface index");
18541       return -99;
18542     }
18543
18544   /* Construct the API message */
18545   M (PG_CREATE_INTERFACE, mp);
18546   mp->context = 0;
18547   mp->interface_id = ntohl (if_id);
18548   mp->gso_enabled = gso_enabled;
18549
18550   S (mp);
18551   W (ret);
18552   return ret;
18553 }
18554
18555 int
18556 api_pg_capture (vat_main_t * vam)
18557 {
18558   unformat_input_t *input = vam->input;
18559   vl_api_pg_capture_t *mp;
18560
18561   u32 if_id = ~0;
18562   u8 enable = 1;
18563   u32 count = 1;
18564   u8 pcap_file_set = 0;
18565   u8 *pcap_file = 0;
18566   int ret;
18567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18568     {
18569       if (unformat (input, "if_id %d", &if_id))
18570         ;
18571       else if (unformat (input, "pcap %s", &pcap_file))
18572         pcap_file_set = 1;
18573       else if (unformat (input, "count %d", &count))
18574         ;
18575       else if (unformat (input, "disable"))
18576         enable = 0;
18577       else
18578         break;
18579     }
18580   if (if_id == ~0)
18581     {
18582       errmsg ("missing pg interface index");
18583       return -99;
18584     }
18585   if (pcap_file_set > 0)
18586     {
18587       if (vec_len (pcap_file) > 255)
18588         {
18589           errmsg ("pcap file name is too long");
18590           return -99;
18591         }
18592     }
18593
18594   /* Construct the API message */
18595   M (PG_CAPTURE, mp);
18596   mp->context = 0;
18597   mp->interface_id = ntohl (if_id);
18598   mp->is_enabled = enable;
18599   mp->count = ntohl (count);
18600   if (pcap_file_set != 0)
18601     {
18602       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18603     }
18604   vec_free (pcap_file);
18605
18606   S (mp);
18607   W (ret);
18608   return ret;
18609 }
18610
18611 int
18612 api_pg_enable_disable (vat_main_t * vam)
18613 {
18614   unformat_input_t *input = vam->input;
18615   vl_api_pg_enable_disable_t *mp;
18616
18617   u8 enable = 1;
18618   u8 stream_name_set = 0;
18619   u8 *stream_name = 0;
18620   int ret;
18621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18622     {
18623       if (unformat (input, "stream %s", &stream_name))
18624         stream_name_set = 1;
18625       else if (unformat (input, "disable"))
18626         enable = 0;
18627       else
18628         break;
18629     }
18630
18631   if (stream_name_set > 0)
18632     {
18633       if (vec_len (stream_name) > 255)
18634         {
18635           errmsg ("stream name too long");
18636           return -99;
18637         }
18638     }
18639
18640   /* Construct the API message */
18641   M (PG_ENABLE_DISABLE, mp);
18642   mp->context = 0;
18643   mp->is_enabled = enable;
18644   if (stream_name_set != 0)
18645     {
18646       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18647     }
18648   vec_free (stream_name);
18649
18650   S (mp);
18651   W (ret);
18652   return ret;
18653 }
18654
18655 int
18656 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18657 {
18658   unformat_input_t *input = vam->input;
18659   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18660
18661   u16 *low_ports = 0;
18662   u16 *high_ports = 0;
18663   u16 this_low;
18664   u16 this_hi;
18665   vl_api_prefix_t prefix;
18666   u32 tmp, tmp2;
18667   u8 prefix_set = 0;
18668   u32 vrf_id = ~0;
18669   u8 is_add = 1;
18670   int ret;
18671
18672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18673     {
18674       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18675         prefix_set = 1;
18676       else if (unformat (input, "vrf %d", &vrf_id))
18677         ;
18678       else if (unformat (input, "del"))
18679         is_add = 0;
18680       else if (unformat (input, "port %d", &tmp))
18681         {
18682           if (tmp == 0 || tmp > 65535)
18683             {
18684               errmsg ("port %d out of range", tmp);
18685               return -99;
18686             }
18687           this_low = tmp;
18688           this_hi = this_low + 1;
18689           vec_add1 (low_ports, this_low);
18690           vec_add1 (high_ports, this_hi);
18691         }
18692       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18693         {
18694           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18695             {
18696               errmsg ("incorrect range parameters");
18697               return -99;
18698             }
18699           this_low = tmp;
18700           /* Note: in debug CLI +1 is added to high before
18701              passing to real fn that does "the work"
18702              (ip_source_and_port_range_check_add_del).
18703              This fn is a wrapper around the binary API fn a
18704              control plane will call, which expects this increment
18705              to have occurred. Hence letting the binary API control
18706              plane fn do the increment for consistency between VAT
18707              and other control planes.
18708            */
18709           this_hi = tmp2;
18710           vec_add1 (low_ports, this_low);
18711           vec_add1 (high_ports, this_hi);
18712         }
18713       else
18714         break;
18715     }
18716
18717   if (prefix_set == 0)
18718     {
18719       errmsg ("<address>/<mask> not specified");
18720       return -99;
18721     }
18722
18723   if (vrf_id == ~0)
18724     {
18725       errmsg ("VRF ID required, not specified");
18726       return -99;
18727     }
18728
18729   if (vrf_id == 0)
18730     {
18731       errmsg
18732         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18733       return -99;
18734     }
18735
18736   if (vec_len (low_ports) == 0)
18737     {
18738       errmsg ("At least one port or port range required");
18739       return -99;
18740     }
18741
18742   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18743
18744   mp->is_add = is_add;
18745
18746   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18747
18748   mp->number_of_ranges = vec_len (low_ports);
18749
18750   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18751   vec_free (low_ports);
18752
18753   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18754   vec_free (high_ports);
18755
18756   mp->vrf_id = ntohl (vrf_id);
18757
18758   S (mp);
18759   W (ret);
18760   return ret;
18761 }
18762
18763 int
18764 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18765 {
18766   unformat_input_t *input = vam->input;
18767   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18768   u32 sw_if_index = ~0;
18769   int vrf_set = 0;
18770   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18771   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18772   u8 is_add = 1;
18773   int ret;
18774
18775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18776     {
18777       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18778         ;
18779       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18780         ;
18781       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18782         vrf_set = 1;
18783       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18784         vrf_set = 1;
18785       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18786         vrf_set = 1;
18787       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18788         vrf_set = 1;
18789       else if (unformat (input, "del"))
18790         is_add = 0;
18791       else
18792         break;
18793     }
18794
18795   if (sw_if_index == ~0)
18796     {
18797       errmsg ("Interface required but not specified");
18798       return -99;
18799     }
18800
18801   if (vrf_set == 0)
18802     {
18803       errmsg ("VRF ID required but not specified");
18804       return -99;
18805     }
18806
18807   if (tcp_out_vrf_id == 0
18808       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18809     {
18810       errmsg
18811         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18812       return -99;
18813     }
18814
18815   /* Construct the API message */
18816   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18817
18818   mp->sw_if_index = ntohl (sw_if_index);
18819   mp->is_add = is_add;
18820   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18821   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18822   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18823   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18824
18825   /* send it... */
18826   S (mp);
18827
18828   /* Wait for a reply... */
18829   W (ret);
18830   return ret;
18831 }
18832
18833 static int
18834 api_set_punt (vat_main_t * vam)
18835 {
18836   unformat_input_t *i = vam->input;
18837   vl_api_address_family_t af;
18838   vl_api_set_punt_t *mp;
18839   u32 protocol = ~0;
18840   u32 port = ~0;
18841   int is_add = 1;
18842   int ret;
18843
18844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18845     {
18846       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18847         ;
18848       else if (unformat (i, "protocol %d", &protocol))
18849         ;
18850       else if (unformat (i, "port %d", &port))
18851         ;
18852       else if (unformat (i, "del"))
18853         is_add = 0;
18854       else
18855         {
18856           clib_warning ("parse error '%U'", format_unformat_error, i);
18857           return -99;
18858         }
18859     }
18860
18861   M (SET_PUNT, mp);
18862
18863   mp->is_add = (u8) is_add;
18864   mp->punt.type = PUNT_API_TYPE_L4;
18865   mp->punt.punt.l4.af = af;
18866   mp->punt.punt.l4.protocol = (u8) protocol;
18867   mp->punt.punt.l4.port = htons ((u16) port);
18868
18869   S (mp);
18870   W (ret);
18871   return ret;
18872 }
18873
18874 static int
18875 api_delete_subif (vat_main_t * vam)
18876 {
18877   unformat_input_t *i = vam->input;
18878   vl_api_delete_subif_t *mp;
18879   u32 sw_if_index = ~0;
18880   int ret;
18881
18882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18883     {
18884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18885         ;
18886       if (unformat (i, "sw_if_index %d", &sw_if_index))
18887         ;
18888       else
18889         break;
18890     }
18891
18892   if (sw_if_index == ~0)
18893     {
18894       errmsg ("missing sw_if_index");
18895       return -99;
18896     }
18897
18898   /* Construct the API message */
18899   M (DELETE_SUBIF, mp);
18900   mp->sw_if_index = ntohl (sw_if_index);
18901
18902   S (mp);
18903   W (ret);
18904   return ret;
18905 }
18906
18907 #define foreach_pbb_vtr_op      \
18908 _("disable",  L2_VTR_DISABLED)  \
18909 _("pop",  L2_VTR_POP_2)         \
18910 _("push",  L2_VTR_PUSH_2)
18911
18912 static int
18913 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18914 {
18915   unformat_input_t *i = vam->input;
18916   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18917   u32 sw_if_index = ~0, vtr_op = ~0;
18918   u16 outer_tag = ~0;
18919   u8 dmac[6], smac[6];
18920   u8 dmac_set = 0, smac_set = 0;
18921   u16 vlanid = 0;
18922   u32 sid = ~0;
18923   u32 tmp;
18924   int ret;
18925
18926   /* Shut up coverity */
18927   clib_memset (dmac, 0, sizeof (dmac));
18928   clib_memset (smac, 0, sizeof (smac));
18929
18930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18931     {
18932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18933         ;
18934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18935         ;
18936       else if (unformat (i, "vtr_op %d", &vtr_op))
18937         ;
18938 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18939       foreach_pbb_vtr_op
18940 #undef _
18941         else if (unformat (i, "translate_pbb_stag"))
18942         {
18943           if (unformat (i, "%d", &tmp))
18944             {
18945               vtr_op = L2_VTR_TRANSLATE_2_1;
18946               outer_tag = tmp;
18947             }
18948           else
18949             {
18950               errmsg
18951                 ("translate_pbb_stag operation requires outer tag definition");
18952               return -99;
18953             }
18954         }
18955       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18956         dmac_set++;
18957       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18958         smac_set++;
18959       else if (unformat (i, "sid %d", &sid))
18960         ;
18961       else if (unformat (i, "vlanid %d", &tmp))
18962         vlanid = tmp;
18963       else
18964         {
18965           clib_warning ("parse error '%U'", format_unformat_error, i);
18966           return -99;
18967         }
18968     }
18969
18970   if ((sw_if_index == ~0) || (vtr_op == ~0))
18971     {
18972       errmsg ("missing sw_if_index or vtr operation");
18973       return -99;
18974     }
18975   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18976       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18977     {
18978       errmsg
18979         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18980       return -99;
18981     }
18982
18983   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18984   mp->sw_if_index = ntohl (sw_if_index);
18985   mp->vtr_op = ntohl (vtr_op);
18986   mp->outer_tag = ntohs (outer_tag);
18987   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18988   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18989   mp->b_vlanid = ntohs (vlanid);
18990   mp->i_sid = ntohl (sid);
18991
18992   S (mp);
18993   W (ret);
18994   return ret;
18995 }
18996
18997 static int
18998 api_flow_classify_set_interface (vat_main_t * vam)
18999 {
19000   unformat_input_t *i = vam->input;
19001   vl_api_flow_classify_set_interface_t *mp;
19002   u32 sw_if_index;
19003   int sw_if_index_set;
19004   u32 ip4_table_index = ~0;
19005   u32 ip6_table_index = ~0;
19006   u8 is_add = 1;
19007   int ret;
19008
19009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19010     {
19011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19012         sw_if_index_set = 1;
19013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19014         sw_if_index_set = 1;
19015       else if (unformat (i, "del"))
19016         is_add = 0;
19017       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19018         ;
19019       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19020         ;
19021       else
19022         {
19023           clib_warning ("parse error '%U'", format_unformat_error, i);
19024           return -99;
19025         }
19026     }
19027
19028   if (sw_if_index_set == 0)
19029     {
19030       errmsg ("missing interface name or sw_if_index");
19031       return -99;
19032     }
19033
19034   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19035
19036   mp->sw_if_index = ntohl (sw_if_index);
19037   mp->ip4_table_index = ntohl (ip4_table_index);
19038   mp->ip6_table_index = ntohl (ip6_table_index);
19039   mp->is_add = is_add;
19040
19041   S (mp);
19042   W (ret);
19043   return ret;
19044 }
19045
19046 static int
19047 api_flow_classify_dump (vat_main_t * vam)
19048 {
19049   unformat_input_t *i = vam->input;
19050   vl_api_flow_classify_dump_t *mp;
19051   vl_api_control_ping_t *mp_ping;
19052   u8 type = FLOW_CLASSIFY_N_TABLES;
19053   int ret;
19054
19055   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19056     ;
19057   else
19058     {
19059       errmsg ("classify table type must be specified");
19060       return -99;
19061     }
19062
19063   if (!vam->json_output)
19064     {
19065       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19066     }
19067
19068   M (FLOW_CLASSIFY_DUMP, mp);
19069   mp->type = type;
19070   /* send it... */
19071   S (mp);
19072
19073   /* Use a control ping for synchronization */
19074   MPING (CONTROL_PING, mp_ping);
19075   S (mp_ping);
19076
19077   /* Wait for a reply... */
19078   W (ret);
19079   return ret;
19080 }
19081
19082 static int
19083 api_feature_enable_disable (vat_main_t * vam)
19084 {
19085   unformat_input_t *i = vam->input;
19086   vl_api_feature_enable_disable_t *mp;
19087   u8 *arc_name = 0;
19088   u8 *feature_name = 0;
19089   u32 sw_if_index = ~0;
19090   u8 enable = 1;
19091   int ret;
19092
19093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19094     {
19095       if (unformat (i, "arc_name %s", &arc_name))
19096         ;
19097       else if (unformat (i, "feature_name %s", &feature_name))
19098         ;
19099       else
19100         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19101         ;
19102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19103         ;
19104       else if (unformat (i, "disable"))
19105         enable = 0;
19106       else
19107         break;
19108     }
19109
19110   if (arc_name == 0)
19111     {
19112       errmsg ("missing arc name");
19113       return -99;
19114     }
19115   if (vec_len (arc_name) > 63)
19116     {
19117       errmsg ("arc name too long");
19118     }
19119
19120   if (feature_name == 0)
19121     {
19122       errmsg ("missing feature name");
19123       return -99;
19124     }
19125   if (vec_len (feature_name) > 63)
19126     {
19127       errmsg ("feature name too long");
19128     }
19129
19130   if (sw_if_index == ~0)
19131     {
19132       errmsg ("missing interface name or sw_if_index");
19133       return -99;
19134     }
19135
19136   /* Construct the API message */
19137   M (FEATURE_ENABLE_DISABLE, mp);
19138   mp->sw_if_index = ntohl (sw_if_index);
19139   mp->enable = enable;
19140   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19141   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19142   vec_free (arc_name);
19143   vec_free (feature_name);
19144
19145   S (mp);
19146   W (ret);
19147   return ret;
19148 }
19149
19150 static int
19151 api_feature_gso_enable_disable (vat_main_t * vam)
19152 {
19153   unformat_input_t *i = vam->input;
19154   vl_api_feature_gso_enable_disable_t *mp;
19155   u32 sw_if_index = ~0;
19156   u8 enable = 1;
19157   int ret;
19158
19159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19160     {
19161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19162         ;
19163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19164         ;
19165       else if (unformat (i, "enable"))
19166         enable = 1;
19167       else if (unformat (i, "disable"))
19168         enable = 0;
19169       else
19170         break;
19171     }
19172
19173   if (sw_if_index == ~0)
19174     {
19175       errmsg ("missing interface name or sw_if_index");
19176       return -99;
19177     }
19178
19179   /* Construct the API message */
19180   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19181   mp->sw_if_index = ntohl (sw_if_index);
19182   mp->enable_disable = enable;
19183
19184   S (mp);
19185   W (ret);
19186   return ret;
19187 }
19188
19189 static int
19190 api_sw_interface_tag_add_del (vat_main_t * vam)
19191 {
19192   unformat_input_t *i = vam->input;
19193   vl_api_sw_interface_tag_add_del_t *mp;
19194   u32 sw_if_index = ~0;
19195   u8 *tag = 0;
19196   u8 enable = 1;
19197   int ret;
19198
19199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19200     {
19201       if (unformat (i, "tag %s", &tag))
19202         ;
19203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19204         ;
19205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19206         ;
19207       else if (unformat (i, "del"))
19208         enable = 0;
19209       else
19210         break;
19211     }
19212
19213   if (sw_if_index == ~0)
19214     {
19215       errmsg ("missing interface name or sw_if_index");
19216       return -99;
19217     }
19218
19219   if (enable && (tag == 0))
19220     {
19221       errmsg ("no tag specified");
19222       return -99;
19223     }
19224
19225   /* Construct the API message */
19226   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19227   mp->sw_if_index = ntohl (sw_if_index);
19228   mp->is_add = enable;
19229   if (enable)
19230     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19231   vec_free (tag);
19232
19233   S (mp);
19234   W (ret);
19235   return ret;
19236 }
19237
19238 static int
19239 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19240 {
19241   unformat_input_t *i = vam->input;
19242   vl_api_mac_address_t mac = { 0 };
19243   vl_api_sw_interface_add_del_mac_address_t *mp;
19244   u32 sw_if_index = ~0;
19245   u8 is_add = 1;
19246   u8 mac_set = 0;
19247   int ret;
19248
19249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19250     {
19251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19252         ;
19253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19254         ;
19255       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19256         mac_set++;
19257       else if (unformat (i, "del"))
19258         is_add = 0;
19259       else
19260         break;
19261     }
19262
19263   if (sw_if_index == ~0)
19264     {
19265       errmsg ("missing interface name or sw_if_index");
19266       return -99;
19267     }
19268
19269   if (!mac_set)
19270     {
19271       errmsg ("missing MAC address");
19272       return -99;
19273     }
19274
19275   /* Construct the API message */
19276   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19277   mp->sw_if_index = ntohl (sw_if_index);
19278   mp->is_add = is_add;
19279   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19280
19281   S (mp);
19282   W (ret);
19283   return ret;
19284 }
19285
19286 static void vl_api_l2_xconnect_details_t_handler
19287   (vl_api_l2_xconnect_details_t * mp)
19288 {
19289   vat_main_t *vam = &vat_main;
19290
19291   print (vam->ofp, "%15d%15d",
19292          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19293 }
19294
19295 static void vl_api_l2_xconnect_details_t_handler_json
19296   (vl_api_l2_xconnect_details_t * mp)
19297 {
19298   vat_main_t *vam = &vat_main;
19299   vat_json_node_t *node = NULL;
19300
19301   if (VAT_JSON_ARRAY != vam->json_tree.type)
19302     {
19303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19304       vat_json_init_array (&vam->json_tree);
19305     }
19306   node = vat_json_array_add (&vam->json_tree);
19307
19308   vat_json_init_object (node);
19309   vat_json_object_add_uint (node, "rx_sw_if_index",
19310                             ntohl (mp->rx_sw_if_index));
19311   vat_json_object_add_uint (node, "tx_sw_if_index",
19312                             ntohl (mp->tx_sw_if_index));
19313 }
19314
19315 static int
19316 api_l2_xconnect_dump (vat_main_t * vam)
19317 {
19318   vl_api_l2_xconnect_dump_t *mp;
19319   vl_api_control_ping_t *mp_ping;
19320   int ret;
19321
19322   if (!vam->json_output)
19323     {
19324       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19325     }
19326
19327   M (L2_XCONNECT_DUMP, mp);
19328
19329   S (mp);
19330
19331   /* Use a control ping for synchronization */
19332   MPING (CONTROL_PING, mp_ping);
19333   S (mp_ping);
19334
19335   W (ret);
19336   return ret;
19337 }
19338
19339 static int
19340 api_hw_interface_set_mtu (vat_main_t * vam)
19341 {
19342   unformat_input_t *i = vam->input;
19343   vl_api_hw_interface_set_mtu_t *mp;
19344   u32 sw_if_index = ~0;
19345   u32 mtu = 0;
19346   int ret;
19347
19348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19349     {
19350       if (unformat (i, "mtu %d", &mtu))
19351         ;
19352       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19353         ;
19354       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19355         ;
19356       else
19357         break;
19358     }
19359
19360   if (sw_if_index == ~0)
19361     {
19362       errmsg ("missing interface name or sw_if_index");
19363       return -99;
19364     }
19365
19366   if (mtu == 0)
19367     {
19368       errmsg ("no mtu specified");
19369       return -99;
19370     }
19371
19372   /* Construct the API message */
19373   M (HW_INTERFACE_SET_MTU, mp);
19374   mp->sw_if_index = ntohl (sw_if_index);
19375   mp->mtu = ntohs ((u16) mtu);
19376
19377   S (mp);
19378   W (ret);
19379   return ret;
19380 }
19381
19382 static int
19383 api_p2p_ethernet_add (vat_main_t * vam)
19384 {
19385   unformat_input_t *i = vam->input;
19386   vl_api_p2p_ethernet_add_t *mp;
19387   u32 parent_if_index = ~0;
19388   u32 sub_id = ~0;
19389   u8 remote_mac[6];
19390   u8 mac_set = 0;
19391   int ret;
19392
19393   clib_memset (remote_mac, 0, sizeof (remote_mac));
19394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19395     {
19396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19397         ;
19398       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19399         ;
19400       else
19401         if (unformat
19402             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19403         mac_set++;
19404       else if (unformat (i, "sub_id %d", &sub_id))
19405         ;
19406       else
19407         {
19408           clib_warning ("parse error '%U'", format_unformat_error, i);
19409           return -99;
19410         }
19411     }
19412
19413   if (parent_if_index == ~0)
19414     {
19415       errmsg ("missing interface name or sw_if_index");
19416       return -99;
19417     }
19418   if (mac_set == 0)
19419     {
19420       errmsg ("missing remote mac address");
19421       return -99;
19422     }
19423   if (sub_id == ~0)
19424     {
19425       errmsg ("missing sub-interface id");
19426       return -99;
19427     }
19428
19429   M (P2P_ETHERNET_ADD, mp);
19430   mp->parent_if_index = ntohl (parent_if_index);
19431   mp->subif_id = ntohl (sub_id);
19432   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19433
19434   S (mp);
19435   W (ret);
19436   return ret;
19437 }
19438
19439 static int
19440 api_p2p_ethernet_del (vat_main_t * vam)
19441 {
19442   unformat_input_t *i = vam->input;
19443   vl_api_p2p_ethernet_del_t *mp;
19444   u32 parent_if_index = ~0;
19445   u8 remote_mac[6];
19446   u8 mac_set = 0;
19447   int ret;
19448
19449   clib_memset (remote_mac, 0, sizeof (remote_mac));
19450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19451     {
19452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19453         ;
19454       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19455         ;
19456       else
19457         if (unformat
19458             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19459         mac_set++;
19460       else
19461         {
19462           clib_warning ("parse error '%U'", format_unformat_error, i);
19463           return -99;
19464         }
19465     }
19466
19467   if (parent_if_index == ~0)
19468     {
19469       errmsg ("missing interface name or sw_if_index");
19470       return -99;
19471     }
19472   if (mac_set == 0)
19473     {
19474       errmsg ("missing remote mac address");
19475       return -99;
19476     }
19477
19478   M (P2P_ETHERNET_DEL, mp);
19479   mp->parent_if_index = ntohl (parent_if_index);
19480   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19481
19482   S (mp);
19483   W (ret);
19484   return ret;
19485 }
19486
19487 static int
19488 api_lldp_config (vat_main_t * vam)
19489 {
19490   unformat_input_t *i = vam->input;
19491   vl_api_lldp_config_t *mp;
19492   int tx_hold = 0;
19493   int tx_interval = 0;
19494   u8 *sys_name = NULL;
19495   int ret;
19496
19497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19498     {
19499       if (unformat (i, "system-name %s", &sys_name))
19500         ;
19501       else if (unformat (i, "tx-hold %d", &tx_hold))
19502         ;
19503       else if (unformat (i, "tx-interval %d", &tx_interval))
19504         ;
19505       else
19506         {
19507           clib_warning ("parse error '%U'", format_unformat_error, i);
19508           return -99;
19509         }
19510     }
19511
19512   vec_add1 (sys_name, 0);
19513
19514   M (LLDP_CONFIG, mp);
19515   mp->tx_hold = htonl (tx_hold);
19516   mp->tx_interval = htonl (tx_interval);
19517   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19518   vec_free (sys_name);
19519
19520   S (mp);
19521   W (ret);
19522   return ret;
19523 }
19524
19525 static int
19526 api_sw_interface_set_lldp (vat_main_t * vam)
19527 {
19528   unformat_input_t *i = vam->input;
19529   vl_api_sw_interface_set_lldp_t *mp;
19530   u32 sw_if_index = ~0;
19531   u32 enable = 1;
19532   u8 *port_desc = NULL, *mgmt_oid = NULL;
19533   ip4_address_t ip4_addr;
19534   ip6_address_t ip6_addr;
19535   int ret;
19536
19537   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19538   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19539
19540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19541     {
19542       if (unformat (i, "disable"))
19543         enable = 0;
19544       else
19545         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19546         ;
19547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19548         ;
19549       else if (unformat (i, "port-desc %s", &port_desc))
19550         ;
19551       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19552         ;
19553       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19554         ;
19555       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19556         ;
19557       else
19558         break;
19559     }
19560
19561   if (sw_if_index == ~0)
19562     {
19563       errmsg ("missing interface name or sw_if_index");
19564       return -99;
19565     }
19566
19567   /* Construct the API message */
19568   vec_add1 (port_desc, 0);
19569   vec_add1 (mgmt_oid, 0);
19570   M (SW_INTERFACE_SET_LLDP, mp);
19571   mp->sw_if_index = ntohl (sw_if_index);
19572   mp->enable = enable;
19573   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19574   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19575   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19576   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19577   vec_free (port_desc);
19578   vec_free (mgmt_oid);
19579
19580   S (mp);
19581   W (ret);
19582   return ret;
19583 }
19584
19585 static int
19586 api_tcp_configure_src_addresses (vat_main_t * vam)
19587 {
19588   vl_api_tcp_configure_src_addresses_t *mp;
19589   unformat_input_t *i = vam->input;
19590   vl_api_address_t first, last;
19591   u8 range_set = 0;
19592   u32 vrf_id = 0;
19593   int ret;
19594
19595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19596     {
19597       if (unformat (i, "%U - %U",
19598                     unformat_vl_api_address, &first,
19599                     unformat_vl_api_address, &last))
19600         {
19601           if (range_set)
19602             {
19603               errmsg ("one range per message (range already set)");
19604               return -99;
19605             }
19606           range_set = 1;
19607         }
19608       else if (unformat (i, "vrf %d", &vrf_id))
19609         ;
19610       else
19611         break;
19612     }
19613
19614   if (range_set == 0)
19615     {
19616       errmsg ("address range not set");
19617       return -99;
19618     }
19619
19620   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19621
19622   mp->vrf_id = ntohl (vrf_id);
19623   clib_memcpy (&mp->first_address, &first, sizeof (first));
19624   clib_memcpy (&mp->last_address, &last, sizeof (last));
19625
19626   S (mp);
19627   W (ret);
19628   return ret;
19629 }
19630
19631 static void vl_api_app_namespace_add_del_reply_t_handler
19632   (vl_api_app_namespace_add_del_reply_t * mp)
19633 {
19634   vat_main_t *vam = &vat_main;
19635   i32 retval = ntohl (mp->retval);
19636   if (vam->async_mode)
19637     {
19638       vam->async_errors += (retval < 0);
19639     }
19640   else
19641     {
19642       vam->retval = retval;
19643       if (retval == 0)
19644         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19645       vam->result_ready = 1;
19646     }
19647 }
19648
19649 static void vl_api_app_namespace_add_del_reply_t_handler_json
19650   (vl_api_app_namespace_add_del_reply_t * mp)
19651 {
19652   vat_main_t *vam = &vat_main;
19653   vat_json_node_t node;
19654
19655   vat_json_init_object (&node);
19656   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19657   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19658
19659   vat_json_print (vam->ofp, &node);
19660   vat_json_free (&node);
19661
19662   vam->retval = ntohl (mp->retval);
19663   vam->result_ready = 1;
19664 }
19665
19666 static int
19667 api_app_namespace_add_del (vat_main_t * vam)
19668 {
19669   vl_api_app_namespace_add_del_t *mp;
19670   unformat_input_t *i = vam->input;
19671   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19672   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19673   u64 secret;
19674   int ret;
19675
19676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19677     {
19678       if (unformat (i, "id %_%v%_", &ns_id))
19679         ;
19680       else if (unformat (i, "secret %lu", &secret))
19681         secret_set = 1;
19682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19683         sw_if_index_set = 1;
19684       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19685         ;
19686       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19687         ;
19688       else
19689         break;
19690     }
19691   if (!ns_id || !secret_set || !sw_if_index_set)
19692     {
19693       errmsg ("namespace id, secret and sw_if_index must be set");
19694       return -99;
19695     }
19696   if (vec_len (ns_id) > 64)
19697     {
19698       errmsg ("namespace id too long");
19699       return -99;
19700     }
19701   M (APP_NAMESPACE_ADD_DEL, mp);
19702
19703   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19704   mp->secret = clib_host_to_net_u64 (secret);
19705   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19706   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19707   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19708   vec_free (ns_id);
19709   S (mp);
19710   W (ret);
19711   return ret;
19712 }
19713
19714 static int
19715 api_sock_init_shm (vat_main_t * vam)
19716 {
19717 #if VPP_API_TEST_BUILTIN == 0
19718   unformat_input_t *i = vam->input;
19719   vl_api_shm_elem_config_t *config = 0;
19720   u64 size = 64 << 20;
19721   int rv;
19722
19723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19724     {
19725       if (unformat (i, "size %U", unformat_memory_size, &size))
19726         ;
19727       else
19728         break;
19729     }
19730
19731   /*
19732    * Canned custom ring allocator config.
19733    * Should probably parse all of this
19734    */
19735   vec_validate (config, 6);
19736   config[0].type = VL_API_VLIB_RING;
19737   config[0].size = 256;
19738   config[0].count = 32;
19739
19740   config[1].type = VL_API_VLIB_RING;
19741   config[1].size = 1024;
19742   config[1].count = 16;
19743
19744   config[2].type = VL_API_VLIB_RING;
19745   config[2].size = 4096;
19746   config[2].count = 2;
19747
19748   config[3].type = VL_API_CLIENT_RING;
19749   config[3].size = 256;
19750   config[3].count = 32;
19751
19752   config[4].type = VL_API_CLIENT_RING;
19753   config[4].size = 1024;
19754   config[4].count = 16;
19755
19756   config[5].type = VL_API_CLIENT_RING;
19757   config[5].size = 4096;
19758   config[5].count = 2;
19759
19760   config[6].type = VL_API_QUEUE;
19761   config[6].count = 128;
19762   config[6].size = sizeof (uword);
19763
19764   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19765   if (!rv)
19766     vam->client_index_invalid = 1;
19767   return rv;
19768 #else
19769   return -99;
19770 #endif
19771 }
19772
19773 static void
19774 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19775 {
19776   vat_main_t *vam = &vat_main;
19777   fib_prefix_t lcl, rmt;
19778
19779   ip_prefix_decode (&mp->lcl, &lcl);
19780   ip_prefix_decode (&mp->rmt, &rmt);
19781
19782   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19783     {
19784       print (vam->ofp,
19785              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19786              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19787              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19788              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19789              &rmt.fp_addr.ip4, rmt.fp_len,
19790              clib_net_to_host_u16 (mp->rmt_port),
19791              clib_net_to_host_u32 (mp->action_index), mp->tag);
19792     }
19793   else
19794     {
19795       print (vam->ofp,
19796              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19797              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19798              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19799              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19800              &rmt.fp_addr.ip6, rmt.fp_len,
19801              clib_net_to_host_u16 (mp->rmt_port),
19802              clib_net_to_host_u32 (mp->action_index), mp->tag);
19803     }
19804 }
19805
19806 static void
19807 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19808                                              mp)
19809 {
19810   vat_main_t *vam = &vat_main;
19811   vat_json_node_t *node = NULL;
19812   struct in6_addr ip6;
19813   struct in_addr ip4;
19814
19815   fib_prefix_t lcl, rmt;
19816
19817   ip_prefix_decode (&mp->lcl, &lcl);
19818   ip_prefix_decode (&mp->rmt, &rmt);
19819
19820   if (VAT_JSON_ARRAY != vam->json_tree.type)
19821     {
19822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19823       vat_json_init_array (&vam->json_tree);
19824     }
19825   node = vat_json_array_add (&vam->json_tree);
19826   vat_json_init_object (node);
19827
19828   vat_json_object_add_uint (node, "appns_index",
19829                             clib_net_to_host_u32 (mp->appns_index));
19830   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19831   vat_json_object_add_uint (node, "scope", mp->scope);
19832   vat_json_object_add_uint (node, "action_index",
19833                             clib_net_to_host_u32 (mp->action_index));
19834   vat_json_object_add_uint (node, "lcl_port",
19835                             clib_net_to_host_u16 (mp->lcl_port));
19836   vat_json_object_add_uint (node, "rmt_port",
19837                             clib_net_to_host_u16 (mp->rmt_port));
19838   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19839   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19840   vat_json_object_add_string_copy (node, "tag", mp->tag);
19841   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19842     {
19843       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19844       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19845       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19846       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19847     }
19848   else
19849     {
19850       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19851       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19852       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19853       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19854     }
19855 }
19856
19857 static int
19858 api_session_rule_add_del (vat_main_t * vam)
19859 {
19860   vl_api_session_rule_add_del_t *mp;
19861   unformat_input_t *i = vam->input;
19862   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19863   u32 appns_index = 0, scope = 0;
19864   ip4_address_t lcl_ip4, rmt_ip4;
19865   ip6_address_t lcl_ip6, rmt_ip6;
19866   u8 is_ip4 = 1, conn_set = 0;
19867   u8 is_add = 1, *tag = 0;
19868   int ret;
19869   fib_prefix_t lcl, rmt;
19870
19871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19872     {
19873       if (unformat (i, "del"))
19874         is_add = 0;
19875       else if (unformat (i, "add"))
19876         ;
19877       else if (unformat (i, "proto tcp"))
19878         proto = 0;
19879       else if (unformat (i, "proto udp"))
19880         proto = 1;
19881       else if (unformat (i, "appns %d", &appns_index))
19882         ;
19883       else if (unformat (i, "scope %d", &scope))
19884         ;
19885       else if (unformat (i, "tag %_%v%_", &tag))
19886         ;
19887       else
19888         if (unformat
19889             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19890              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19891              &rmt_port))
19892         {
19893           is_ip4 = 1;
19894           conn_set = 1;
19895         }
19896       else
19897         if (unformat
19898             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19899              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19900              &rmt_port))
19901         {
19902           is_ip4 = 0;
19903           conn_set = 1;
19904         }
19905       else if (unformat (i, "action %d", &action))
19906         ;
19907       else
19908         break;
19909     }
19910   if (proto == ~0 || !conn_set || action == ~0)
19911     {
19912       errmsg ("transport proto, connection and action must be set");
19913       return -99;
19914     }
19915
19916   if (scope > 3)
19917     {
19918       errmsg ("scope should be 0-3");
19919       return -99;
19920     }
19921
19922   M (SESSION_RULE_ADD_DEL, mp);
19923
19924   clib_memset (&lcl, 0, sizeof (lcl));
19925   clib_memset (&rmt, 0, sizeof (rmt));
19926   if (is_ip4)
19927     {
19928       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19929       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19930       lcl.fp_len = lcl_plen;
19931       rmt.fp_len = rmt_plen;
19932     }
19933   else
19934     {
19935       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19936       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19937       lcl.fp_len = lcl_plen;
19938       rmt.fp_len = rmt_plen;
19939     }
19940
19941
19942   ip_prefix_encode (&lcl, &mp->lcl);
19943   ip_prefix_encode (&rmt, &mp->rmt);
19944   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19945   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19946   mp->transport_proto =
19947     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19948   mp->action_index = clib_host_to_net_u32 (action);
19949   mp->appns_index = clib_host_to_net_u32 (appns_index);
19950   mp->scope = scope;
19951   mp->is_add = is_add;
19952   if (tag)
19953     {
19954       clib_memcpy (mp->tag, tag, vec_len (tag));
19955       vec_free (tag);
19956     }
19957
19958   S (mp);
19959   W (ret);
19960   return ret;
19961 }
19962
19963 static int
19964 api_session_rules_dump (vat_main_t * vam)
19965 {
19966   vl_api_session_rules_dump_t *mp;
19967   vl_api_control_ping_t *mp_ping;
19968   int ret;
19969
19970   if (!vam->json_output)
19971     {
19972       print (vam->ofp, "%=20s", "Session Rules");
19973     }
19974
19975   M (SESSION_RULES_DUMP, mp);
19976   /* send it... */
19977   S (mp);
19978
19979   /* Use a control ping for synchronization */
19980   MPING (CONTROL_PING, mp_ping);
19981   S (mp_ping);
19982
19983   /* Wait for a reply... */
19984   W (ret);
19985   return ret;
19986 }
19987
19988 static int
19989 api_ip_container_proxy_add_del (vat_main_t * vam)
19990 {
19991   vl_api_ip_container_proxy_add_del_t *mp;
19992   unformat_input_t *i = vam->input;
19993   u32 sw_if_index = ~0;
19994   vl_api_prefix_t pfx = { };
19995   u8 is_add = 1;
19996   int ret;
19997
19998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19999     {
20000       if (unformat (i, "del"))
20001         is_add = 0;
20002       else if (unformat (i, "add"))
20003         ;
20004       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20005         ;
20006       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20007         ;
20008       else
20009         break;
20010     }
20011   if (sw_if_index == ~0 || pfx.len == 0)
20012     {
20013       errmsg ("address and sw_if_index must be set");
20014       return -99;
20015     }
20016
20017   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20018
20019   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20020   mp->is_add = is_add;
20021   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20022
20023   S (mp);
20024   W (ret);
20025   return ret;
20026 }
20027
20028 static int
20029 api_qos_record_enable_disable (vat_main_t * vam)
20030 {
20031   unformat_input_t *i = vam->input;
20032   vl_api_qos_record_enable_disable_t *mp;
20033   u32 sw_if_index, qs = 0xff;
20034   u8 sw_if_index_set = 0;
20035   u8 enable = 1;
20036   int ret;
20037
20038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20039     {
20040       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20041         sw_if_index_set = 1;
20042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20043         sw_if_index_set = 1;
20044       else if (unformat (i, "%U", unformat_qos_source, &qs))
20045         ;
20046       else if (unformat (i, "disable"))
20047         enable = 0;
20048       else
20049         {
20050           clib_warning ("parse error '%U'", format_unformat_error, i);
20051           return -99;
20052         }
20053     }
20054
20055   if (sw_if_index_set == 0)
20056     {
20057       errmsg ("missing interface name or sw_if_index");
20058       return -99;
20059     }
20060   if (qs == 0xff)
20061     {
20062       errmsg ("input location must be specified");
20063       return -99;
20064     }
20065
20066   M (QOS_RECORD_ENABLE_DISABLE, mp);
20067
20068   mp->record.sw_if_index = ntohl (sw_if_index);
20069   mp->record.input_source = qs;
20070   mp->enable = enable;
20071
20072   S (mp);
20073   W (ret);
20074   return ret;
20075 }
20076
20077
20078 static int
20079 q_or_quit (vat_main_t * vam)
20080 {
20081 #if VPP_API_TEST_BUILTIN == 0
20082   longjmp (vam->jump_buf, 1);
20083 #endif
20084   return 0;                     /* not so much */
20085 }
20086
20087 static int
20088 q (vat_main_t * vam)
20089 {
20090   return q_or_quit (vam);
20091 }
20092
20093 static int
20094 quit (vat_main_t * vam)
20095 {
20096   return q_or_quit (vam);
20097 }
20098
20099 static int
20100 comment (vat_main_t * vam)
20101 {
20102   return 0;
20103 }
20104
20105 static int
20106 elog_save (vat_main_t * vam)
20107 {
20108 #if VPP_API_TEST_BUILTIN == 0
20109   elog_main_t *em = &vam->elog_main;
20110   unformat_input_t *i = vam->input;
20111   char *file, *chroot_file;
20112   clib_error_t *error;
20113
20114   if (!unformat (i, "%s", &file))
20115     {
20116       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20117       return 0;
20118     }
20119
20120   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20121   if (strstr (file, "..") || index (file, '/'))
20122     {
20123       errmsg ("illegal characters in filename '%s'", file);
20124       return 0;
20125     }
20126
20127   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20128
20129   vec_free (file);
20130
20131   errmsg ("Saving %wd of %wd events to %s",
20132           elog_n_events_in_buffer (em),
20133           elog_buffer_capacity (em), chroot_file);
20134
20135   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20136   vec_free (chroot_file);
20137
20138   if (error)
20139     clib_error_report (error);
20140 #else
20141   errmsg ("Use the vpp event loger...");
20142 #endif
20143
20144   return 0;
20145 }
20146
20147 static int
20148 elog_setup (vat_main_t * vam)
20149 {
20150 #if VPP_API_TEST_BUILTIN == 0
20151   elog_main_t *em = &vam->elog_main;
20152   unformat_input_t *i = vam->input;
20153   u32 nevents = 128 << 10;
20154
20155   (void) unformat (i, "nevents %d", &nevents);
20156
20157   elog_init (em, nevents);
20158   vl_api_set_elog_main (em);
20159   vl_api_set_elog_trace_api_messages (1);
20160   errmsg ("Event logger initialized with %u events", nevents);
20161 #else
20162   errmsg ("Use the vpp event loger...");
20163 #endif
20164   return 0;
20165 }
20166
20167 static int
20168 elog_enable (vat_main_t * vam)
20169 {
20170 #if VPP_API_TEST_BUILTIN == 0
20171   elog_main_t *em = &vam->elog_main;
20172
20173   elog_enable_disable (em, 1 /* enable */ );
20174   vl_api_set_elog_trace_api_messages (1);
20175   errmsg ("Event logger enabled...");
20176 #else
20177   errmsg ("Use the vpp event loger...");
20178 #endif
20179   return 0;
20180 }
20181
20182 static int
20183 elog_disable (vat_main_t * vam)
20184 {
20185 #if VPP_API_TEST_BUILTIN == 0
20186   elog_main_t *em = &vam->elog_main;
20187
20188   elog_enable_disable (em, 0 /* enable */ );
20189   vl_api_set_elog_trace_api_messages (1);
20190   errmsg ("Event logger disabled...");
20191 #else
20192   errmsg ("Use the vpp event loger...");
20193 #endif
20194   return 0;
20195 }
20196
20197 static int
20198 statseg (vat_main_t * vam)
20199 {
20200   ssvm_private_t *ssvmp = &vam->stat_segment;
20201   ssvm_shared_header_t *shared_header = ssvmp->sh;
20202   vlib_counter_t **counters;
20203   u64 thread0_index1_packets;
20204   u64 thread0_index1_bytes;
20205   f64 vector_rate, input_rate;
20206   uword *p;
20207
20208   uword *counter_vector_by_name;
20209   if (vam->stat_segment_lockp == 0)
20210     {
20211       errmsg ("Stat segment not mapped...");
20212       return -99;
20213     }
20214
20215   /* look up "/if/rx for sw_if_index 1 as a test */
20216
20217   clib_spinlock_lock (vam->stat_segment_lockp);
20218
20219   counter_vector_by_name = (uword *) shared_header->opaque[1];
20220
20221   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20222   if (p == 0)
20223     {
20224       clib_spinlock_unlock (vam->stat_segment_lockp);
20225       errmsg ("/if/tx not found?");
20226       return -99;
20227     }
20228
20229   /* Fish per-thread vector of combined counters from shared memory */
20230   counters = (vlib_counter_t **) p[0];
20231
20232   if (vec_len (counters[0]) < 2)
20233     {
20234       clib_spinlock_unlock (vam->stat_segment_lockp);
20235       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20236       return -99;
20237     }
20238
20239   /* Read thread 0 sw_if_index 1 counter */
20240   thread0_index1_packets = counters[0][1].packets;
20241   thread0_index1_bytes = counters[0][1].bytes;
20242
20243   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20244   if (p == 0)
20245     {
20246       clib_spinlock_unlock (vam->stat_segment_lockp);
20247       errmsg ("vector_rate not found?");
20248       return -99;
20249     }
20250
20251   vector_rate = *(f64 *) (p[0]);
20252   p = hash_get_mem (counter_vector_by_name, "input_rate");
20253   if (p == 0)
20254     {
20255       clib_spinlock_unlock (vam->stat_segment_lockp);
20256       errmsg ("input_rate not found?");
20257       return -99;
20258     }
20259   input_rate = *(f64 *) (p[0]);
20260
20261   clib_spinlock_unlock (vam->stat_segment_lockp);
20262
20263   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20264          vector_rate, input_rate);
20265   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20266          thread0_index1_packets, thread0_index1_bytes);
20267
20268   return 0;
20269 }
20270
20271 static int
20272 cmd_cmp (void *a1, void *a2)
20273 {
20274   u8 **c1 = a1;
20275   u8 **c2 = a2;
20276
20277   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20278 }
20279
20280 static int
20281 help (vat_main_t * vam)
20282 {
20283   u8 **cmds = 0;
20284   u8 *name = 0;
20285   hash_pair_t *p;
20286   unformat_input_t *i = vam->input;
20287   int j;
20288
20289   if (unformat (i, "%s", &name))
20290     {
20291       uword *hs;
20292
20293       vec_add1 (name, 0);
20294
20295       hs = hash_get_mem (vam->help_by_name, name);
20296       if (hs)
20297         print (vam->ofp, "usage: %s %s", name, hs[0]);
20298       else
20299         print (vam->ofp, "No such msg / command '%s'", name);
20300       vec_free (name);
20301       return 0;
20302     }
20303
20304   print (vam->ofp, "Help is available for the following:");
20305
20306     /* *INDENT-OFF* */
20307     hash_foreach_pair (p, vam->function_by_name,
20308     ({
20309       vec_add1 (cmds, (u8 *)(p->key));
20310     }));
20311     /* *INDENT-ON* */
20312
20313   vec_sort_with_function (cmds, cmd_cmp);
20314
20315   for (j = 0; j < vec_len (cmds); j++)
20316     print (vam->ofp, "%s", cmds[j]);
20317
20318   vec_free (cmds);
20319   return 0;
20320 }
20321
20322 static int
20323 set (vat_main_t * vam)
20324 {
20325   u8 *name = 0, *value = 0;
20326   unformat_input_t *i = vam->input;
20327
20328   if (unformat (i, "%s", &name))
20329     {
20330       /* The input buffer is a vector, not a string. */
20331       value = vec_dup (i->buffer);
20332       vec_delete (value, i->index, 0);
20333       /* Almost certainly has a trailing newline */
20334       if (value[vec_len (value) - 1] == '\n')
20335         value[vec_len (value) - 1] = 0;
20336       /* Make sure it's a proper string, one way or the other */
20337       vec_add1 (value, 0);
20338       (void) clib_macro_set_value (&vam->macro_main,
20339                                    (char *) name, (char *) value);
20340     }
20341   else
20342     errmsg ("usage: set <name> <value>");
20343
20344   vec_free (name);
20345   vec_free (value);
20346   return 0;
20347 }
20348
20349 static int
20350 unset (vat_main_t * vam)
20351 {
20352   u8 *name = 0;
20353
20354   if (unformat (vam->input, "%s", &name))
20355     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20356       errmsg ("unset: %s wasn't set", name);
20357   vec_free (name);
20358   return 0;
20359 }
20360
20361 typedef struct
20362 {
20363   u8 *name;
20364   u8 *value;
20365 } macro_sort_t;
20366
20367
20368 static int
20369 macro_sort_cmp (void *a1, void *a2)
20370 {
20371   macro_sort_t *s1 = a1;
20372   macro_sort_t *s2 = a2;
20373
20374   return strcmp ((char *) (s1->name), (char *) (s2->name));
20375 }
20376
20377 static int
20378 dump_macro_table (vat_main_t * vam)
20379 {
20380   macro_sort_t *sort_me = 0, *sm;
20381   int i;
20382   hash_pair_t *p;
20383
20384     /* *INDENT-OFF* */
20385     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20386     ({
20387       vec_add2 (sort_me, sm, 1);
20388       sm->name = (u8 *)(p->key);
20389       sm->value = (u8 *) (p->value[0]);
20390     }));
20391     /* *INDENT-ON* */
20392
20393   vec_sort_with_function (sort_me, macro_sort_cmp);
20394
20395   if (vec_len (sort_me))
20396     print (vam->ofp, "%-15s%s", "Name", "Value");
20397   else
20398     print (vam->ofp, "The macro table is empty...");
20399
20400   for (i = 0; i < vec_len (sort_me); i++)
20401     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20402   return 0;
20403 }
20404
20405 static int
20406 dump_node_table (vat_main_t * vam)
20407 {
20408   int i, j;
20409   vlib_node_t *node, *next_node;
20410
20411   if (vec_len (vam->graph_nodes) == 0)
20412     {
20413       print (vam->ofp, "Node table empty, issue get_node_graph...");
20414       return 0;
20415     }
20416
20417   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20418     {
20419       node = vam->graph_nodes[0][i];
20420       print (vam->ofp, "[%d] %s", i, node->name);
20421       for (j = 0; j < vec_len (node->next_nodes); j++)
20422         {
20423           if (node->next_nodes[j] != ~0)
20424             {
20425               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20426               print (vam->ofp, "  [%d] %s", j, next_node->name);
20427             }
20428         }
20429     }
20430   return 0;
20431 }
20432
20433 static int
20434 value_sort_cmp (void *a1, void *a2)
20435 {
20436   name_sort_t *n1 = a1;
20437   name_sort_t *n2 = a2;
20438
20439   if (n1->value < n2->value)
20440     return -1;
20441   if (n1->value > n2->value)
20442     return 1;
20443   return 0;
20444 }
20445
20446
20447 static int
20448 dump_msg_api_table (vat_main_t * vam)
20449 {
20450   api_main_t *am = vlibapi_get_main ();
20451   name_sort_t *nses = 0, *ns;
20452   hash_pair_t *hp;
20453   int i;
20454
20455   /* *INDENT-OFF* */
20456   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20457   ({
20458     vec_add2 (nses, ns, 1);
20459     ns->name = (u8 *)(hp->key);
20460     ns->value = (u32) hp->value[0];
20461   }));
20462   /* *INDENT-ON* */
20463
20464   vec_sort_with_function (nses, value_sort_cmp);
20465
20466   for (i = 0; i < vec_len (nses); i++)
20467     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20468   vec_free (nses);
20469   return 0;
20470 }
20471
20472 static int
20473 get_msg_id (vat_main_t * vam)
20474 {
20475   u8 *name_and_crc;
20476   u32 message_index;
20477
20478   if (unformat (vam->input, "%s", &name_and_crc))
20479     {
20480       message_index = vl_msg_api_get_msg_index (name_and_crc);
20481       if (message_index == ~0)
20482         {
20483           print (vam->ofp, " '%s' not found", name_and_crc);
20484           return 0;
20485         }
20486       print (vam->ofp, " '%s' has message index %d",
20487              name_and_crc, message_index);
20488       return 0;
20489     }
20490   errmsg ("name_and_crc required...");
20491   return 0;
20492 }
20493
20494 static int
20495 search_node_table (vat_main_t * vam)
20496 {
20497   unformat_input_t *line_input = vam->input;
20498   u8 *node_to_find;
20499   int j;
20500   vlib_node_t *node, *next_node;
20501   uword *p;
20502
20503   if (vam->graph_node_index_by_name == 0)
20504     {
20505       print (vam->ofp, "Node table empty, issue get_node_graph...");
20506       return 0;
20507     }
20508
20509   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20510     {
20511       if (unformat (line_input, "%s", &node_to_find))
20512         {
20513           vec_add1 (node_to_find, 0);
20514           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20515           if (p == 0)
20516             {
20517               print (vam->ofp, "%s not found...", node_to_find);
20518               goto out;
20519             }
20520           node = vam->graph_nodes[0][p[0]];
20521           print (vam->ofp, "[%d] %s", p[0], node->name);
20522           for (j = 0; j < vec_len (node->next_nodes); j++)
20523             {
20524               if (node->next_nodes[j] != ~0)
20525                 {
20526                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20527                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20528                 }
20529             }
20530         }
20531
20532       else
20533         {
20534           clib_warning ("parse error '%U'", format_unformat_error,
20535                         line_input);
20536           return -99;
20537         }
20538
20539     out:
20540       vec_free (node_to_find);
20541
20542     }
20543
20544   return 0;
20545 }
20546
20547
20548 static int
20549 script (vat_main_t * vam)
20550 {
20551 #if (VPP_API_TEST_BUILTIN==0)
20552   u8 *s = 0;
20553   char *save_current_file;
20554   unformat_input_t save_input;
20555   jmp_buf save_jump_buf;
20556   u32 save_line_number;
20557
20558   FILE *new_fp, *save_ifp;
20559
20560   if (unformat (vam->input, "%s", &s))
20561     {
20562       new_fp = fopen ((char *) s, "r");
20563       if (new_fp == 0)
20564         {
20565           errmsg ("Couldn't open script file %s", s);
20566           vec_free (s);
20567           return -99;
20568         }
20569     }
20570   else
20571     {
20572       errmsg ("Missing script name");
20573       return -99;
20574     }
20575
20576   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20577   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20578   save_ifp = vam->ifp;
20579   save_line_number = vam->input_line_number;
20580   save_current_file = (char *) vam->current_file;
20581
20582   vam->input_line_number = 0;
20583   vam->ifp = new_fp;
20584   vam->current_file = s;
20585   do_one_file (vam);
20586
20587   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20588   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20589   vam->ifp = save_ifp;
20590   vam->input_line_number = save_line_number;
20591   vam->current_file = (u8 *) save_current_file;
20592   vec_free (s);
20593
20594   return 0;
20595 #else
20596   clib_warning ("use the exec command...");
20597   return -99;
20598 #endif
20599 }
20600
20601 static int
20602 echo (vat_main_t * vam)
20603 {
20604   print (vam->ofp, "%v", vam->input->buffer);
20605   return 0;
20606 }
20607
20608 /* List of API message constructors, CLI names map to api_xxx */
20609 #define foreach_vpe_api_msg                                             \
20610 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20611 _(sw_interface_dump,"")                                                 \
20612 _(sw_interface_set_flags,                                               \
20613   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20614 _(sw_interface_add_del_address,                                         \
20615   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20616 _(sw_interface_set_rx_mode,                                             \
20617   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20618 _(sw_interface_set_rx_placement,                                        \
20619   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20620 _(sw_interface_rx_placement_dump,                                       \
20621   "[<intfc> | sw_if_index <id>]")                                         \
20622 _(sw_interface_set_table,                                               \
20623   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20624 _(sw_interface_set_mpls_enable,                                         \
20625   "<intfc> | sw_if_index [disable | dis]")                              \
20626 _(sw_interface_set_vpath,                                               \
20627   "<intfc> | sw_if_index <id> enable | disable")                        \
20628 _(sw_interface_set_vxlan_bypass,                                        \
20629   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20630 _(sw_interface_set_geneve_bypass,                                       \
20631   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20632 _(sw_interface_set_l2_xconnect,                                         \
20633   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20634   "enable | disable")                                                   \
20635 _(sw_interface_set_l2_bridge,                                           \
20636   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20637   "[shg <split-horizon-group>] [bvi]\n"                                 \
20638   "enable | disable")                                                   \
20639 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20640 _(bridge_domain_add_del,                                                \
20641   "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") \
20642 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20643 _(l2fib_add_del,                                                        \
20644   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20645 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20646 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20647 _(l2_flags,                                                             \
20648   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20649 _(bridge_flags,                                                         \
20650   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20651 _(tap_create_v2,                                                        \
20652   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload] [persist] [attach]") \
20653 _(tap_delete_v2,                                                        \
20654   "<vpp-if-name> | sw_if_index <id>")                                   \
20655 _(sw_interface_tap_v2_dump, "")                                         \
20656 _(virtio_pci_create,                                                    \
20657   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20658 _(virtio_pci_delete,                                                    \
20659   "<vpp-if-name> | sw_if_index <id>")                                   \
20660 _(sw_interface_virtio_pci_dump, "")                                     \
20661 _(bond_create,                                                          \
20662   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20663   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20664   "[id <if-id>]")                                                       \
20665 _(bond_delete,                                                          \
20666   "<vpp-if-name> | sw_if_index <id>")                                   \
20667 _(bond_enslave,                                                         \
20668   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20669 _(bond_detach_slave,                                                    \
20670   "sw_if_index <n>")                                                    \
20671  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20672 _(sw_interface_bond_dump, "")                                           \
20673 _(sw_interface_slave_dump,                                              \
20674   "<vpp-if-name> | sw_if_index <id>")                                   \
20675 _(ip_table_add_del,                                                     \
20676   "table <n> [ipv6] [add | del]\n")                                     \
20677 _(ip_route_add_del,                                                     \
20678   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20679   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20680   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20681   "[multipath] [count <n>] [del]")                                      \
20682 _(ip_mroute_add_del,                                                    \
20683   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20684   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20685 _(mpls_table_add_del,                                                   \
20686   "table <n> [add | del]\n")                                            \
20687 _(mpls_route_add_del,                                                   \
20688   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20689   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20690   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20691   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20692   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20693   "[count <n>] [del]")                                                  \
20694 _(mpls_ip_bind_unbind,                                                  \
20695   "<label> <addr/len>")                                                 \
20696 _(mpls_tunnel_add_del,                                                  \
20697   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20698   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20699   "[l2-only]  [out-label <n>]")                                         \
20700 _(sr_mpls_policy_add,                                                   \
20701   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20702 _(sr_mpls_policy_del,                                                   \
20703   "bsid <id>")                                                          \
20704 _(bier_table_add_del,                                                   \
20705   "<label> <sub-domain> <set> <bsl> [del]")                             \
20706 _(bier_route_add_del,                                                   \
20707   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20708   "[<intfc> | sw_if_index <id>]"                                        \
20709   "[weight <n>] [del] [multipath]")                                     \
20710 _(sw_interface_set_unnumbered,                                          \
20711   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20712 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20713 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20714   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20715   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20716   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20717 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20718 _(ip_table_flush, "table <n> [ipv6]")                                   \
20719 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20720 _(set_ip_flow_hash,                                                     \
20721   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20722 _(sw_interface_ip6_enable_disable,                                      \
20723   "<intfc> | sw_if_index <id> enable | disable")                        \
20724 _(l2_patch_add_del,                                                     \
20725   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20726   "enable | disable")                                                   \
20727 _(sr_localsid_add_del,                                                  \
20728   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20729   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20730 _(classify_add_del_table,                                               \
20731   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20732   " [del] [del-chain] mask <mask-value>\n"                              \
20733   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20734   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20735 _(classify_add_del_session,                                             \
20736   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20737   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20738   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20739   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20740 _(classify_set_interface_ip_table,                                      \
20741   "<intfc> | sw_if_index <nn> table <nn>")                              \
20742 _(classify_set_interface_l2_tables,                                     \
20743   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20744   "  [other-table <nn>]")                                               \
20745 _(get_node_index, "node <node-name")                                    \
20746 _(add_node_next, "node <node-name> next <next-node-name>")              \
20747 _(l2tpv3_create_tunnel,                                                 \
20748   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20749   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20750   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20751 _(l2tpv3_set_tunnel_cookies,                                            \
20752   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20753   "[new_remote_cookie <nn>]\n")                                         \
20754 _(l2tpv3_interface_enable_disable,                                      \
20755   "<intfc> | sw_if_index <nn> enable | disable")                        \
20756 _(l2tpv3_set_lookup_key,                                                \
20757   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20758 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20759 _(vxlan_offload_rx,                                                     \
20760   "hw { <interface name> | hw_if_index <nn>} "                          \
20761   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20762 _(vxlan_add_del_tunnel,                                                 \
20763   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20764   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20765   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20766 _(geneve_add_del_tunnel,                                                \
20767   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20768   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20769   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20770 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20771 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20772 _(gre_tunnel_add_del,                                                   \
20773   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20774   "[teb | erspan <session-id>] [del]")                                  \
20775 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20776 _(l2_fib_clear_table, "")                                               \
20777 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20778 _(l2_interface_vlan_tag_rewrite,                                        \
20779   "<intfc> | sw_if_index <nn> \n"                                       \
20780   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20781   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20782 _(create_vhost_user_if,                                                 \
20783         "socket <filename> [server] [renumber <dev_instance>] "         \
20784         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20785         "[mac <mac_address>]")                                          \
20786 _(modify_vhost_user_if,                                                 \
20787         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20788         "[server] [renumber <dev_instance>] [gso]")                     \
20789 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20790 _(sw_interface_vhost_user_dump, "")                                     \
20791 _(show_version, "")                                                     \
20792 _(show_threads, "")                                                     \
20793 _(vxlan_gpe_add_del_tunnel,                                             \
20794   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20795   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20796   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20797   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20798 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20799 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20800 _(interface_name_renumber,                                              \
20801   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20802 _(input_acl_set_interface,                                              \
20803   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20804   "  [l2-table <nn>] [del]")                                            \
20805 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20806 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20807 _(ip_dump, "ipv4 | ipv6")                                               \
20808 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20809 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20810   "  spid_id <n> ")                                                     \
20811 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20812   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20813   "  integ_alg <alg> integ_key <hex>")                                  \
20814 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20815   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20816   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20817   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20818 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20819   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20820   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20821   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20822   "  [instance <n>]")     \
20823 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20824 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20825 _(delete_loopback,"sw_if_index <nn>")                                   \
20826 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20827 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20828 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20829 _(want_interface_events,  "enable|disable")                             \
20830 _(get_first_msg_id, "client <name>")                                    \
20831 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20832 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20833   "fib-id <nn> [ip4][ip6][default]")                                    \
20834 _(get_node_graph, " ")                                                  \
20835 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20836 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20837 _(ioam_disable, "")                                                     \
20838 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20839                             " sw_if_index <sw_if_index> p <priority> "  \
20840                             "w <weight>] [del]")                        \
20841 _(one_add_del_locator, "locator-set <locator_name> "                    \
20842                         "iface <intf> | sw_if_index <sw_if_index> "     \
20843                         "p <priority> w <weight> [del]")                \
20844 _(one_add_del_local_eid,"vni <vni> eid "                                \
20845                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20846                          "locator-set <locator_name> [del]"             \
20847                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20848 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20849 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20850 _(one_enable_disable, "enable|disable")                                 \
20851 _(one_map_register_enable_disable, "enable|disable")                    \
20852 _(one_map_register_fallback_threshold, "<value>")                       \
20853 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20854 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20855                                "[seid <seid>] "                         \
20856                                "rloc <locator> p <prio> "               \
20857                                "w <weight> [rloc <loc> ... ] "          \
20858                                "action <action> [del-all]")             \
20859 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20860                           "<local-eid>")                                \
20861 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20862 _(one_use_petr, "ip-address> | disable")                                \
20863 _(one_map_request_mode, "src-dst|dst-only")                             \
20864 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20865 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20866 _(one_locator_set_dump, "[local | remote]")                             \
20867 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20868 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20869                        "[local] | [remote]")                            \
20870 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20871 _(one_ndp_bd_get, "")                                                   \
20872 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20873 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20874 _(one_l2_arp_bd_get, "")                                                \
20875 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20876 _(one_stats_enable_disable, "enable|disable")                           \
20877 _(show_one_stats_enable_disable, "")                                    \
20878 _(one_eid_table_vni_dump, "")                                           \
20879 _(one_eid_table_map_dump, "l2|l3")                                      \
20880 _(one_map_resolver_dump, "")                                            \
20881 _(one_map_server_dump, "")                                              \
20882 _(one_adjacencies_get, "vni <vni>")                                     \
20883 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20884 _(show_one_rloc_probe_state, "")                                        \
20885 _(show_one_map_register_state, "")                                      \
20886 _(show_one_status, "")                                                  \
20887 _(one_stats_dump, "")                                                   \
20888 _(one_stats_flush, "")                                                  \
20889 _(one_get_map_request_itr_rlocs, "")                                    \
20890 _(one_map_register_set_ttl, "<ttl>")                                    \
20891 _(one_set_transport_protocol, "udp|api")                                \
20892 _(one_get_transport_protocol, "")                                       \
20893 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20894 _(one_show_xtr_mode, "")                                                \
20895 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20896 _(one_show_pitr_mode, "")                                               \
20897 _(one_enable_disable_petr_mode, "enable|disable")                       \
20898 _(one_show_petr_mode, "")                                               \
20899 _(show_one_nsh_mapping, "")                                             \
20900 _(show_one_pitr, "")                                                    \
20901 _(show_one_use_petr, "")                                                \
20902 _(show_one_map_request_mode, "")                                        \
20903 _(show_one_map_register_ttl, "")                                        \
20904 _(show_one_map_register_fallback_threshold, "")                         \
20905 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20906                             " sw_if_index <sw_if_index> p <priority> "  \
20907                             "w <weight>] [del]")                        \
20908 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20909                         "iface <intf> | sw_if_index <sw_if_index> "     \
20910                         "p <priority> w <weight> [del]")                \
20911 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20912                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20913                          "locator-set <locator_name> [del]"             \
20914                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20915 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20916 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20917 _(lisp_enable_disable, "enable|disable")                                \
20918 _(lisp_map_register_enable_disable, "enable|disable")                   \
20919 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20920 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20921                                "[seid <seid>] "                         \
20922                                "rloc <locator> p <prio> "               \
20923                                "w <weight> [rloc <loc> ... ] "          \
20924                                "action <action> [del-all]")             \
20925 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20926                           "<local-eid>")                                \
20927 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20928 _(lisp_use_petr, "<ip-address> | disable")                              \
20929 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20930 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20931 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20932 _(lisp_locator_set_dump, "[local | remote]")                            \
20933 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20934 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20935                        "[local] | [remote]")                            \
20936 _(lisp_eid_table_vni_dump, "")                                          \
20937 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20938 _(lisp_map_resolver_dump, "")                                           \
20939 _(lisp_map_server_dump, "")                                             \
20940 _(lisp_adjacencies_get, "vni <vni>")                                    \
20941 _(gpe_fwd_entry_vnis_get, "")                                           \
20942 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20943 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20944                                 "[table <table-id>]")                   \
20945 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20946 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20947 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20948 _(gpe_get_encap_mode, "")                                               \
20949 _(lisp_gpe_add_del_iface, "up|down")                                    \
20950 _(lisp_gpe_enable_disable, "enable|disable")                            \
20951 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20952   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20953 _(show_lisp_rloc_probe_state, "")                                       \
20954 _(show_lisp_map_register_state, "")                                     \
20955 _(show_lisp_status, "")                                                 \
20956 _(lisp_get_map_request_itr_rlocs, "")                                   \
20957 _(show_lisp_pitr, "")                                                   \
20958 _(show_lisp_use_petr, "")                                               \
20959 _(show_lisp_map_request_mode, "")                                       \
20960 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20961 _(af_packet_delete, "name <host interface name>")                       \
20962 _(af_packet_dump, "")                                                   \
20963 _(policer_add_del, "name <policer name> <params> [del]")                \
20964 _(policer_dump, "[name <policer name>]")                                \
20965 _(policer_classify_set_interface,                                       \
20966   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20967   "  [l2-table <nn>] [del]")                                            \
20968 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20969 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20970 _(mpls_table_dump, "")                                                  \
20971 _(mpls_route_dump, "table-id <ID>")                                     \
20972 _(classify_table_ids, "")                                               \
20973 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20974 _(classify_table_info, "table_id <nn>")                                 \
20975 _(classify_session_dump, "table_id <nn>")                               \
20976 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20977     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20978     "[template_interval <nn>] [udp_checksum]")                          \
20979 _(ipfix_exporter_dump, "")                                              \
20980 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20981 _(ipfix_classify_stream_dump, "")                                       \
20982 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20983 _(ipfix_classify_table_dump, "")                                        \
20984 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20985 _(sw_interface_span_dump, "[l2]")                                           \
20986 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20987 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20988 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20989 _(pg_enable_disable, "[stream <id>] disable")                           \
20990 _(ip_source_and_port_range_check_add_del,                               \
20991   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20992 _(ip_source_and_port_range_check_interface_add_del,                     \
20993   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20994   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20995 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20996 _(l2_interface_pbb_tag_rewrite,                                         \
20997   "<intfc> | sw_if_index <nn> \n"                                       \
20998   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20999   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21000 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21001 _(flow_classify_set_interface,                                          \
21002   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21003 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21004 _(ip_table_dump, "")                                                    \
21005 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21006 _(ip_mtable_dump, "")                                                   \
21007 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21008 _(feature_enable_disable, "arc_name <arc_name> "                        \
21009   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21010 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21011   "[enable | disable] ")                                                \
21012 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21013 "[disable]")                                                            \
21014 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21015   "mac <mac-address> [del]")                                            \
21016 _(l2_xconnect_dump, "")                                                 \
21017 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21018 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21019 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21020 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21021 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21022 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21023   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21024 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21025 _(sock_init_shm, "size <nnn>")                                          \
21026 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21027 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21028   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21029 _(session_rules_dump, "")                                               \
21030 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21031 _(output_acl_set_interface,                                             \
21032   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21033   "  [l2-table <nn>] [del]")                                            \
21034 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21035
21036 /* List of command functions, CLI names map directly to functions */
21037 #define foreach_cli_function                                    \
21038 _(comment, "usage: comment <ignore-rest-of-line>")              \
21039 _(dump_interface_table, "usage: dump_interface_table")          \
21040 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21041 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21042 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21043 _(dump_macro_table, "usage: dump_macro_table ")                 \
21044 _(dump_node_table, "usage: dump_node_table")                    \
21045 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21046 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21047 _(elog_disable, "usage: elog_disable")                          \
21048 _(elog_enable, "usage: elog_enable")                            \
21049 _(elog_save, "usage: elog_save <filename>")                     \
21050 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21051 _(echo, "usage: echo <message>")                                \
21052 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21053 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21054 _(help, "usage: help")                                          \
21055 _(q, "usage: quit")                                             \
21056 _(quit, "usage: quit")                                          \
21057 _(search_node_table, "usage: search_node_table <name>...")      \
21058 _(set, "usage: set <variable-name> <value>")                    \
21059 _(script, "usage: script <file-name>")                          \
21060 _(statseg, "usage: statseg")                                    \
21061 _(unset, "usage: unset <variable-name>")
21062
21063 #define _(N,n)                                  \
21064     static void vl_api_##n##_t_handler_uni      \
21065     (vl_api_##n##_t * mp)                       \
21066     {                                           \
21067         vat_main_t * vam = &vat_main;           \
21068         if (vam->json_output) {                 \
21069             vl_api_##n##_t_handler_json(mp);    \
21070         } else {                                \
21071             vl_api_##n##_t_handler(mp);         \
21072         }                                       \
21073     }
21074 foreach_vpe_api_reply_msg;
21075 #if VPP_API_TEST_BUILTIN == 0
21076 foreach_standalone_reply_msg;
21077 #endif
21078 #undef _
21079
21080 void
21081 vat_api_hookup (vat_main_t * vam)
21082 {
21083 #define _(N,n)                                                  \
21084     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21085                            vl_api_##n##_t_handler_uni,          \
21086                            vl_noop_handler,                     \
21087                            vl_api_##n##_t_endian,               \
21088                            vl_api_##n##_t_print,                \
21089                            sizeof(vl_api_##n##_t), 1);
21090   foreach_vpe_api_reply_msg;
21091 #if VPP_API_TEST_BUILTIN == 0
21092   foreach_standalone_reply_msg;
21093 #endif
21094 #undef _
21095
21096 #if (VPP_API_TEST_BUILTIN==0)
21097   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21098
21099   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21100
21101   vam->function_by_name = hash_create_string (0, sizeof (uword));
21102
21103   vam->help_by_name = hash_create_string (0, sizeof (uword));
21104 #endif
21105
21106   /* API messages we can send */
21107 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21108   foreach_vpe_api_msg;
21109 #undef _
21110
21111   /* Help strings */
21112 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21113   foreach_vpe_api_msg;
21114 #undef _
21115
21116   /* CLI functions */
21117 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21118   foreach_cli_function;
21119 #undef _
21120
21121   /* Help strings */
21122 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21123   foreach_cli_function;
21124 #undef _
21125 }
21126
21127 #if VPP_API_TEST_BUILTIN
21128 static clib_error_t *
21129 vat_api_hookup_shim (vlib_main_t * vm)
21130 {
21131   vat_api_hookup (&vat_main);
21132   return 0;
21133 }
21134
21135 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21136 #endif
21137
21138 /*
21139  * fd.io coding-style-patch-verification: ON
21140  *
21141  * Local Variables:
21142  * eval: (c-set-style "gnu")
21143  * End:
21144  */