vxlan: vxlan/vxlan.api API cleanup
[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   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP46 address. */
268 uword
269 unformat_ip46_address (unformat_input_t * input, va_list * args)
270 {
271   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
272   ip46_type_t type = va_arg (*args, ip46_type_t);
273   if ((type != IP46_TYPE_IP6) &&
274       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
275     {
276       ip46_address_mask_ip4 (ip46);
277       return 1;
278     }
279   else if ((type != IP46_TYPE_IP4) &&
280            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
281     {
282       return 1;
283     }
284   return 0;
285 }
286
287 /* Parse an IP6 address. */
288 uword
289 unformat_ip6_address (unformat_input_t * input, va_list * args)
290 {
291   ip6_address_t *result = va_arg (*args, ip6_address_t *);
292   u16 hex_quads[8];
293   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
294   uword c, n_colon, double_colon_index;
295
296   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
297   double_colon_index = ARRAY_LEN (hex_quads);
298   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
299     {
300       hex_digit = 16;
301       if (c >= '0' && c <= '9')
302         hex_digit = c - '0';
303       else if (c >= 'a' && c <= 'f')
304         hex_digit = c + 10 - 'a';
305       else if (c >= 'A' && c <= 'F')
306         hex_digit = c + 10 - 'A';
307       else if (c == ':' && n_colon < 2)
308         n_colon++;
309       else
310         {
311           unformat_put_input (input);
312           break;
313         }
314
315       /* Too many hex quads. */
316       if (n_hex_quads >= ARRAY_LEN (hex_quads))
317         return 0;
318
319       if (hex_digit < 16)
320         {
321           hex_quad = (hex_quad << 4) | hex_digit;
322
323           /* Hex quad must fit in 16 bits. */
324           if (n_hex_digits >= 4)
325             return 0;
326
327           n_colon = 0;
328           n_hex_digits++;
329         }
330
331       /* Save position of :: */
332       if (n_colon == 2)
333         {
334           /* More than one :: ? */
335           if (double_colon_index < ARRAY_LEN (hex_quads))
336             return 0;
337           double_colon_index = n_hex_quads;
338         }
339
340       if (n_colon > 0 && n_hex_digits > 0)
341         {
342           hex_quads[n_hex_quads++] = hex_quad;
343           hex_quad = 0;
344           n_hex_digits = 0;
345         }
346     }
347
348   if (n_hex_digits > 0)
349     hex_quads[n_hex_quads++] = hex_quad;
350
351   {
352     word i;
353
354     /* Expand :: to appropriate number of zero hex quads. */
355     if (double_colon_index < ARRAY_LEN (hex_quads))
356       {
357         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
358
359         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
360           hex_quads[n_zero + i] = hex_quads[i];
361
362         for (i = 0; i < n_zero; i++)
363           hex_quads[double_colon_index + i] = 0;
364
365         n_hex_quads = ARRAY_LEN (hex_quads);
366       }
367
368     /* Too few hex quads given. */
369     if (n_hex_quads < ARRAY_LEN (hex_quads))
370       return 0;
371
372     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
373       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
374
375     return 1;
376   }
377 }
378
379 uword
380 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
381 {
382   u32 *r = va_arg (*args, u32 *);
383
384   if (0);
385 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
386   foreach_ipsec_policy_action
387 #undef _
388     else
389     return 0;
390   return 1;
391 }
392
393 u8 *
394 format_ipsec_crypto_alg (u8 * s, va_list * args)
395 {
396   u32 i = va_arg (*args, u32);
397   u8 *t = 0;
398
399   switch (i)
400     {
401 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
402       foreach_ipsec_crypto_alg
403 #undef _
404     default:
405       return format (s, "unknown");
406     }
407   return format (s, "%s", t);
408 }
409
410 u8 *
411 format_ipsec_integ_alg (u8 * s, va_list * args)
412 {
413   u32 i = va_arg (*args, u32);
414   u8 *t = 0;
415
416   switch (i)
417     {
418 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
419       foreach_ipsec_integ_alg
420 #undef _
421     default:
422       return format (s, "unknown");
423     }
424   return format (s, "%s", t);
425 }
426
427 #else /* VPP_API_TEST_BUILTIN == 1 */
428 static uword
429 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
430 {
431   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
432   vnet_main_t *vnm = vnet_get_main ();
433   u32 *result = va_arg (*args, u32 *);
434
435   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
436 }
437
438 static uword
439 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
440 {
441   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
442   vnet_main_t *vnm = vnet_get_main ();
443   u32 *result = va_arg (*args, u32 *);
444
445   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
446 }
447
448 #endif /* VPP_API_TEST_BUILTIN */
449
450 uword
451 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
452 {
453   u32 *r = va_arg (*args, u32 *);
454
455   if (0);
456 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
457   foreach_ipsec_crypto_alg
458 #undef _
459     else
460     return 0;
461   return 1;
462 }
463
464 uword
465 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
466 {
467   u32 *r = va_arg (*args, u32 *);
468
469   if (0);
470 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
471   foreach_ipsec_integ_alg
472 #undef _
473     else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "kbps"))
484     *r = SSE2_QOS_RATE_KBPS;
485   else if (unformat (input, "pps"))
486     *r = SSE2_QOS_RATE_PPS;
487   else
488     return 0;
489   return 1;
490 }
491
492 static uword
493 unformat_policer_round_type (unformat_input_t * input, va_list * args)
494 {
495   u8 *r = va_arg (*args, u8 *);
496
497   if (unformat (input, "closest"))
498     *r = SSE2_QOS_ROUND_TO_CLOSEST;
499   else if (unformat (input, "up"))
500     *r = SSE2_QOS_ROUND_TO_UP;
501   else if (unformat (input, "down"))
502     *r = SSE2_QOS_ROUND_TO_DOWN;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_policer_type (unformat_input_t * input, va_list * args)
510 {
511   u8 *r = va_arg (*args, u8 *);
512
513   if (unformat (input, "1r2c"))
514     *r = SSE2_QOS_POLICER_TYPE_1R2C;
515   else if (unformat (input, "1r3c"))
516     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
517   else if (unformat (input, "2r3c-2698"))
518     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
519   else if (unformat (input, "2r3c-4115"))
520     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
521   else if (unformat (input, "2r3c-mef5cf1"))
522     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
523   else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_dscp (unformat_input_t * input, va_list * va)
530 {
531   u8 *r = va_arg (*va, u8 *);
532
533   if (0);
534 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
535   foreach_vnet_dscp
536 #undef _
537     else
538     return 0;
539   return 1;
540 }
541
542 static uword
543 unformat_policer_action_type (unformat_input_t * input, va_list * va)
544 {
545   sse2_qos_pol_action_params_st *a
546     = va_arg (*va, sse2_qos_pol_action_params_st *);
547
548   if (unformat (input, "drop"))
549     a->action_type = SSE2_QOS_ACTION_DROP;
550   else if (unformat (input, "transmit"))
551     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
552   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
553     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
554   else
555     return 0;
556   return 1;
557 }
558
559 static uword
560 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
561 {
562   u32 *r = va_arg (*va, u32 *);
563   u32 tid;
564
565   if (unformat (input, "ip4"))
566     tid = POLICER_CLASSIFY_TABLE_IP4;
567   else if (unformat (input, "ip6"))
568     tid = POLICER_CLASSIFY_TABLE_IP6;
569   else if (unformat (input, "l2"))
570     tid = POLICER_CLASSIFY_TABLE_L2;
571   else
572     return 0;
573
574   *r = tid;
575   return 1;
576 }
577
578 static uword
579 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
580 {
581   u32 *r = va_arg (*va, u32 *);
582   u32 tid;
583
584   if (unformat (input, "ip4"))
585     tid = FLOW_CLASSIFY_TABLE_IP4;
586   else if (unformat (input, "ip6"))
587     tid = FLOW_CLASSIFY_TABLE_IP6;
588   else
589     return 0;
590
591   *r = tid;
592   return 1;
593 }
594
595 #if (VPP_API_TEST_BUILTIN==0)
596
597 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
598 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
599 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
600 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
601
602 uword
603 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
604 {
605   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
606   mfib_itf_attribute_t attr;
607
608   old = *iflags;
609   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_itf_flag_long_names[attr]))
612       *iflags |= (1 << attr);
613   }
614   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
615   {
616     if (unformat (input, mfib_itf_flag_names[attr]))
617       *iflags |= (1 << attr);
618   }
619
620   return (old == *iflags ? 0 : 1);
621 }
622
623 uword
624 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
625 {
626   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
627   mfib_entry_attribute_t attr;
628
629   old = *eflags;
630   FOR_EACH_MFIB_ATTRIBUTE (attr)
631   {
632     if (unformat (input, mfib_flag_long_names[attr]))
633       *eflags |= (1 << attr);
634   }
635   FOR_EACH_MFIB_ATTRIBUTE (attr)
636   {
637     if (unformat (input, mfib_flag_names[attr]))
638       *eflags |= (1 << attr);
639   }
640
641   return (old == *eflags ? 0 : 1);
642 }
643
644 u8 *
645 format_ip4_address (u8 * s, va_list * args)
646 {
647   u8 *a = va_arg (*args, u8 *);
648   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
649 }
650
651 u8 *
652 format_ip6_address (u8 * s, va_list * args)
653 {
654   ip6_address_t *a = va_arg (*args, ip6_address_t *);
655   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
656
657   i_max_n_zero = ARRAY_LEN (a->as_u16);
658   max_n_zeros = 0;
659   i_first_zero = i_max_n_zero;
660   n_zeros = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       u32 is_zero = a->as_u16[i] == 0;
664       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
665         {
666           i_first_zero = i;
667           n_zeros = 0;
668         }
669       n_zeros += is_zero;
670       if ((!is_zero && n_zeros > max_n_zeros)
671           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
672         {
673           i_max_n_zero = i_first_zero;
674           max_n_zeros = n_zeros;
675           i_first_zero = ARRAY_LEN (a->as_u16);
676           n_zeros = 0;
677         }
678     }
679
680   last_double_colon = 0;
681   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
682     {
683       if (i == i_max_n_zero && max_n_zeros > 1)
684         {
685           s = format (s, "::");
686           i += max_n_zeros - 1;
687           last_double_colon = 1;
688         }
689       else
690         {
691           s = format (s, "%s%x",
692                       (last_double_colon || i == 0) ? "" : ":",
693                       clib_net_to_host_u16 (a->as_u16[i]));
694           last_double_colon = 0;
695         }
696     }
697
698   return s;
699 }
700
701 /* Format an IP46 address. */
702 u8 *
703 format_ip46_address (u8 * s, va_list * args)
704 {
705   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
706   ip46_type_t type = va_arg (*args, ip46_type_t);
707   int is_ip4 = 1;
708
709   switch (type)
710     {
711     case IP46_TYPE_ANY:
712       is_ip4 = ip46_address_is_ip4 (ip46);
713       break;
714     case IP46_TYPE_IP4:
715       is_ip4 = 1;
716       break;
717     case IP46_TYPE_IP6:
718       is_ip4 = 0;
719       break;
720     }
721
722   return is_ip4 ?
723     format (s, "%U", format_ip4_address, &ip46->ip4) :
724     format (s, "%U", format_ip6_address, &ip46->ip6);
725 }
726
727 u8 *
728 format_ethernet_address (u8 * s, va_list * args)
729 {
730   u8 *a = va_arg (*args, u8 *);
731
732   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
733                  a[0], a[1], a[2], a[3], a[4], a[5]);
734 }
735 #endif
736
737 static void
738 increment_v4_address (vl_api_ip4_address_t * i)
739 {
740   ip4_address_t *a = (ip4_address_t *) i;
741   u32 v;
742
743   v = ntohl (a->as_u32) + 1;
744   a->as_u32 = ntohl (v);
745 }
746
747 static void
748 increment_v6_address (vl_api_ip6_address_t * i)
749 {
750   ip6_address_t *a = (ip6_address_t *) i;
751   u64 v0, v1;
752
753   v0 = clib_net_to_host_u64 (a->as_u64[0]);
754   v1 = clib_net_to_host_u64 (a->as_u64[1]);
755
756   v1 += 1;
757   if (v1 == 0)
758     v0 += 1;
759   a->as_u64[0] = clib_net_to_host_u64 (v0);
760   a->as_u64[1] = clib_net_to_host_u64 (v1);
761 }
762
763 static void
764 increment_address (vl_api_address_t * a)
765 {
766   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
767     increment_v4_address (&a->un.ip4);
768   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
769     increment_v6_address (&a->un.ip6);
770 }
771
772 static void
773 set_ip4_address (vl_api_address_t * a, u32 v)
774 {
775   if (a->af == ADDRESS_IP4)
776     {
777       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
778       i->as_u32 = v;
779     }
780 }
781
782 void
783 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
784 {
785   if (is_ip4)
786     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
787   else
788     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
789                       sizeof (ip6_address_t));
790 }
791
792 static void
793 increment_mac_address (u8 * mac)
794 {
795   u64 tmp = *((u64 *) mac);
796   tmp = clib_net_to_host_u64 (tmp);
797   tmp += 1 << 16;               /* skip unused (least significant) octets */
798   tmp = clib_host_to_net_u64 (tmp);
799
800   clib_memcpy (mac, &tmp, 6);
801 }
802
803 static void
804 vat_json_object_add_address (vat_json_node_t * node,
805                              const char *str, const vl_api_address_t * addr)
806 {
807   if (ADDRESS_IP6 == addr->af)
808     {
809       struct in6_addr ip6;
810
811       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
812       vat_json_object_add_ip6 (node, str, ip6);
813     }
814   else
815     {
816       struct in_addr ip4;
817
818       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
819       vat_json_object_add_ip4 (node, str, ip4);
820     }
821 }
822
823 static void
824 vat_json_object_add_prefix (vat_json_node_t * node,
825                             const vl_api_prefix_t * prefix)
826 {
827   vat_json_object_add_uint (node, "len", prefix->len);
828   vat_json_object_add_address (node, "address", &prefix->address);
829 }
830
831 static void vl_api_create_loopback_reply_t_handler
832   (vl_api_create_loopback_reply_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   i32 retval = ntohl (mp->retval);
836
837   vam->retval = retval;
838   vam->regenerate_interface_table = 1;
839   vam->sw_if_index = ntohl (mp->sw_if_index);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_create_loopback_reply_t_handler_json
844   (vl_api_create_loopback_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   vat_json_node_t node;
848
849   vat_json_init_object (&node);
850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
851   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
852
853   vat_json_print (vam->ofp, &node);
854   vat_json_free (&node);
855   vam->retval = ntohl (mp->retval);
856   vam->result_ready = 1;
857 }
858
859 static void vl_api_create_loopback_instance_reply_t_handler
860   (vl_api_create_loopback_instance_reply_t * mp)
861 {
862   vat_main_t *vam = &vat_main;
863   i32 retval = ntohl (mp->retval);
864
865   vam->retval = retval;
866   vam->regenerate_interface_table = 1;
867   vam->sw_if_index = ntohl (mp->sw_if_index);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_loopback_instance_reply_t_handler_json
872   (vl_api_create_loopback_instance_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   vat_json_node_t node;
876
877   vat_json_init_object (&node);
878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
879   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
880
881   vat_json_print (vam->ofp, &node);
882   vat_json_free (&node);
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_af_packet_create_reply_t_handler
888   (vl_api_af_packet_create_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->sw_if_index = ntohl (mp->sw_if_index);
896   vam->result_ready = 1;
897 }
898
899 static void vl_api_af_packet_create_reply_t_handler_json
900   (vl_api_af_packet_create_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904
905   vat_json_init_object (&node);
906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 static void vl_api_create_vlan_subif_reply_t_handler
917   (vl_api_create_vlan_subif_reply_t * mp)
918 {
919   vat_main_t *vam = &vat_main;
920   i32 retval = ntohl (mp->retval);
921
922   vam->retval = retval;
923   vam->regenerate_interface_table = 1;
924   vam->sw_if_index = ntohl (mp->sw_if_index);
925   vam->result_ready = 1;
926 }
927
928 static void vl_api_create_vlan_subif_reply_t_handler_json
929   (vl_api_create_vlan_subif_reply_t * mp)
930 {
931   vat_main_t *vam = &vat_main;
932   vat_json_node_t node;
933
934   vat_json_init_object (&node);
935   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
936   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_create_subif_reply_t_handler
946   (vl_api_create_subif_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950
951   vam->retval = retval;
952   vam->regenerate_interface_table = 1;
953   vam->sw_if_index = ntohl (mp->sw_if_index);
954   vam->result_ready = 1;
955 }
956
957 static void vl_api_create_subif_reply_t_handler_json
958   (vl_api_create_subif_reply_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   vat_json_node_t node;
962
963   vat_json_init_object (&node);
964   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
965   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
966
967   vat_json_print (vam->ofp, &node);
968   vat_json_free (&node);
969
970   vam->retval = ntohl (mp->retval);
971   vam->result_ready = 1;
972 }
973
974 static void vl_api_interface_name_renumber_reply_t_handler
975   (vl_api_interface_name_renumber_reply_t * mp)
976 {
977   vat_main_t *vam = &vat_main;
978   i32 retval = ntohl (mp->retval);
979
980   vam->retval = retval;
981   vam->regenerate_interface_table = 1;
982   vam->result_ready = 1;
983 }
984
985 static void vl_api_interface_name_renumber_reply_t_handler_json
986   (vl_api_interface_name_renumber_reply_t * mp)
987 {
988   vat_main_t *vam = &vat_main;
989   vat_json_node_t node;
990
991   vat_json_init_object (&node);
992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
993
994   vat_json_print (vam->ofp, &node);
995   vat_json_free (&node);
996
997   vam->retval = ntohl (mp->retval);
998   vam->result_ready = 1;
999 }
1000
1001 /*
1002  * Special-case: build the interface table, maintain
1003  * the next loopback sw_if_index vbl.
1004  */
1005 static void vl_api_sw_interface_details_t_handler
1006   (vl_api_sw_interface_details_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1010
1011   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1012                 ntohl (mp->sw_if_index));
1013
1014   /* In sub interface case, fill the sub interface table entry */
1015   if (mp->sw_if_index != mp->sup_sw_if_index)
1016     {
1017       sw_interface_subif_t *sub = NULL;
1018
1019       vec_add2 (vam->sw_if_subif_table, sub, 1);
1020
1021       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1022       strncpy ((char *) sub->interface_name, (char *) s,
1023                vec_len (sub->interface_name));
1024       sub->sw_if_index = ntohl (mp->sw_if_index);
1025       sub->sub_id = ntohl (mp->sub_id);
1026
1027       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1028
1029       sub->sub_number_of_tags = mp->sub_number_of_tags;
1030       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1031       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1032
1033       /* vlan tag rewrite */
1034       sub->vtr_op = ntohl (mp->vtr_op);
1035       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1036       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1037       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1038     }
1039 }
1040
1041 static void vl_api_sw_interface_details_t_handler_json
1042   (vl_api_sw_interface_details_t * mp)
1043 {
1044   vat_main_t *vam = &vat_main;
1045   vat_json_node_t *node = NULL;
1046
1047   if (VAT_JSON_ARRAY != vam->json_tree.type)
1048     {
1049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1050       vat_json_init_array (&vam->json_tree);
1051     }
1052   node = vat_json_array_add (&vam->json_tree);
1053
1054   vat_json_init_object (node);
1055   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1056   vat_json_object_add_uint (node, "sup_sw_if_index",
1057                             ntohl (mp->sup_sw_if_index));
1058   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1059                              sizeof (mp->l2_address));
1060   vat_json_object_add_string_copy (node, "interface_name",
1061                                    mp->interface_name);
1062   vat_json_object_add_string_copy (node, "interface_dev_type",
1063                                    mp->interface_dev_type);
1064   vat_json_object_add_uint (node, "flags", mp->flags);
1065   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1066   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1067   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1068   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1069   vat_json_object_add_uint (node, "sub_number_of_tags",
1070                             mp->sub_number_of_tags);
1071   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1072                             ntohs (mp->sub_outer_vlan_id));
1073   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1074                             ntohs (mp->sub_inner_vlan_id));
1075   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1076   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1077   vat_json_object_add_uint (node, "vtr_push_dot1q",
1078                             ntohl (mp->vtr_push_dot1q));
1079   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1080   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1081   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1082     {
1083       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1084                                        format (0, "%U",
1085                                                format_ethernet_address,
1086                                                &mp->b_dmac));
1087       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1088                                        format (0, "%U",
1089                                                format_ethernet_address,
1090                                                &mp->b_smac));
1091       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1092       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1093     }
1094 }
1095
1096 #if VPP_API_TEST_BUILTIN == 0
1097 static void vl_api_sw_interface_event_t_handler
1098   (vl_api_sw_interface_event_t * mp)
1099 {
1100   vat_main_t *vam = &vat_main;
1101   if (vam->interface_event_display)
1102     errmsg ("interface flags: sw_if_index %d %s %s",
1103             ntohl (mp->sw_if_index),
1104             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1105             "admin-up" : "admin-down",
1106             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1107             "link-up" : "link-down");
1108 }
1109 #endif
1110
1111 __clib_unused static void
1112 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1113 {
1114   /* JSON output not supported */
1115 }
1116
1117 static void
1118 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122
1123   vam->retval = retval;
1124   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1125   vam->result_ready = 1;
1126 }
1127
1128 static void
1129 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1130 {
1131   vat_main_t *vam = &vat_main;
1132   vat_json_node_t node;
1133   void *oldheap;
1134   u8 *reply;
1135
1136   vat_json_init_object (&node);
1137   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1138   vat_json_object_add_uint (&node, "reply_in_shmem",
1139                             ntohl (mp->reply_in_shmem));
1140   /* Toss the shared-memory original... */
1141   oldheap = vl_msg_push_heap ();
1142
1143   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1144   vec_free (reply);
1145
1146   vl_msg_pop_heap (oldheap);
1147
1148   vat_json_print (vam->ofp, &node);
1149   vat_json_free (&node);
1150
1151   vam->retval = ntohl (mp->retval);
1152   vam->result_ready = 1;
1153 }
1154
1155 static void
1156 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1157 {
1158   vat_main_t *vam = &vat_main;
1159   i32 retval = ntohl (mp->retval);
1160
1161   vec_reset_length (vam->cmd_reply);
1162
1163   vam->retval = retval;
1164   if (retval == 0)
1165     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1166   vam->result_ready = 1;
1167 }
1168
1169 static void
1170 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174   u8 *reply = 0;                /* reply vector */
1175
1176   reply = vl_api_from_api_to_new_vec (&mp->reply);
1177   vec_reset_length (vam->cmd_reply);
1178
1179   vat_json_init_object (&node);
1180   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1181   vat_json_object_add_string_copy (&node, "reply", reply);
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185   vec_free (reply);
1186
1187   vam->retval = ntohl (mp->retval);
1188   vam->result_ready = 1;
1189 }
1190
1191 static void vl_api_classify_add_del_table_reply_t_handler
1192   (vl_api_classify_add_del_table_reply_t * mp)
1193 {
1194   vat_main_t *vam = &vat_main;
1195   i32 retval = ntohl (mp->retval);
1196   if (vam->async_mode)
1197     {
1198       vam->async_errors += (retval < 0);
1199     }
1200   else
1201     {
1202       vam->retval = retval;
1203       if (retval == 0 &&
1204           ((mp->new_table_index != 0xFFFFFFFF) ||
1205            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1206            (mp->match_n_vectors != 0xFFFFFFFF)))
1207         /*
1208          * Note: this is just barely thread-safe, depends on
1209          * the main thread spinning waiting for an answer...
1210          */
1211         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1212                 ntohl (mp->new_table_index),
1213                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1214       vam->result_ready = 1;
1215     }
1216 }
1217
1218 static void vl_api_classify_add_del_table_reply_t_handler_json
1219   (vl_api_classify_add_del_table_reply_t * mp)
1220 {
1221   vat_main_t *vam = &vat_main;
1222   vat_json_node_t node;
1223
1224   vat_json_init_object (&node);
1225   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1226   vat_json_object_add_uint (&node, "new_table_index",
1227                             ntohl (mp->new_table_index));
1228   vat_json_object_add_uint (&node, "skip_n_vectors",
1229                             ntohl (mp->skip_n_vectors));
1230   vat_json_object_add_uint (&node, "match_n_vectors",
1231                             ntohl (mp->match_n_vectors));
1232
1233   vat_json_print (vam->ofp, &node);
1234   vat_json_free (&node);
1235
1236   vam->retval = ntohl (mp->retval);
1237   vam->result_ready = 1;
1238 }
1239
1240 static void vl_api_get_node_index_reply_t_handler
1241   (vl_api_get_node_index_reply_t * mp)
1242 {
1243   vat_main_t *vam = &vat_main;
1244   i32 retval = ntohl (mp->retval);
1245   if (vam->async_mode)
1246     {
1247       vam->async_errors += (retval < 0);
1248     }
1249   else
1250     {
1251       vam->retval = retval;
1252       if (retval == 0)
1253         errmsg ("node index %d", ntohl (mp->node_index));
1254       vam->result_ready = 1;
1255     }
1256 }
1257
1258 static void vl_api_get_node_index_reply_t_handler_json
1259   (vl_api_get_node_index_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   vat_json_node_t node;
1263
1264   vat_json_init_object (&node);
1265   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1266   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1267
1268   vat_json_print (vam->ofp, &node);
1269   vat_json_free (&node);
1270
1271   vam->retval = ntohl (mp->retval);
1272   vam->result_ready = 1;
1273 }
1274
1275 static void vl_api_get_next_index_reply_t_handler
1276   (vl_api_get_next_index_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   i32 retval = ntohl (mp->retval);
1280   if (vam->async_mode)
1281     {
1282       vam->async_errors += (retval < 0);
1283     }
1284   else
1285     {
1286       vam->retval = retval;
1287       if (retval == 0)
1288         errmsg ("next node index %d", ntohl (mp->next_index));
1289       vam->result_ready = 1;
1290     }
1291 }
1292
1293 static void vl_api_get_next_index_reply_t_handler_json
1294   (vl_api_get_next_index_reply_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   vat_json_node_t node;
1298
1299   vat_json_init_object (&node);
1300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1301   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1302
1303   vat_json_print (vam->ofp, &node);
1304   vat_json_free (&node);
1305
1306   vam->retval = ntohl (mp->retval);
1307   vam->result_ready = 1;
1308 }
1309
1310 static void vl_api_add_node_next_reply_t_handler
1311   (vl_api_add_node_next_reply_t * mp)
1312 {
1313   vat_main_t *vam = &vat_main;
1314   i32 retval = ntohl (mp->retval);
1315   if (vam->async_mode)
1316     {
1317       vam->async_errors += (retval < 0);
1318     }
1319   else
1320     {
1321       vam->retval = retval;
1322       if (retval == 0)
1323         errmsg ("next index %d", ntohl (mp->next_index));
1324       vam->result_ready = 1;
1325     }
1326 }
1327
1328 static void vl_api_add_node_next_reply_t_handler_json
1329   (vl_api_add_node_next_reply_t * mp)
1330 {
1331   vat_main_t *vam = &vat_main;
1332   vat_json_node_t node;
1333
1334   vat_json_init_object (&node);
1335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1336   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1337
1338   vat_json_print (vam->ofp, &node);
1339   vat_json_free (&node);
1340
1341   vam->retval = ntohl (mp->retval);
1342   vam->result_ready = 1;
1343 }
1344
1345 static void vl_api_show_version_reply_t_handler
1346   (vl_api_show_version_reply_t * mp)
1347 {
1348   vat_main_t *vam = &vat_main;
1349   i32 retval = ntohl (mp->retval);
1350
1351   if (retval >= 0)
1352     {
1353       errmsg ("        program: %s", mp->program);
1354       errmsg ("        version: %s", mp->version);
1355       errmsg ("     build date: %s", mp->build_date);
1356       errmsg ("build directory: %s", mp->build_directory);
1357     }
1358   vam->retval = retval;
1359   vam->result_ready = 1;
1360 }
1361
1362 static void vl_api_show_version_reply_t_handler_json
1363   (vl_api_show_version_reply_t * mp)
1364 {
1365   vat_main_t *vam = &vat_main;
1366   vat_json_node_t node;
1367
1368   vat_json_init_object (&node);
1369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1370   vat_json_object_add_string_copy (&node, "program", mp->program);
1371   vat_json_object_add_string_copy (&node, "version", mp->version);
1372   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1373   vat_json_object_add_string_copy (&node, "build_directory",
1374                                    mp->build_directory);
1375
1376   vat_json_print (vam->ofp, &node);
1377   vat_json_free (&node);
1378
1379   vam->retval = ntohl (mp->retval);
1380   vam->result_ready = 1;
1381 }
1382
1383 static void vl_api_show_threads_reply_t_handler
1384   (vl_api_show_threads_reply_t * mp)
1385 {
1386   vat_main_t *vam = &vat_main;
1387   i32 retval = ntohl (mp->retval);
1388   int i, count = 0;
1389
1390   if (retval >= 0)
1391     count = ntohl (mp->count);
1392
1393   for (i = 0; i < count; i++)
1394     print (vam->ofp,
1395            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1396            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1397            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1398            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1399            ntohl (mp->thread_data[i].cpu_socket));
1400
1401   vam->retval = retval;
1402   vam->result_ready = 1;
1403 }
1404
1405 static void vl_api_show_threads_reply_t_handler_json
1406   (vl_api_show_threads_reply_t * mp)
1407 {
1408   vat_main_t *vam = &vat_main;
1409   vat_json_node_t node;
1410   vl_api_thread_data_t *td;
1411   i32 retval = ntohl (mp->retval);
1412   int i, count = 0;
1413
1414   if (retval >= 0)
1415     count = ntohl (mp->count);
1416
1417   vat_json_init_object (&node);
1418   vat_json_object_add_int (&node, "retval", retval);
1419   vat_json_object_add_uint (&node, "count", count);
1420
1421   for (i = 0; i < count; i++)
1422     {
1423       td = &mp->thread_data[i];
1424       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1425       vat_json_object_add_string_copy (&node, "name", td->name);
1426       vat_json_object_add_string_copy (&node, "type", td->type);
1427       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1428       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1429       vat_json_object_add_int (&node, "core", ntohl (td->id));
1430       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1431     }
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = retval;
1437   vam->result_ready = 1;
1438 }
1439
1440 static int
1441 api_show_threads (vat_main_t * vam)
1442 {
1443   vl_api_show_threads_t *mp;
1444   int ret;
1445
1446   print (vam->ofp,
1447          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1448          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1449
1450   M (SHOW_THREADS, mp);
1451
1452   S (mp);
1453   W (ret);
1454   return ret;
1455 }
1456
1457 static void
1458 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1459 {
1460   u32 n_macs = ntohl (mp->n_macs);
1461   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1462           ntohl (mp->pid), mp->client_index, n_macs);
1463   int i;
1464   for (i = 0; i < n_macs; i++)
1465     {
1466       vl_api_mac_entry_t *mac = &mp->mac[i];
1467       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1468               i + 1, ntohl (mac->sw_if_index),
1469               format_ethernet_address, mac->mac_addr, mac->action);
1470       if (i == 1000)
1471         break;
1472     }
1473 }
1474
1475 static void
1476 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1477 {
1478   /* JSON output not supported */
1479 }
1480
1481 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1482 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1483
1484 /*
1485  * Special-case: build the bridge domain table, maintain
1486  * the next bd id vbl.
1487  */
1488 static void vl_api_bridge_domain_details_t_handler
1489   (vl_api_bridge_domain_details_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1493   int i;
1494
1495   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1496          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1497
1498   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1499          ntohl (mp->bd_id), mp->learn, mp->forward,
1500          mp->flood, ntohl (mp->bvi_sw_if_index),
1501          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1502
1503   if (n_sw_ifs)
1504     {
1505       vl_api_bridge_domain_sw_if_t *sw_ifs;
1506       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1507              "Interface Name");
1508
1509       sw_ifs = mp->sw_if_details;
1510       for (i = 0; i < n_sw_ifs; i++)
1511         {
1512           u8 *sw_if_name = 0;
1513           u32 sw_if_index;
1514           hash_pair_t *p;
1515
1516           sw_if_index = ntohl (sw_ifs->sw_if_index);
1517
1518           /* *INDENT-OFF* */
1519           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1520                              ({
1521                                if ((u32) p->value[0] == sw_if_index)
1522                                  {
1523                                    sw_if_name = (u8 *)(p->key);
1524                                    break;
1525                                  }
1526                              }));
1527           /* *INDENT-ON* */
1528           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1529                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1530                  "sw_if_index not found!");
1531
1532           sw_ifs++;
1533         }
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_details_t_handler_json
1538   (vl_api_bridge_domain_details_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t *node, *array = NULL;
1542   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1543
1544   if (VAT_JSON_ARRAY != vam->json_tree.type)
1545     {
1546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1547       vat_json_init_array (&vam->json_tree);
1548     }
1549   node = vat_json_array_add (&vam->json_tree);
1550
1551   vat_json_init_object (node);
1552   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1553   vat_json_object_add_uint (node, "flood", mp->flood);
1554   vat_json_object_add_uint (node, "forward", mp->forward);
1555   vat_json_object_add_uint (node, "learn", mp->learn);
1556   vat_json_object_add_uint (node, "bvi_sw_if_index",
1557                             ntohl (mp->bvi_sw_if_index));
1558   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1559   array = vat_json_object_add (node, "sw_if");
1560   vat_json_init_array (array);
1561
1562
1563
1564   if (n_sw_ifs)
1565     {
1566       vl_api_bridge_domain_sw_if_t *sw_ifs;
1567       int i;
1568
1569       sw_ifs = mp->sw_if_details;
1570       for (i = 0; i < n_sw_ifs; i++)
1571         {
1572           node = vat_json_array_add (array);
1573           vat_json_init_object (node);
1574           vat_json_object_add_uint (node, "sw_if_index",
1575                                     ntohl (sw_ifs->sw_if_index));
1576           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1577           sw_ifs++;
1578         }
1579     }
1580 }
1581
1582 static void vl_api_control_ping_reply_t_handler
1583   (vl_api_control_ping_reply_t * mp)
1584 {
1585   vat_main_t *vam = &vat_main;
1586   i32 retval = ntohl (mp->retval);
1587   if (vam->async_mode)
1588     {
1589       vam->async_errors += (retval < 0);
1590     }
1591   else
1592     {
1593       vam->retval = retval;
1594       vam->result_ready = 1;
1595     }
1596   if (vam->socket_client_main)
1597     vam->socket_client_main->control_pings_outstanding--;
1598 }
1599
1600 static void vl_api_control_ping_reply_t_handler_json
1601   (vl_api_control_ping_reply_t * mp)
1602 {
1603   vat_main_t *vam = &vat_main;
1604   i32 retval = ntohl (mp->retval);
1605
1606   if (VAT_JSON_NONE != vam->json_tree.type)
1607     {
1608       vat_json_print (vam->ofp, &vam->json_tree);
1609       vat_json_free (&vam->json_tree);
1610       vam->json_tree.type = VAT_JSON_NONE;
1611     }
1612   else
1613     {
1614       /* just print [] */
1615       vat_json_init_array (&vam->json_tree);
1616       vat_json_print (vam->ofp, &vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619
1620   vam->retval = retval;
1621   vam->result_ready = 1;
1622 }
1623
1624 static void
1625   vl_api_bridge_domain_set_mac_age_reply_t_handler
1626   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1642   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649
1650   vat_json_print (vam->ofp, &node);
1651   vat_json_free (&node);
1652
1653   vam->retval = ntohl (mp->retval);
1654   vam->result_ready = 1;
1655 }
1656
1657 static void
1658 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->result_ready = 1;
1670     }
1671 }
1672
1673 static void vl_api_l2_flags_reply_t_handler_json
1674   (vl_api_l2_flags_reply_t * mp)
1675 {
1676   vat_main_t *vam = &vat_main;
1677   vat_json_node_t node;
1678
1679   vat_json_init_object (&node);
1680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1681   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1682                             ntohl (mp->resulting_feature_bitmap));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void vl_api_bridge_flags_reply_t_handler
1692   (vl_api_bridge_flags_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_bridge_flags_reply_t_handler_json
1708   (vl_api_bridge_flags_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1716                             ntohl (mp->resulting_feature_bitmap));
1717
1718   vat_json_print (vam->ofp, &node);
1719   vat_json_free (&node);
1720
1721   vam->retval = ntohl (mp->retval);
1722   vam->result_ready = 1;
1723 }
1724
1725 static void
1726 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   i32 retval = ntohl (mp->retval);
1730   if (vam->async_mode)
1731     {
1732       vam->async_errors += (retval < 0);
1733     }
1734   else
1735     {
1736       vam->retval = retval;
1737       vam->sw_if_index = ntohl (mp->sw_if_index);
1738       vam->result_ready = 1;
1739     }
1740
1741 }
1742
1743 static void vl_api_tap_create_v2_reply_t_handler_json
1744   (vl_api_tap_create_v2_reply_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   vat_json_node_t node;
1748
1749   vat_json_init_object (&node);
1750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1752
1753   vat_json_print (vam->ofp, &node);
1754   vat_json_free (&node);
1755
1756   vam->retval = ntohl (mp->retval);
1757   vam->result_ready = 1;
1758
1759 }
1760
1761 static void
1762 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->result_ready = 1;
1774     }
1775 }
1776
1777 static void vl_api_tap_delete_v2_reply_t_handler_json
1778   (vl_api_tap_delete_v2_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   vat_json_node_t node;
1782
1783   vat_json_init_object (&node);
1784   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1785
1786   vat_json_print (vam->ofp, &node);
1787   vat_json_free (&node);
1788
1789   vam->retval = ntohl (mp->retval);
1790   vam->result_ready = 1;
1791 }
1792
1793 static void
1794 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1795                                           mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   i32 retval = ntohl (mp->retval);
1799   if (vam->async_mode)
1800     {
1801       vam->async_errors += (retval < 0);
1802     }
1803   else
1804     {
1805       vam->retval = retval;
1806       vam->sw_if_index = ntohl (mp->sw_if_index);
1807       vam->result_ready = 1;
1808     }
1809 }
1810
1811 static void vl_api_virtio_pci_create_reply_t_handler_json
1812   (vl_api_virtio_pci_create_reply_t * mp)
1813 {
1814   vat_main_t *vam = &vat_main;
1815   vat_json_node_t node;
1816
1817   vat_json_init_object (&node);
1818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1819   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1820
1821   vat_json_print (vam->ofp, &node);
1822   vat_json_free (&node);
1823
1824   vam->retval = ntohl (mp->retval);
1825   vam->result_ready = 1;
1826
1827 }
1828
1829 static void
1830 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1831                                           mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   i32 retval = ntohl (mp->retval);
1835   if (vam->async_mode)
1836     {
1837       vam->async_errors += (retval < 0);
1838     }
1839   else
1840     {
1841       vam->retval = retval;
1842       vam->result_ready = 1;
1843     }
1844 }
1845
1846 static void vl_api_virtio_pci_delete_reply_t_handler_json
1847   (vl_api_virtio_pci_delete_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   vat_json_node_t node;
1851
1852   vat_json_init_object (&node);
1853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1854
1855   vat_json_print (vam->ofp, &node);
1856   vat_json_free (&node);
1857
1858   vam->retval = ntohl (mp->retval);
1859   vam->result_ready = 1;
1860 }
1861
1862 static void
1863 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   i32 retval = ntohl (mp->retval);
1867
1868   if (vam->async_mode)
1869     {
1870       vam->async_errors += (retval < 0);
1871     }
1872   else
1873     {
1874       vam->retval = retval;
1875       vam->sw_if_index = ntohl (mp->sw_if_index);
1876       vam->result_ready = 1;
1877     }
1878 }
1879
1880 static void vl_api_bond_create_reply_t_handler_json
1881   (vl_api_bond_create_reply_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   vat_json_node_t node;
1885
1886   vat_json_init_object (&node);
1887   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1888   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1889
1890   vat_json_print (vam->ofp, &node);
1891   vat_json_free (&node);
1892
1893   vam->retval = ntohl (mp->retval);
1894   vam->result_ready = 1;
1895 }
1896
1897 static void
1898 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902
1903   if (vam->async_mode)
1904     {
1905       vam->async_errors += (retval < 0);
1906     }
1907   else
1908     {
1909       vam->retval = retval;
1910       vam->result_ready = 1;
1911     }
1912 }
1913
1914 static void vl_api_bond_delete_reply_t_handler_json
1915   (vl_api_bond_delete_reply_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918   vat_json_node_t node;
1919
1920   vat_json_init_object (&node);
1921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1922
1923   vat_json_print (vam->ofp, &node);
1924   vat_json_free (&node);
1925
1926   vam->retval = ntohl (mp->retval);
1927   vam->result_ready = 1;
1928 }
1929
1930 static void
1931 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   i32 retval = ntohl (mp->retval);
1935
1936   if (vam->async_mode)
1937     {
1938       vam->async_errors += (retval < 0);
1939     }
1940   else
1941     {
1942       vam->retval = retval;
1943       vam->result_ready = 1;
1944     }
1945 }
1946
1947 static void vl_api_bond_enslave_reply_t_handler_json
1948   (vl_api_bond_enslave_reply_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951   vat_json_node_t node;
1952
1953   vat_json_init_object (&node);
1954   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1955
1956   vat_json_print (vam->ofp, &node);
1957   vat_json_free (&node);
1958
1959   vam->retval = ntohl (mp->retval);
1960   vam->result_ready = 1;
1961 }
1962
1963 static void
1964 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1965                                           mp)
1966 {
1967   vat_main_t *vam = &vat_main;
1968   i32 retval = ntohl (mp->retval);
1969
1970   if (vam->async_mode)
1971     {
1972       vam->async_errors += (retval < 0);
1973     }
1974   else
1975     {
1976       vam->retval = retval;
1977       vam->result_ready = 1;
1978     }
1979 }
1980
1981 static void vl_api_bond_detach_slave_reply_t_handler_json
1982   (vl_api_bond_detach_slave_reply_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985   vat_json_node_t node;
1986
1987   vat_json_init_object (&node);
1988   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1989
1990   vat_json_print (vam->ofp, &node);
1991   vat_json_free (&node);
1992
1993   vam->retval = ntohl (mp->retval);
1994   vam->result_ready = 1;
1995 }
1996
1997 static int
1998 api_sw_interface_set_bond_weight (vat_main_t * vam)
1999 {
2000   unformat_input_t *i = vam->input;
2001   vl_api_sw_interface_set_bond_weight_t *mp;
2002   u32 sw_if_index = ~0;
2003   u32 weight = 0;
2004   u8 weight_enter = 0;
2005   int ret;
2006
2007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2008     {
2009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2010         ;
2011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2012         ;
2013       else if (unformat (i, "weight %u", &weight))
2014         weight_enter = 1;
2015       else
2016         break;
2017     }
2018
2019   if (sw_if_index == ~0)
2020     {
2021       errmsg ("missing interface name or sw_if_index");
2022       return -99;
2023     }
2024   if (weight_enter == 0)
2025     {
2026       errmsg ("missing valid weight");
2027       return -99;
2028     }
2029
2030   /* Construct the API message */
2031   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2032   mp->sw_if_index = ntohl (sw_if_index);
2033   mp->weight = ntohl (weight);
2034
2035   S (mp);
2036   W (ret);
2037   return ret;
2038 }
2039
2040 static void vl_api_sw_interface_bond_details_t_handler
2041   (vl_api_sw_interface_bond_details_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044
2045   print (vam->ofp,
2046          "%-16s %-12d %-12U %-13U %-14u %-14u",
2047          mp->interface_name, ntohl (mp->sw_if_index),
2048          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2049          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2050 }
2051
2052 static void vl_api_sw_interface_bond_details_t_handler_json
2053   (vl_api_sw_interface_bond_details_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   vat_json_node_t *node = NULL;
2057
2058   if (VAT_JSON_ARRAY != vam->json_tree.type)
2059     {
2060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2061       vat_json_init_array (&vam->json_tree);
2062     }
2063   node = vat_json_array_add (&vam->json_tree);
2064
2065   vat_json_init_object (node);
2066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2067   vat_json_object_add_string_copy (node, "interface_name",
2068                                    mp->interface_name);
2069   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2070   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2071   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2072   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2073 }
2074
2075 static int
2076 api_sw_interface_bond_dump (vat_main_t * vam)
2077 {
2078   vl_api_sw_interface_bond_dump_t *mp;
2079   vl_api_control_ping_t *mp_ping;
2080   int ret;
2081
2082   print (vam->ofp,
2083          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2084          "interface name", "sw_if_index", "mode", "load balance",
2085          "active slaves", "slaves");
2086
2087   /* Get list of bond interfaces */
2088   M (SW_INTERFACE_BOND_DUMP, mp);
2089   S (mp);
2090
2091   /* Use a control ping for synchronization */
2092   MPING (CONTROL_PING, mp_ping);
2093   S (mp_ping);
2094
2095   W (ret);
2096   return ret;
2097 }
2098
2099 static void vl_api_sw_interface_slave_details_t_handler
2100   (vl_api_sw_interface_slave_details_t * mp)
2101 {
2102   vat_main_t *vam = &vat_main;
2103
2104   print (vam->ofp,
2105          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2106          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2107          ntohl (mp->weight), mp->is_local_numa);
2108 }
2109
2110 static void vl_api_sw_interface_slave_details_t_handler_json
2111   (vl_api_sw_interface_slave_details_t * mp)
2112 {
2113   vat_main_t *vam = &vat_main;
2114   vat_json_node_t *node = NULL;
2115
2116   if (VAT_JSON_ARRAY != vam->json_tree.type)
2117     {
2118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2119       vat_json_init_array (&vam->json_tree);
2120     }
2121   node = vat_json_array_add (&vam->json_tree);
2122
2123   vat_json_init_object (node);
2124   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2125   vat_json_object_add_string_copy (node, "interface_name",
2126                                    mp->interface_name);
2127   vat_json_object_add_uint (node, "passive", mp->is_passive);
2128   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2129   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2130   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2131 }
2132
2133 static int
2134 api_sw_interface_slave_dump (vat_main_t * vam)
2135 {
2136   unformat_input_t *i = vam->input;
2137   vl_api_sw_interface_slave_dump_t *mp;
2138   vl_api_control_ping_t *mp_ping;
2139   u32 sw_if_index = ~0;
2140   u8 sw_if_index_set = 0;
2141   int ret;
2142
2143   /* Parse args required to build the message */
2144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145     {
2146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147         sw_if_index_set = 1;
2148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2149         sw_if_index_set = 1;
2150       else
2151         break;
2152     }
2153
2154   if (sw_if_index_set == 0)
2155     {
2156       errmsg ("missing vpp interface name. ");
2157       return -99;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2162          "slave interface name", "sw_if_index", "passive", "long_timeout",
2163          "weight", "local numa");
2164
2165   /* Get list of bond interfaces */
2166   M (SW_INTERFACE_SLAVE_DUMP, mp);
2167   mp->sw_if_index = ntohl (sw_if_index);
2168   S (mp);
2169
2170   /* Use a control ping for synchronization */
2171   MPING (CONTROL_PING, mp_ping);
2172   S (mp_ping);
2173
2174   W (ret);
2175   return ret;
2176 }
2177
2178 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2179   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2180 {
2181   vat_main_t *vam = &vat_main;
2182   i32 retval = ntohl (mp->retval);
2183   if (vam->async_mode)
2184     {
2185       vam->async_errors += (retval < 0);
2186     }
2187   else
2188     {
2189       vam->retval = retval;
2190       vam->sw_if_index = ntohl (mp->sw_if_index);
2191       vam->result_ready = 1;
2192     }
2193   vam->regenerate_interface_table = 1;
2194 }
2195
2196 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2197   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vat_json_node_t node;
2201
2202   vat_json_init_object (&node);
2203   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2204   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2205                             ntohl (mp->sw_if_index));
2206
2207   vat_json_print (vam->ofp, &node);
2208   vat_json_free (&node);
2209
2210   vam->retval = ntohl (mp->retval);
2211   vam->result_ready = 1;
2212 }
2213
2214 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2215   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   i32 retval = ntohl (mp->retval);
2219   if (vam->async_mode)
2220     {
2221       vam->async_errors += (retval < 0);
2222     }
2223   else
2224     {
2225       vam->retval = retval;
2226       vam->sw_if_index = ntohl (mp->sw_if_index);
2227       vam->result_ready = 1;
2228     }
2229 }
2230
2231 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2232   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   vat_json_node_t node;
2236
2237   vat_json_init_object (&node);
2238   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2239   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2240
2241   vat_json_print (vam->ofp, &node);
2242   vat_json_free (&node);
2243
2244   vam->retval = ntohl (mp->retval);
2245   vam->result_ready = 1;
2246 }
2247
2248 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2249   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   i32 retval = ntohl (mp->retval);
2253   if (vam->async_mode)
2254     {
2255       vam->async_errors += (retval < 0);
2256     }
2257   else
2258     {
2259       vam->retval = retval;
2260       vam->result_ready = 1;
2261     }
2262 }
2263
2264 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2265   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   vat_json_node_t node;
2269
2270   vat_json_init_object (&node);
2271   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2272   vat_json_object_add_uint (&node, "fwd_entry_index",
2273                             clib_net_to_host_u32 (mp->fwd_entry_index));
2274
2275   vat_json_print (vam->ofp, &node);
2276   vat_json_free (&node);
2277
2278   vam->retval = ntohl (mp->retval);
2279   vam->result_ready = 1;
2280 }
2281
2282 u8 *
2283 format_lisp_transport_protocol (u8 * s, va_list * args)
2284 {
2285   u32 proto = va_arg (*args, u32);
2286
2287   switch (proto)
2288     {
2289     case 1:
2290       return format (s, "udp");
2291     case 2:
2292       return format (s, "api");
2293     default:
2294       return 0;
2295     }
2296   return 0;
2297 }
2298
2299 static void vl_api_one_get_transport_protocol_reply_t_handler
2300   (vl_api_one_get_transport_protocol_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       u32 proto = mp->protocol;
2311       print (vam->ofp, "Transport protocol: %U",
2312              format_lisp_transport_protocol, proto);
2313       vam->retval = retval;
2314       vam->result_ready = 1;
2315     }
2316 }
2317
2318 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2319   (vl_api_one_get_transport_protocol_reply_t * mp)
2320 {
2321   vat_main_t *vam = &vat_main;
2322   vat_json_node_t node;
2323   u8 *s;
2324
2325   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2326   vec_add1 (s, 0);
2327
2328   vat_json_init_object (&node);
2329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2330   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2331
2332   vec_free (s);
2333   vat_json_print (vam->ofp, &node);
2334   vat_json_free (&node);
2335
2336   vam->retval = ntohl (mp->retval);
2337   vam->result_ready = 1;
2338 }
2339
2340 static void vl_api_one_add_del_locator_set_reply_t_handler
2341   (vl_api_one_add_del_locator_set_reply_t * mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   i32 retval = ntohl (mp->retval);
2345   if (vam->async_mode)
2346     {
2347       vam->async_errors += (retval < 0);
2348     }
2349   else
2350     {
2351       vam->retval = retval;
2352       vam->result_ready = 1;
2353     }
2354 }
2355
2356 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2357   (vl_api_one_add_del_locator_set_reply_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   vat_json_node_t node;
2361
2362   vat_json_init_object (&node);
2363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2364   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2365
2366   vat_json_print (vam->ofp, &node);
2367   vat_json_free (&node);
2368
2369   vam->retval = ntohl (mp->retval);
2370   vam->result_ready = 1;
2371 }
2372
2373 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2374   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   i32 retval = ntohl (mp->retval);
2378   if (vam->async_mode)
2379     {
2380       vam->async_errors += (retval < 0);
2381     }
2382   else
2383     {
2384       vam->retval = retval;
2385       vam->sw_if_index = ntohl (mp->sw_if_index);
2386       vam->result_ready = 1;
2387     }
2388   vam->regenerate_interface_table = 1;
2389 }
2390
2391 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2392   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   vat_json_node_t node;
2396
2397   vat_json_init_object (&node);
2398   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2399   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2400
2401   vat_json_print (vam->ofp, &node);
2402   vat_json_free (&node);
2403
2404   vam->retval = ntohl (mp->retval);
2405   vam->result_ready = 1;
2406 }
2407
2408 static void vl_api_vxlan_offload_rx_reply_t_handler
2409   (vl_api_vxlan_offload_rx_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   i32 retval = ntohl (mp->retval);
2413   if (vam->async_mode)
2414     {
2415       vam->async_errors += (retval < 0);
2416     }
2417   else
2418     {
2419       vam->retval = retval;
2420       vam->result_ready = 1;
2421     }
2422 }
2423
2424 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2425   (vl_api_vxlan_offload_rx_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   vat_json_node_t node;
2429
2430   vat_json_init_object (&node);
2431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2432
2433   vat_json_print (vam->ofp, &node);
2434   vat_json_free (&node);
2435
2436   vam->retval = ntohl (mp->retval);
2437   vam->result_ready = 1;
2438 }
2439
2440 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2441   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   i32 retval = ntohl (mp->retval);
2445   if (vam->async_mode)
2446     {
2447       vam->async_errors += (retval < 0);
2448     }
2449   else
2450     {
2451       vam->retval = retval;
2452       vam->sw_if_index = ntohl (mp->sw_if_index);
2453       vam->result_ready = 1;
2454     }
2455 }
2456
2457 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2458   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2459 {
2460   vat_main_t *vam = &vat_main;
2461   vat_json_node_t node;
2462
2463   vat_json_init_object (&node);
2464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2466
2467   vat_json_print (vam->ofp, &node);
2468   vat_json_free (&node);
2469
2470   vam->retval = ntohl (mp->retval);
2471   vam->result_ready = 1;
2472 }
2473
2474 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2475   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   i32 retval = ntohl (mp->retval);
2479   if (vam->async_mode)
2480     {
2481       vam->async_errors += (retval < 0);
2482     }
2483   else
2484     {
2485       vam->retval = retval;
2486       vam->sw_if_index = ntohl (mp->sw_if_index);
2487       vam->result_ready = 1;
2488     }
2489   vam->regenerate_interface_table = 1;
2490 }
2491
2492 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2493   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t node;
2497
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2501
2502   vat_json_print (vam->ofp, &node);
2503   vat_json_free (&node);
2504
2505   vam->retval = ntohl (mp->retval);
2506   vam->result_ready = 1;
2507 }
2508
2509 static void vl_api_gre_tunnel_add_del_reply_t_handler
2510   (vl_api_gre_tunnel_add_del_reply_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   i32 retval = ntohl (mp->retval);
2514   if (vam->async_mode)
2515     {
2516       vam->async_errors += (retval < 0);
2517     }
2518   else
2519     {
2520       vam->retval = retval;
2521       vam->sw_if_index = ntohl (mp->sw_if_index);
2522       vam->result_ready = 1;
2523     }
2524 }
2525
2526 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2527   (vl_api_gre_tunnel_add_del_reply_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   vat_json_node_t node;
2531
2532   vat_json_init_object (&node);
2533   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2534   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2535
2536   vat_json_print (vam->ofp, &node);
2537   vat_json_free (&node);
2538
2539   vam->retval = ntohl (mp->retval);
2540   vam->result_ready = 1;
2541 }
2542
2543 static void vl_api_create_vhost_user_if_reply_t_handler
2544   (vl_api_create_vhost_user_if_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   i32 retval = ntohl (mp->retval);
2548   if (vam->async_mode)
2549     {
2550       vam->async_errors += (retval < 0);
2551     }
2552   else
2553     {
2554       vam->retval = retval;
2555       vam->sw_if_index = ntohl (mp->sw_if_index);
2556       vam->result_ready = 1;
2557     }
2558   vam->regenerate_interface_table = 1;
2559 }
2560
2561 static void vl_api_create_vhost_user_if_reply_t_handler_json
2562   (vl_api_create_vhost_user_if_reply_t * mp)
2563 {
2564   vat_main_t *vam = &vat_main;
2565   vat_json_node_t node;
2566
2567   vat_json_init_object (&node);
2568   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2569   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2570
2571   vat_json_print (vam->ofp, &node);
2572   vat_json_free (&node);
2573
2574   vam->retval = ntohl (mp->retval);
2575   vam->result_ready = 1;
2576 }
2577
2578 static void vl_api_ip_address_details_t_handler
2579   (vl_api_ip_address_details_t * mp)
2580 {
2581   vat_main_t *vam = &vat_main;
2582   static ip_address_details_t empty_ip_address_details = { {0} };
2583   ip_address_details_t *address = NULL;
2584   ip_details_t *current_ip_details = NULL;
2585   ip_details_t *details = NULL;
2586
2587   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2588
2589   if (!details || vam->current_sw_if_index >= vec_len (details)
2590       || !details[vam->current_sw_if_index].present)
2591     {
2592       errmsg ("ip address details arrived but not stored");
2593       errmsg ("ip_dump should be called first");
2594       return;
2595     }
2596
2597   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2598
2599 #define addresses (current_ip_details->addr)
2600
2601   vec_validate_init_empty (addresses, vec_len (addresses),
2602                            empty_ip_address_details);
2603
2604   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2605
2606   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2607   address->prefix_length = mp->prefix.len;
2608 #undef addresses
2609 }
2610
2611 static void vl_api_ip_address_details_t_handler_json
2612   (vl_api_ip_address_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616
2617   if (VAT_JSON_ARRAY != vam->json_tree.type)
2618     {
2619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2620       vat_json_init_array (&vam->json_tree);
2621     }
2622   node = vat_json_array_add (&vam->json_tree);
2623
2624   vat_json_init_object (node);
2625   vat_json_object_add_prefix (node, &mp->prefix);
2626 }
2627
2628 static void
2629 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   static ip_details_t empty_ip_details = { 0 };
2633   ip_details_t *ip = NULL;
2634   u32 sw_if_index = ~0;
2635
2636   sw_if_index = ntohl (mp->sw_if_index);
2637
2638   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2639                            sw_if_index, empty_ip_details);
2640
2641   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642                          sw_if_index);
2643
2644   ip->present = 1;
2645 }
2646
2647 static void
2648 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2649 {
2650   vat_main_t *vam = &vat_main;
2651
2652   if (VAT_JSON_ARRAY != vam->json_tree.type)
2653     {
2654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2655       vat_json_init_array (&vam->json_tree);
2656     }
2657   vat_json_array_add_uint (&vam->json_tree,
2658                            clib_net_to_host_u32 (mp->sw_if_index));
2659 }
2660
2661 static void vl_api_get_first_msg_id_reply_t_handler
2662   (vl_api_get_first_msg_id_reply_t * mp)
2663 {
2664   vat_main_t *vam = &vat_main;
2665   i32 retval = ntohl (mp->retval);
2666
2667   if (vam->async_mode)
2668     {
2669       vam->async_errors += (retval < 0);
2670     }
2671   else
2672     {
2673       vam->retval = retval;
2674       vam->result_ready = 1;
2675     }
2676   if (retval >= 0)
2677     {
2678       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2679     }
2680 }
2681
2682 static void vl_api_get_first_msg_id_reply_t_handler_json
2683   (vl_api_get_first_msg_id_reply_t * mp)
2684 {
2685   vat_main_t *vam = &vat_main;
2686   vat_json_node_t node;
2687
2688   vat_json_init_object (&node);
2689   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2690   vat_json_object_add_uint (&node, "first_msg_id",
2691                             (uint) ntohs (mp->first_msg_id));
2692
2693   vat_json_print (vam->ofp, &node);
2694   vat_json_free (&node);
2695
2696   vam->retval = ntohl (mp->retval);
2697   vam->result_ready = 1;
2698 }
2699
2700 static void vl_api_get_node_graph_reply_t_handler
2701   (vl_api_get_node_graph_reply_t * mp)
2702 {
2703   vat_main_t *vam = &vat_main;
2704   i32 retval = ntohl (mp->retval);
2705   u8 *pvt_copy, *reply;
2706   void *oldheap;
2707   vlib_node_t *node;
2708   int i;
2709
2710   if (vam->async_mode)
2711     {
2712       vam->async_errors += (retval < 0);
2713     }
2714   else
2715     {
2716       vam->retval = retval;
2717       vam->result_ready = 1;
2718     }
2719
2720   /* "Should never happen..." */
2721   if (retval != 0)
2722     return;
2723
2724   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2725   pvt_copy = vec_dup (reply);
2726
2727   /* Toss the shared-memory original... */
2728   oldheap = vl_msg_push_heap ();
2729
2730   vec_free (reply);
2731
2732   vl_msg_pop_heap (oldheap);
2733
2734   if (vam->graph_nodes)
2735     {
2736       hash_free (vam->graph_node_index_by_name);
2737
2738       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2739         {
2740           node = vam->graph_nodes[0][i];
2741           vec_free (node->name);
2742           vec_free (node->next_nodes);
2743           vec_free (node);
2744         }
2745       vec_free (vam->graph_nodes[0]);
2746       vec_free (vam->graph_nodes);
2747     }
2748
2749   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2750   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2751   vec_free (pvt_copy);
2752
2753   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2754     {
2755       node = vam->graph_nodes[0][i];
2756       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2757     }
2758 }
2759
2760 static void vl_api_get_node_graph_reply_t_handler_json
2761   (vl_api_get_node_graph_reply_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   void *oldheap;
2765   vat_json_node_t node;
2766   u8 *reply;
2767
2768   /* $$$$ make this real? */
2769   vat_json_init_object (&node);
2770   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2771   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2772
2773   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2774
2775   /* Toss the shared-memory original... */
2776   oldheap = vl_msg_push_heap ();
2777
2778   vec_free (reply);
2779
2780   vl_msg_pop_heap (oldheap);
2781
2782   vat_json_print (vam->ofp, &node);
2783   vat_json_free (&node);
2784
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793   u8 *s = 0;
2794
2795   if (mp->local)
2796     {
2797       s = format (s, "%=16d%=16d%=16d",
2798                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2799     }
2800   else
2801     {
2802       s = format (s, "%=16U%=16d%=16d",
2803                   mp->is_ipv6 ? format_ip6_address :
2804                   format_ip4_address,
2805                   mp->ip_address, mp->priority, mp->weight);
2806     }
2807
2808   print (vam->ofp, "%v", s);
2809   vec_free (s);
2810 }
2811
2812 static void
2813 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2814 {
2815   vat_main_t *vam = &vat_main;
2816   vat_json_node_t *node = NULL;
2817   struct in6_addr ip6;
2818   struct in_addr ip4;
2819
2820   if (VAT_JSON_ARRAY != vam->json_tree.type)
2821     {
2822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2823       vat_json_init_array (&vam->json_tree);
2824     }
2825   node = vat_json_array_add (&vam->json_tree);
2826   vat_json_init_object (node);
2827
2828   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2829   vat_json_object_add_uint (node, "priority", mp->priority);
2830   vat_json_object_add_uint (node, "weight", mp->weight);
2831
2832   if (mp->local)
2833     vat_json_object_add_uint (node, "sw_if_index",
2834                               clib_net_to_host_u32 (mp->sw_if_index));
2835   else
2836     {
2837       if (mp->is_ipv6)
2838         {
2839           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2840           vat_json_object_add_ip6 (node, "address", ip6);
2841         }
2842       else
2843         {
2844           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2845           vat_json_object_add_ip4 (node, "address", ip4);
2846         }
2847     }
2848 }
2849
2850 static void
2851 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2852                                           mp)
2853 {
2854   vat_main_t *vam = &vat_main;
2855   u8 *ls_name = 0;
2856
2857   ls_name = format (0, "%s", mp->ls_name);
2858
2859   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2860          ls_name);
2861   vec_free (ls_name);
2862 }
2863
2864 static void
2865   vl_api_one_locator_set_details_t_handler_json
2866   (vl_api_one_locator_set_details_t * mp)
2867 {
2868   vat_main_t *vam = &vat_main;
2869   vat_json_node_t *node = 0;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873   vec_add1 (ls_name, 0);
2874
2875   if (VAT_JSON_ARRAY != vam->json_tree.type)
2876     {
2877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2878       vat_json_init_array (&vam->json_tree);
2879     }
2880   node = vat_json_array_add (&vam->json_tree);
2881
2882   vat_json_init_object (node);
2883   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2884   vat_json_object_add_uint (node, "ls_index",
2885                             clib_net_to_host_u32 (mp->ls_index));
2886   vec_free (ls_name);
2887 }
2888
2889 typedef struct
2890 {
2891   u32 spi;
2892   u8 si;
2893 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2894
2895 uword
2896 unformat_nsh_address (unformat_input_t * input, va_list * args)
2897 {
2898   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2899   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2900 }
2901
2902 u8 *
2903 format_nsh_address_vat (u8 * s, va_list * args)
2904 {
2905   nsh_t *a = va_arg (*args, nsh_t *);
2906   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2907 }
2908
2909 static u8 *
2910 format_lisp_flat_eid (u8 * s, va_list * args)
2911 {
2912   u32 type = va_arg (*args, u32);
2913   u8 *eid = va_arg (*args, u8 *);
2914   u32 eid_len = va_arg (*args, u32);
2915
2916   switch (type)
2917     {
2918     case 0:
2919       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2920     case 1:
2921       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2922     case 2:
2923       return format (s, "%U", format_ethernet_address, eid);
2924     case 3:
2925       return format (s, "%U", format_nsh_address_vat, eid);
2926     }
2927   return 0;
2928 }
2929
2930 static u8 *
2931 format_lisp_eid_vat (u8 * s, va_list * args)
2932 {
2933   u32 type = va_arg (*args, u32);
2934   u8 *eid = va_arg (*args, u8 *);
2935   u32 eid_len = va_arg (*args, u32);
2936   u8 *seid = va_arg (*args, u8 *);
2937   u32 seid_len = va_arg (*args, u32);
2938   u32 is_src_dst = va_arg (*args, u32);
2939
2940   if (is_src_dst)
2941     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2942
2943   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2944
2945   return s;
2946 }
2947
2948 static void
2949 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *s = 0, *eid = 0;
2953
2954   if (~0 == mp->locator_set_index)
2955     s = format (0, "action: %d", mp->action);
2956   else
2957     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2958
2959   eid = format (0, "%U", format_lisp_eid_vat,
2960                 mp->eid_type,
2961                 mp->eid,
2962                 mp->eid_prefix_len,
2963                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2964   vec_add1 (eid, 0);
2965
2966   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2967          clib_net_to_host_u32 (mp->vni),
2968          eid,
2969          mp->is_local ? "local" : "remote",
2970          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2971          clib_net_to_host_u16 (mp->key_id), mp->key);
2972
2973   vec_free (s);
2974   vec_free (eid);
2975 }
2976
2977 static void
2978 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2979                                              * mp)
2980 {
2981   vat_main_t *vam = &vat_main;
2982   vat_json_node_t *node = 0;
2983   u8 *eid = 0;
2984
2985   if (VAT_JSON_ARRAY != vam->json_tree.type)
2986     {
2987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2988       vat_json_init_array (&vam->json_tree);
2989     }
2990   node = vat_json_array_add (&vam->json_tree);
2991
2992   vat_json_init_object (node);
2993   if (~0 == mp->locator_set_index)
2994     vat_json_object_add_uint (node, "action", mp->action);
2995   else
2996     vat_json_object_add_uint (node, "locator_set_index",
2997                               clib_net_to_host_u32 (mp->locator_set_index));
2998
2999   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3000   if (mp->eid_type == 3)
3001     {
3002       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3003       vat_json_init_object (nsh_json);
3004       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3005       vat_json_object_add_uint (nsh_json, "spi",
3006                                 clib_net_to_host_u32 (nsh->spi));
3007       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3008     }
3009   else
3010     {
3011       eid = format (0, "%U", format_lisp_eid_vat,
3012                     mp->eid_type,
3013                     mp->eid,
3014                     mp->eid_prefix_len,
3015                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3016       vec_add1 (eid, 0);
3017       vat_json_object_add_string_copy (node, "eid", eid);
3018       vec_free (eid);
3019     }
3020   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3021   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3022   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3023
3024   if (mp->key_id)
3025     {
3026       vat_json_object_add_uint (node, "key_id",
3027                                 clib_net_to_host_u16 (mp->key_id));
3028       vat_json_object_add_string_copy (node, "key", mp->key);
3029     }
3030 }
3031
3032 static void
3033 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3034 {
3035   vat_main_t *vam = &vat_main;
3036   u8 *seid = 0, *deid = 0;
3037   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3038
3039   deid = format (0, "%U", format_lisp_eid_vat,
3040                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3041
3042   seid = format (0, "%U", format_lisp_eid_vat,
3043                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3044
3045   vec_add1 (deid, 0);
3046   vec_add1 (seid, 0);
3047
3048   if (mp->is_ip4)
3049     format_ip_address_fcn = format_ip4_address;
3050   else
3051     format_ip_address_fcn = format_ip6_address;
3052
3053
3054   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3055          clib_net_to_host_u32 (mp->vni),
3056          seid, deid,
3057          format_ip_address_fcn, mp->lloc,
3058          format_ip_address_fcn, mp->rloc,
3059          clib_net_to_host_u32 (mp->pkt_count),
3060          clib_net_to_host_u32 (mp->bytes));
3061
3062   vec_free (deid);
3063   vec_free (seid);
3064 }
3065
3066 static void
3067 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3068 {
3069   struct in6_addr ip6;
3070   struct in_addr ip4;
3071   vat_main_t *vam = &vat_main;
3072   vat_json_node_t *node = 0;
3073   u8 *deid = 0, *seid = 0;
3074
3075   if (VAT_JSON_ARRAY != vam->json_tree.type)
3076     {
3077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3078       vat_json_init_array (&vam->json_tree);
3079     }
3080   node = vat_json_array_add (&vam->json_tree);
3081
3082   vat_json_init_object (node);
3083   deid = format (0, "%U", format_lisp_eid_vat,
3084                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3085
3086   seid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3088
3089   vec_add1 (deid, 0);
3090   vec_add1 (seid, 0);
3091
3092   vat_json_object_add_string_copy (node, "seid", seid);
3093   vat_json_object_add_string_copy (node, "deid", deid);
3094   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3095
3096   if (mp->is_ip4)
3097     {
3098       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3099       vat_json_object_add_ip4 (node, "lloc", ip4);
3100       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3101       vat_json_object_add_ip4 (node, "rloc", ip4);
3102     }
3103   else
3104     {
3105       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3106       vat_json_object_add_ip6 (node, "lloc", ip6);
3107       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3108       vat_json_object_add_ip6 (node, "rloc", ip6);
3109     }
3110   vat_json_object_add_uint (node, "pkt_count",
3111                             clib_net_to_host_u32 (mp->pkt_count));
3112   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3113
3114   vec_free (deid);
3115   vec_free (seid);
3116 }
3117
3118 static void
3119   vl_api_one_eid_table_map_details_t_handler
3120   (vl_api_one_eid_table_map_details_t * mp)
3121 {
3122   vat_main_t *vam = &vat_main;
3123
3124   u8 *line = format (0, "%=10d%=10d",
3125                      clib_net_to_host_u32 (mp->vni),
3126                      clib_net_to_host_u32 (mp->dp_table));
3127   print (vam->ofp, "%v", line);
3128   vec_free (line);
3129 }
3130
3131 static void
3132   vl_api_one_eid_table_map_details_t_handler_json
3133   (vl_api_one_eid_table_map_details_t * mp)
3134 {
3135   vat_main_t *vam = &vat_main;
3136   vat_json_node_t *node = NULL;
3137
3138   if (VAT_JSON_ARRAY != vam->json_tree.type)
3139     {
3140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3141       vat_json_init_array (&vam->json_tree);
3142     }
3143   node = vat_json_array_add (&vam->json_tree);
3144   vat_json_init_object (node);
3145   vat_json_object_add_uint (node, "dp_table",
3146                             clib_net_to_host_u32 (mp->dp_table));
3147   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3148 }
3149
3150 static void
3151   vl_api_one_eid_table_vni_details_t_handler
3152   (vl_api_one_eid_table_vni_details_t * mp)
3153 {
3154   vat_main_t *vam = &vat_main;
3155
3156   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3157   print (vam->ofp, "%v", line);
3158   vec_free (line);
3159 }
3160
3161 static void
3162   vl_api_one_eid_table_vni_details_t_handler_json
3163   (vl_api_one_eid_table_vni_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t *node = NULL;
3167
3168   if (VAT_JSON_ARRAY != vam->json_tree.type)
3169     {
3170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3171       vat_json_init_array (&vam->json_tree);
3172     }
3173   node = vat_json_array_add (&vam->json_tree);
3174   vat_json_init_object (node);
3175   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3176 }
3177
3178 static void
3179   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3180   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3181 {
3182   vat_main_t *vam = &vat_main;
3183   int retval = clib_net_to_host_u32 (mp->retval);
3184
3185   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3186   print (vam->ofp, "fallback threshold value: %d", mp->value);
3187
3188   vam->retval = retval;
3189   vam->result_ready = 1;
3190 }
3191
3192 static void
3193   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3194   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   vat_json_node_t _node, *node = &_node;
3198   int retval = clib_net_to_host_u32 (mp->retval);
3199
3200   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3201   vat_json_init_object (node);
3202   vat_json_object_add_uint (node, "value", mp->value);
3203
3204   vat_json_print (vam->ofp, node);
3205   vat_json_free (node);
3206
3207   vam->retval = retval;
3208   vam->result_ready = 1;
3209 }
3210
3211 static void
3212   vl_api_show_one_map_register_state_reply_t_handler
3213   (vl_api_show_one_map_register_state_reply_t * mp)
3214 {
3215   vat_main_t *vam = &vat_main;
3216   int retval = clib_net_to_host_u32 (mp->retval);
3217
3218   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3219
3220   vam->retval = retval;
3221   vam->result_ready = 1;
3222 }
3223
3224 static void
3225   vl_api_show_one_map_register_state_reply_t_handler_json
3226   (vl_api_show_one_map_register_state_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   vat_json_node_t _node, *node = &_node;
3230   int retval = clib_net_to_host_u32 (mp->retval);
3231
3232   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3233
3234   vat_json_init_object (node);
3235   vat_json_object_add_string_copy (node, "state", s);
3236
3237   vat_json_print (vam->ofp, node);
3238   vat_json_free (node);
3239
3240   vam->retval = retval;
3241   vam->result_ready = 1;
3242   vec_free (s);
3243 }
3244
3245 static void
3246   vl_api_show_one_rloc_probe_state_reply_t_handler
3247   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3248 {
3249   vat_main_t *vam = &vat_main;
3250   int retval = clib_net_to_host_u32 (mp->retval);
3251
3252   if (retval)
3253     goto end;
3254
3255   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3256 end:
3257   vam->retval = retval;
3258   vam->result_ready = 1;
3259 }
3260
3261 static void
3262   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3263   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t _node, *node = &_node;
3267   int retval = clib_net_to_host_u32 (mp->retval);
3268
3269   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3270   vat_json_init_object (node);
3271   vat_json_object_add_string_copy (node, "state", s);
3272
3273   vat_json_print (vam->ofp, node);
3274   vat_json_free (node);
3275
3276   vam->retval = retval;
3277   vam->result_ready = 1;
3278   vec_free (s);
3279 }
3280
3281 static void
3282   vl_api_show_one_stats_enable_disable_reply_t_handler
3283   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3284 {
3285   vat_main_t *vam = &vat_main;
3286   int retval = clib_net_to_host_u32 (mp->retval);
3287
3288   if (retval)
3289     goto end;
3290
3291   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3292 end:
3293   vam->retval = retval;
3294   vam->result_ready = 1;
3295 }
3296
3297 static void
3298   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3299   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3300 {
3301   vat_main_t *vam = &vat_main;
3302   vat_json_node_t _node, *node = &_node;
3303   int retval = clib_net_to_host_u32 (mp->retval);
3304
3305   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3306   vat_json_init_object (node);
3307   vat_json_object_add_string_copy (node, "state", s);
3308
3309   vat_json_print (vam->ofp, node);
3310   vat_json_free (node);
3311
3312   vam->retval = retval;
3313   vam->result_ready = 1;
3314   vec_free (s);
3315 }
3316
3317 static void
3318 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3319 {
3320   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3321   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3322   e->vni = clib_net_to_host_u32 (e->vni);
3323 }
3324
3325 static void
3326   gpe_fwd_entries_get_reply_t_net_to_host
3327   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3328 {
3329   u32 i;
3330
3331   mp->count = clib_net_to_host_u32 (mp->count);
3332   for (i = 0; i < mp->count; i++)
3333     {
3334       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3335     }
3336 }
3337
3338 static u8 *
3339 format_gpe_encap_mode (u8 * s, va_list * args)
3340 {
3341   u32 mode = va_arg (*args, u32);
3342
3343   switch (mode)
3344     {
3345     case 0:
3346       return format (s, "lisp");
3347     case 1:
3348       return format (s, "vxlan");
3349     }
3350   return 0;
3351 }
3352
3353 static void
3354   vl_api_gpe_get_encap_mode_reply_t_handler
3355   (vl_api_gpe_get_encap_mode_reply_t * mp)
3356 {
3357   vat_main_t *vam = &vat_main;
3358
3359   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3360   vam->retval = ntohl (mp->retval);
3361   vam->result_ready = 1;
3362 }
3363
3364 static void
3365   vl_api_gpe_get_encap_mode_reply_t_handler_json
3366   (vl_api_gpe_get_encap_mode_reply_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   vat_json_node_t node;
3370
3371   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3372   vec_add1 (encap_mode, 0);
3373
3374   vat_json_init_object (&node);
3375   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3376
3377   vec_free (encap_mode);
3378   vat_json_print (vam->ofp, &node);
3379   vat_json_free (&node);
3380
3381   vam->retval = ntohl (mp->retval);
3382   vam->result_ready = 1;
3383 }
3384
3385 static void
3386   vl_api_gpe_fwd_entry_path_details_t_handler
3387   (vl_api_gpe_fwd_entry_path_details_t * mp)
3388 {
3389   vat_main_t *vam = &vat_main;
3390   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3391
3392   if (mp->lcl_loc.is_ip4)
3393     format_ip_address_fcn = format_ip4_address;
3394   else
3395     format_ip_address_fcn = format_ip6_address;
3396
3397   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3398          format_ip_address_fcn, &mp->lcl_loc,
3399          format_ip_address_fcn, &mp->rmt_loc);
3400 }
3401
3402 static void
3403 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3404 {
3405   struct in6_addr ip6;
3406   struct in_addr ip4;
3407
3408   if (loc->is_ip4)
3409     {
3410       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3411       vat_json_object_add_ip4 (n, "address", ip4);
3412     }
3413   else
3414     {
3415       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3416       vat_json_object_add_ip6 (n, "address", ip6);
3417     }
3418   vat_json_object_add_uint (n, "weight", loc->weight);
3419 }
3420
3421 static void
3422   vl_api_gpe_fwd_entry_path_details_t_handler_json
3423   (vl_api_gpe_fwd_entry_path_details_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   vat_json_node_t *node = NULL;
3427   vat_json_node_t *loc_node;
3428
3429   if (VAT_JSON_ARRAY != vam->json_tree.type)
3430     {
3431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3432       vat_json_init_array (&vam->json_tree);
3433     }
3434   node = vat_json_array_add (&vam->json_tree);
3435   vat_json_init_object (node);
3436
3437   loc_node = vat_json_object_add (node, "local_locator");
3438   vat_json_init_object (loc_node);
3439   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3440
3441   loc_node = vat_json_object_add (node, "remote_locator");
3442   vat_json_init_object (loc_node);
3443   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3444 }
3445
3446 static void
3447   vl_api_gpe_fwd_entries_get_reply_t_handler
3448   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3449 {
3450   vat_main_t *vam = &vat_main;
3451   u32 i;
3452   int retval = clib_net_to_host_u32 (mp->retval);
3453   vl_api_gpe_fwd_entry_t *e;
3454
3455   if (retval)
3456     goto end;
3457
3458   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3459
3460   for (i = 0; i < mp->count; i++)
3461     {
3462       e = &mp->entries[i];
3463       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3464              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3465              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3466     }
3467
3468 end:
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3475   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3476 {
3477   u8 *s = 0;
3478   vat_main_t *vam = &vat_main;
3479   vat_json_node_t *e = 0, root;
3480   u32 i;
3481   int retval = clib_net_to_host_u32 (mp->retval);
3482   vl_api_gpe_fwd_entry_t *fwd;
3483
3484   if (retval)
3485     goto end;
3486
3487   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3488   vat_json_init_array (&root);
3489
3490   for (i = 0; i < mp->count; i++)
3491     {
3492       e = vat_json_array_add (&root);
3493       fwd = &mp->entries[i];
3494
3495       vat_json_init_object (e);
3496       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3497       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3498       vat_json_object_add_int (e, "vni", fwd->vni);
3499       vat_json_object_add_int (e, "action", fwd->action);
3500
3501       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3502                   fwd->leid_prefix_len);
3503       vec_add1 (s, 0);
3504       vat_json_object_add_string_copy (e, "leid", s);
3505       vec_free (s);
3506
3507       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3508                   fwd->reid_prefix_len);
3509       vec_add1 (s, 0);
3510       vat_json_object_add_string_copy (e, "reid", s);
3511       vec_free (s);
3512     }
3513
3514   vat_json_print (vam->ofp, &root);
3515   vat_json_free (&root);
3516
3517 end:
3518   vam->retval = retval;
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3524   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   u32 i, n;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_native_fwd_rpath_t *r;
3530
3531   if (retval)
3532     goto end;
3533
3534   n = clib_net_to_host_u32 (mp->count);
3535
3536   for (i = 0; i < n; i++)
3537     {
3538       r = &mp->entries[i];
3539       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3540              clib_net_to_host_u32 (r->fib_index),
3541              clib_net_to_host_u32 (r->nh_sw_if_index),
3542              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3543     }
3544
3545 end:
3546   vam->retval = retval;
3547   vam->result_ready = 1;
3548 }
3549
3550 static void
3551   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3552   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3553 {
3554   vat_main_t *vam = &vat_main;
3555   vat_json_node_t root, *e;
3556   u32 i, n;
3557   int retval = clib_net_to_host_u32 (mp->retval);
3558   vl_api_gpe_native_fwd_rpath_t *r;
3559   u8 *s;
3560
3561   if (retval)
3562     goto end;
3563
3564   n = clib_net_to_host_u32 (mp->count);
3565   vat_json_init_array (&root);
3566
3567   for (i = 0; i < n; i++)
3568     {
3569       e = vat_json_array_add (&root);
3570       vat_json_init_object (e);
3571       r = &mp->entries[i];
3572       s =
3573         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3574                 r->nh_addr);
3575       vec_add1 (s, 0);
3576       vat_json_object_add_string_copy (e, "ip4", s);
3577       vec_free (s);
3578
3579       vat_json_object_add_uint (e, "fib_index",
3580                                 clib_net_to_host_u32 (r->fib_index));
3581       vat_json_object_add_uint (e, "nh_sw_if_index",
3582                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3583     }
3584
3585   vat_json_print (vam->ofp, &root);
3586   vat_json_free (&root);
3587
3588 end:
3589   vam->retval = retval;
3590   vam->result_ready = 1;
3591 }
3592
3593 static void
3594   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3595   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   u32 i, n;
3599   int retval = clib_net_to_host_u32 (mp->retval);
3600
3601   if (retval)
3602     goto end;
3603
3604   n = clib_net_to_host_u32 (mp->count);
3605
3606   for (i = 0; i < n; i++)
3607     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3608
3609 end:
3610   vam->retval = retval;
3611   vam->result_ready = 1;
3612 }
3613
3614 static void
3615   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3616   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   vat_json_node_t root;
3620   u32 i, n;
3621   int retval = clib_net_to_host_u32 (mp->retval);
3622
3623   if (retval)
3624     goto end;
3625
3626   n = clib_net_to_host_u32 (mp->count);
3627   vat_json_init_array (&root);
3628
3629   for (i = 0; i < n; i++)
3630     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3631
3632   vat_json_print (vam->ofp, &root);
3633   vat_json_free (&root);
3634
3635 end:
3636   vam->retval = retval;
3637   vam->result_ready = 1;
3638 }
3639
3640 static void
3641   vl_api_one_ndp_entries_get_reply_t_handler
3642   (vl_api_one_ndp_entries_get_reply_t * mp)
3643 {
3644   vat_main_t *vam = &vat_main;
3645   u32 i, n;
3646   int retval = clib_net_to_host_u32 (mp->retval);
3647
3648   if (retval)
3649     goto end;
3650
3651   n = clib_net_to_host_u32 (mp->count);
3652
3653   for (i = 0; i < n; i++)
3654     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3655            format_ethernet_address, mp->entries[i].mac);
3656
3657 end:
3658   vam->retval = retval;
3659   vam->result_ready = 1;
3660 }
3661
3662 static void
3663   vl_api_one_ndp_entries_get_reply_t_handler_json
3664   (vl_api_one_ndp_entries_get_reply_t * mp)
3665 {
3666   u8 *s = 0;
3667   vat_main_t *vam = &vat_main;
3668   vat_json_node_t *e = 0, root;
3669   u32 i, n;
3670   int retval = clib_net_to_host_u32 (mp->retval);
3671   vl_api_one_ndp_entry_t *arp_entry;
3672
3673   if (retval)
3674     goto end;
3675
3676   n = clib_net_to_host_u32 (mp->count);
3677   vat_json_init_array (&root);
3678
3679   for (i = 0; i < n; i++)
3680     {
3681       e = vat_json_array_add (&root);
3682       arp_entry = &mp->entries[i];
3683
3684       vat_json_init_object (e);
3685       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3686       vec_add1 (s, 0);
3687
3688       vat_json_object_add_string_copy (e, "mac", s);
3689       vec_free (s);
3690
3691       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3692       vec_add1 (s, 0);
3693       vat_json_object_add_string_copy (e, "ip6", s);
3694       vec_free (s);
3695     }
3696
3697   vat_json_print (vam->ofp, &root);
3698   vat_json_free (&root);
3699
3700 end:
3701   vam->retval = retval;
3702   vam->result_ready = 1;
3703 }
3704
3705 static void
3706   vl_api_one_l2_arp_entries_get_reply_t_handler
3707   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3708 {
3709   vat_main_t *vam = &vat_main;
3710   u32 i, n;
3711   int retval = clib_net_to_host_u32 (mp->retval);
3712
3713   if (retval)
3714     goto end;
3715
3716   n = clib_net_to_host_u32 (mp->count);
3717
3718   for (i = 0; i < n; i++)
3719     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3720            format_ethernet_address, mp->entries[i].mac);
3721
3722 end:
3723   vam->retval = retval;
3724   vam->result_ready = 1;
3725 }
3726
3727 static void
3728   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3729   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3730 {
3731   u8 *s = 0;
3732   vat_main_t *vam = &vat_main;
3733   vat_json_node_t *e = 0, root;
3734   u32 i, n;
3735   int retval = clib_net_to_host_u32 (mp->retval);
3736   vl_api_one_l2_arp_entry_t *arp_entry;
3737
3738   if (retval)
3739     goto end;
3740
3741   n = clib_net_to_host_u32 (mp->count);
3742   vat_json_init_array (&root);
3743
3744   for (i = 0; i < n; i++)
3745     {
3746       e = vat_json_array_add (&root);
3747       arp_entry = &mp->entries[i];
3748
3749       vat_json_init_object (e);
3750       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3751       vec_add1 (s, 0);
3752
3753       vat_json_object_add_string_copy (e, "mac", s);
3754       vec_free (s);
3755
3756       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3757       vec_add1 (s, 0);
3758       vat_json_object_add_string_copy (e, "ip4", s);
3759       vec_free (s);
3760     }
3761
3762   vat_json_print (vam->ofp, &root);
3763   vat_json_free (&root);
3764
3765 end:
3766   vam->retval = retval;
3767   vam->result_ready = 1;
3768 }
3769
3770 static void
3771 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3772 {
3773   vat_main_t *vam = &vat_main;
3774   u32 i, n;
3775   int retval = clib_net_to_host_u32 (mp->retval);
3776
3777   if (retval)
3778     goto end;
3779
3780   n = clib_net_to_host_u32 (mp->count);
3781
3782   for (i = 0; i < n; i++)
3783     {
3784       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3785     }
3786
3787 end:
3788   vam->retval = retval;
3789   vam->result_ready = 1;
3790 }
3791
3792 static void
3793   vl_api_one_ndp_bd_get_reply_t_handler_json
3794   (vl_api_one_ndp_bd_get_reply_t * mp)
3795 {
3796   vat_main_t *vam = &vat_main;
3797   vat_json_node_t root;
3798   u32 i, n;
3799   int retval = clib_net_to_host_u32 (mp->retval);
3800
3801   if (retval)
3802     goto end;
3803
3804   n = clib_net_to_host_u32 (mp->count);
3805   vat_json_init_array (&root);
3806
3807   for (i = 0; i < n; i++)
3808     {
3809       vat_json_array_add_uint (&root,
3810                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3811     }
3812
3813   vat_json_print (vam->ofp, &root);
3814   vat_json_free (&root);
3815
3816 end:
3817   vam->retval = retval;
3818   vam->result_ready = 1;
3819 }
3820
3821 static void
3822   vl_api_one_l2_arp_bd_get_reply_t_handler
3823   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3824 {
3825   vat_main_t *vam = &vat_main;
3826   u32 i, n;
3827   int retval = clib_net_to_host_u32 (mp->retval);
3828
3829   if (retval)
3830     goto end;
3831
3832   n = clib_net_to_host_u32 (mp->count);
3833
3834   for (i = 0; i < n; i++)
3835     {
3836       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3837     }
3838
3839 end:
3840   vam->retval = retval;
3841   vam->result_ready = 1;
3842 }
3843
3844 static void
3845   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3846   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3847 {
3848   vat_main_t *vam = &vat_main;
3849   vat_json_node_t root;
3850   u32 i, n;
3851   int retval = clib_net_to_host_u32 (mp->retval);
3852
3853   if (retval)
3854     goto end;
3855
3856   n = clib_net_to_host_u32 (mp->count);
3857   vat_json_init_array (&root);
3858
3859   for (i = 0; i < n; i++)
3860     {
3861       vat_json_array_add_uint (&root,
3862                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3863     }
3864
3865   vat_json_print (vam->ofp, &root);
3866   vat_json_free (&root);
3867
3868 end:
3869   vam->retval = retval;
3870   vam->result_ready = 1;
3871 }
3872
3873 static void
3874   vl_api_one_adjacencies_get_reply_t_handler
3875   (vl_api_one_adjacencies_get_reply_t * mp)
3876 {
3877   vat_main_t *vam = &vat_main;
3878   u32 i, n;
3879   int retval = clib_net_to_host_u32 (mp->retval);
3880   vl_api_one_adjacency_t *a;
3881
3882   if (retval)
3883     goto end;
3884
3885   n = clib_net_to_host_u32 (mp->count);
3886
3887   for (i = 0; i < n; i++)
3888     {
3889       a = &mp->adjacencies[i];
3890       print (vam->ofp, "%U %40U",
3891              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3892              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3893     }
3894
3895 end:
3896   vam->retval = retval;
3897   vam->result_ready = 1;
3898 }
3899
3900 static void
3901   vl_api_one_adjacencies_get_reply_t_handler_json
3902   (vl_api_one_adjacencies_get_reply_t * mp)
3903 {
3904   u8 *s = 0;
3905   vat_main_t *vam = &vat_main;
3906   vat_json_node_t *e = 0, root;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909   vl_api_one_adjacency_t *a;
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915   vat_json_init_array (&root);
3916
3917   for (i = 0; i < n; i++)
3918     {
3919       e = vat_json_array_add (&root);
3920       a = &mp->adjacencies[i];
3921
3922       vat_json_init_object (e);
3923       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3924                   a->leid_prefix_len);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "leid", s);
3927       vec_free (s);
3928
3929       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3930                   a->reid_prefix_len);
3931       vec_add1 (s, 0);
3932       vat_json_object_add_string_copy (e, "reid", s);
3933       vec_free (s);
3934     }
3935
3936   vat_json_print (vam->ofp, &root);
3937   vat_json_free (&root);
3938
3939 end:
3940   vam->retval = retval;
3941   vam->result_ready = 1;
3942 }
3943
3944 static void
3945 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948
3949   print (vam->ofp, "%=20U",
3950          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3951          mp->ip_address);
3952 }
3953
3954 static void
3955   vl_api_one_map_server_details_t_handler_json
3956   (vl_api_one_map_server_details_t * mp)
3957 {
3958   vat_main_t *vam = &vat_main;
3959   vat_json_node_t *node = NULL;
3960   struct in6_addr ip6;
3961   struct in_addr ip4;
3962
3963   if (VAT_JSON_ARRAY != vam->json_tree.type)
3964     {
3965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3966       vat_json_init_array (&vam->json_tree);
3967     }
3968   node = vat_json_array_add (&vam->json_tree);
3969
3970   vat_json_init_object (node);
3971   if (mp->is_ipv6)
3972     {
3973       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3974       vat_json_object_add_ip6 (node, "map-server", ip6);
3975     }
3976   else
3977     {
3978       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3979       vat_json_object_add_ip4 (node, "map-server", ip4);
3980     }
3981 }
3982
3983 static void
3984 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3985                                            * mp)
3986 {
3987   vat_main_t *vam = &vat_main;
3988
3989   print (vam->ofp, "%=20U",
3990          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3991          mp->ip_address);
3992 }
3993
3994 static void
3995   vl_api_one_map_resolver_details_t_handler_json
3996   (vl_api_one_map_resolver_details_t * mp)
3997 {
3998   vat_main_t *vam = &vat_main;
3999   vat_json_node_t *node = NULL;
4000   struct in6_addr ip6;
4001   struct in_addr ip4;
4002
4003   if (VAT_JSON_ARRAY != vam->json_tree.type)
4004     {
4005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4006       vat_json_init_array (&vam->json_tree);
4007     }
4008   node = vat_json_array_add (&vam->json_tree);
4009
4010   vat_json_init_object (node);
4011   if (mp->is_ipv6)
4012     {
4013       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4014       vat_json_object_add_ip6 (node, "map resolver", ip6);
4015     }
4016   else
4017     {
4018       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4019       vat_json_object_add_ip4 (node, "map resolver", ip4);
4020     }
4021 }
4022
4023 static void
4024 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4025 {
4026   vat_main_t *vam = &vat_main;
4027   i32 retval = ntohl (mp->retval);
4028
4029   if (0 <= retval)
4030     {
4031       print (vam->ofp, "feature: %s\ngpe: %s",
4032              mp->feature_status ? "enabled" : "disabled",
4033              mp->gpe_status ? "enabled" : "disabled");
4034     }
4035
4036   vam->retval = retval;
4037   vam->result_ready = 1;
4038 }
4039
4040 static void
4041   vl_api_show_one_status_reply_t_handler_json
4042   (vl_api_show_one_status_reply_t * mp)
4043 {
4044   vat_main_t *vam = &vat_main;
4045   vat_json_node_t node;
4046   u8 *gpe_status = NULL;
4047   u8 *feature_status = NULL;
4048
4049   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4050   feature_status = format (0, "%s",
4051                            mp->feature_status ? "enabled" : "disabled");
4052   vec_add1 (gpe_status, 0);
4053   vec_add1 (feature_status, 0);
4054
4055   vat_json_init_object (&node);
4056   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4057   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4058
4059   vec_free (gpe_status);
4060   vec_free (feature_status);
4061
4062   vat_json_print (vam->ofp, &node);
4063   vat_json_free (&node);
4064
4065   vam->retval = ntohl (mp->retval);
4066   vam->result_ready = 1;
4067 }
4068
4069 static void
4070   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4071   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   i32 retval = ntohl (mp->retval);
4075
4076   if (retval >= 0)
4077     {
4078       print (vam->ofp, "%=20s", mp->locator_set_name);
4079     }
4080
4081   vam->retval = retval;
4082   vam->result_ready = 1;
4083 }
4084
4085 static void
4086   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4087   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4088 {
4089   vat_main_t *vam = &vat_main;
4090   vat_json_node_t *node = NULL;
4091
4092   if (VAT_JSON_ARRAY != vam->json_tree.type)
4093     {
4094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4095       vat_json_init_array (&vam->json_tree);
4096     }
4097   node = vat_json_array_add (&vam->json_tree);
4098
4099   vat_json_init_object (node);
4100   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4101
4102   vat_json_print (vam->ofp, node);
4103   vat_json_free (node);
4104
4105   vam->retval = ntohl (mp->retval);
4106   vam->result_ready = 1;
4107 }
4108
4109 static u8 *
4110 format_lisp_map_request_mode (u8 * s, va_list * args)
4111 {
4112   u32 mode = va_arg (*args, u32);
4113
4114   switch (mode)
4115     {
4116     case 0:
4117       return format (0, "dst-only");
4118     case 1:
4119       return format (0, "src-dst");
4120     }
4121   return 0;
4122 }
4123
4124 static void
4125   vl_api_show_one_map_request_mode_reply_t_handler
4126   (vl_api_show_one_map_request_mode_reply_t * mp)
4127 {
4128   vat_main_t *vam = &vat_main;
4129   i32 retval = ntohl (mp->retval);
4130
4131   if (0 <= retval)
4132     {
4133       u32 mode = mp->mode;
4134       print (vam->ofp, "map_request_mode: %U",
4135              format_lisp_map_request_mode, mode);
4136     }
4137
4138   vam->retval = retval;
4139   vam->result_ready = 1;
4140 }
4141
4142 static void
4143   vl_api_show_one_map_request_mode_reply_t_handler_json
4144   (vl_api_show_one_map_request_mode_reply_t * mp)
4145 {
4146   vat_main_t *vam = &vat_main;
4147   vat_json_node_t node;
4148   u8 *s = 0;
4149   u32 mode;
4150
4151   mode = mp->mode;
4152   s = format (0, "%U", format_lisp_map_request_mode, mode);
4153   vec_add1 (s, 0);
4154
4155   vat_json_init_object (&node);
4156   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4157   vat_json_print (vam->ofp, &node);
4158   vat_json_free (&node);
4159
4160   vec_free (s);
4161   vam->retval = ntohl (mp->retval);
4162   vam->result_ready = 1;
4163 }
4164
4165 static void
4166   vl_api_one_show_xtr_mode_reply_t_handler
4167   (vl_api_one_show_xtr_mode_reply_t * mp)
4168 {
4169   vat_main_t *vam = &vat_main;
4170   i32 retval = ntohl (mp->retval);
4171
4172   if (0 <= retval)
4173     {
4174       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4175     }
4176
4177   vam->retval = retval;
4178   vam->result_ready = 1;
4179 }
4180
4181 static void
4182   vl_api_one_show_xtr_mode_reply_t_handler_json
4183   (vl_api_one_show_xtr_mode_reply_t * mp)
4184 {
4185   vat_main_t *vam = &vat_main;
4186   vat_json_node_t node;
4187   u8 *status = 0;
4188
4189   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4190   vec_add1 (status, 0);
4191
4192   vat_json_init_object (&node);
4193   vat_json_object_add_string_copy (&node, "status", status);
4194
4195   vec_free (status);
4196
4197   vat_json_print (vam->ofp, &node);
4198   vat_json_free (&node);
4199
4200   vam->retval = ntohl (mp->retval);
4201   vam->result_ready = 1;
4202 }
4203
4204 static void
4205   vl_api_one_show_pitr_mode_reply_t_handler
4206   (vl_api_one_show_pitr_mode_reply_t * mp)
4207 {
4208   vat_main_t *vam = &vat_main;
4209   i32 retval = ntohl (mp->retval);
4210
4211   if (0 <= retval)
4212     {
4213       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4214     }
4215
4216   vam->retval = retval;
4217   vam->result_ready = 1;
4218 }
4219
4220 static void
4221   vl_api_one_show_pitr_mode_reply_t_handler_json
4222   (vl_api_one_show_pitr_mode_reply_t * mp)
4223 {
4224   vat_main_t *vam = &vat_main;
4225   vat_json_node_t node;
4226   u8 *status = 0;
4227
4228   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4229   vec_add1 (status, 0);
4230
4231   vat_json_init_object (&node);
4232   vat_json_object_add_string_copy (&node, "status", status);
4233
4234   vec_free (status);
4235
4236   vat_json_print (vam->ofp, &node);
4237   vat_json_free (&node);
4238
4239   vam->retval = ntohl (mp->retval);
4240   vam->result_ready = 1;
4241 }
4242
4243 static void
4244   vl_api_one_show_petr_mode_reply_t_handler
4245   (vl_api_one_show_petr_mode_reply_t * mp)
4246 {
4247   vat_main_t *vam = &vat_main;
4248   i32 retval = ntohl (mp->retval);
4249
4250   if (0 <= retval)
4251     {
4252       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4253     }
4254
4255   vam->retval = retval;
4256   vam->result_ready = 1;
4257 }
4258
4259 static void
4260   vl_api_one_show_petr_mode_reply_t_handler_json
4261   (vl_api_one_show_petr_mode_reply_t * mp)
4262 {
4263   vat_main_t *vam = &vat_main;
4264   vat_json_node_t node;
4265   u8 *status = 0;
4266
4267   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4268   vec_add1 (status, 0);
4269
4270   vat_json_init_object (&node);
4271   vat_json_object_add_string_copy (&node, "status", status);
4272
4273   vec_free (status);
4274
4275   vat_json_print (vam->ofp, &node);
4276   vat_json_free (&node);
4277
4278   vam->retval = ntohl (mp->retval);
4279   vam->result_ready = 1;
4280 }
4281
4282 static void
4283   vl_api_show_one_use_petr_reply_t_handler
4284   (vl_api_show_one_use_petr_reply_t * mp)
4285 {
4286   vat_main_t *vam = &vat_main;
4287   i32 retval = ntohl (mp->retval);
4288
4289   if (0 <= retval)
4290     {
4291       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4292       if (mp->status)
4293         {
4294           print (vam->ofp, "Proxy-ETR address; %U",
4295                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4296                  mp->address);
4297         }
4298     }
4299
4300   vam->retval = retval;
4301   vam->result_ready = 1;
4302 }
4303
4304 static void
4305   vl_api_show_one_use_petr_reply_t_handler_json
4306   (vl_api_show_one_use_petr_reply_t * mp)
4307 {
4308   vat_main_t *vam = &vat_main;
4309   vat_json_node_t node;
4310   u8 *status = 0;
4311   struct in_addr ip4;
4312   struct in6_addr ip6;
4313
4314   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4315   vec_add1 (status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "status", status);
4319   if (mp->status)
4320     {
4321       if (mp->is_ip4)
4322         {
4323           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4324           vat_json_object_add_ip6 (&node, "address", ip6);
4325         }
4326       else
4327         {
4328           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4329           vat_json_object_add_ip4 (&node, "address", ip4);
4330         }
4331     }
4332
4333   vec_free (status);
4334
4335   vat_json_print (vam->ofp, &node);
4336   vat_json_free (&node);
4337
4338   vam->retval = ntohl (mp->retval);
4339   vam->result_ready = 1;
4340 }
4341
4342 static void
4343   vl_api_show_one_nsh_mapping_reply_t_handler
4344   (vl_api_show_one_nsh_mapping_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   i32 retval = ntohl (mp->retval);
4348
4349   if (0 <= retval)
4350     {
4351       print (vam->ofp, "%-20s%-16s",
4352              mp->is_set ? "set" : "not-set",
4353              mp->is_set ? (char *) mp->locator_set_name : "");
4354     }
4355
4356   vam->retval = retval;
4357   vam->result_ready = 1;
4358 }
4359
4360 static void
4361   vl_api_show_one_nsh_mapping_reply_t_handler_json
4362   (vl_api_show_one_nsh_mapping_reply_t * mp)
4363 {
4364   vat_main_t *vam = &vat_main;
4365   vat_json_node_t node;
4366   u8 *status = 0;
4367
4368   status = format (0, "%s", mp->is_set ? "yes" : "no");
4369   vec_add1 (status, 0);
4370
4371   vat_json_init_object (&node);
4372   vat_json_object_add_string_copy (&node, "is_set", status);
4373   if (mp->is_set)
4374     {
4375       vat_json_object_add_string_copy (&node, "locator_set",
4376                                        mp->locator_set_name);
4377     }
4378
4379   vec_free (status);
4380
4381   vat_json_print (vam->ofp, &node);
4382   vat_json_free (&node);
4383
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_show_one_map_register_ttl_reply_t_handler
4390   (vl_api_show_one_map_register_ttl_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   i32 retval = ntohl (mp->retval);
4394
4395   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4396
4397   if (0 <= retval)
4398     {
4399       print (vam->ofp, "ttl: %u", mp->ttl);
4400     }
4401
4402   vam->retval = retval;
4403   vam->result_ready = 1;
4404 }
4405
4406 static void
4407   vl_api_show_one_map_register_ttl_reply_t_handler_json
4408   (vl_api_show_one_map_register_ttl_reply_t * mp)
4409 {
4410   vat_main_t *vam = &vat_main;
4411   vat_json_node_t node;
4412
4413   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4414   vat_json_init_object (&node);
4415   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4416
4417   vat_json_print (vam->ofp, &node);
4418   vat_json_free (&node);
4419
4420   vam->retval = ntohl (mp->retval);
4421   vam->result_ready = 1;
4422 }
4423
4424 static void
4425 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4426 {
4427   vat_main_t *vam = &vat_main;
4428   i32 retval = ntohl (mp->retval);
4429
4430   if (0 <= retval)
4431     {
4432       print (vam->ofp, "%-20s%-16s",
4433              mp->status ? "enabled" : "disabled",
4434              mp->status ? (char *) mp->locator_set_name : "");
4435     }
4436
4437   vam->retval = retval;
4438   vam->result_ready = 1;
4439 }
4440
4441 static void
4442 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4443 {
4444   vat_main_t *vam = &vat_main;
4445   vat_json_node_t node;
4446   u8 *status = 0;
4447
4448   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4449   vec_add1 (status, 0);
4450
4451   vat_json_init_object (&node);
4452   vat_json_object_add_string_copy (&node, "status", status);
4453   if (mp->status)
4454     {
4455       vat_json_object_add_string_copy (&node, "locator_set",
4456                                        mp->locator_set_name);
4457     }
4458
4459   vec_free (status);
4460
4461   vat_json_print (vam->ofp, &node);
4462   vat_json_free (&node);
4463
4464   vam->retval = ntohl (mp->retval);
4465   vam->result_ready = 1;
4466 }
4467
4468 static u8 *
4469 format_policer_type (u8 * s, va_list * va)
4470 {
4471   u32 i = va_arg (*va, u32);
4472
4473   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4474     s = format (s, "1r2c");
4475   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4476     s = format (s, "1r3c");
4477   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4478     s = format (s, "2r3c-2698");
4479   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4480     s = format (s, "2r3c-4115");
4481   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4482     s = format (s, "2r3c-mef5cf1");
4483   else
4484     s = format (s, "ILLEGAL");
4485   return s;
4486 }
4487
4488 static u8 *
4489 format_policer_rate_type (u8 * s, va_list * va)
4490 {
4491   u32 i = va_arg (*va, u32);
4492
4493   if (i == SSE2_QOS_RATE_KBPS)
4494     s = format (s, "kbps");
4495   else if (i == SSE2_QOS_RATE_PPS)
4496     s = format (s, "pps");
4497   else
4498     s = format (s, "ILLEGAL");
4499   return s;
4500 }
4501
4502 static u8 *
4503 format_policer_round_type (u8 * s, va_list * va)
4504 {
4505   u32 i = va_arg (*va, u32);
4506
4507   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4508     s = format (s, "closest");
4509   else if (i == SSE2_QOS_ROUND_TO_UP)
4510     s = format (s, "up");
4511   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4512     s = format (s, "down");
4513   else
4514     s = format (s, "ILLEGAL");
4515   return s;
4516 }
4517
4518 static u8 *
4519 format_policer_action_type (u8 * s, va_list * va)
4520 {
4521   u32 i = va_arg (*va, u32);
4522
4523   if (i == SSE2_QOS_ACTION_DROP)
4524     s = format (s, "drop");
4525   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4526     s = format (s, "transmit");
4527   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4528     s = format (s, "mark-and-transmit");
4529   else
4530     s = format (s, "ILLEGAL");
4531   return s;
4532 }
4533
4534 static u8 *
4535 format_dscp (u8 * s, va_list * va)
4536 {
4537   u32 i = va_arg (*va, u32);
4538   char *t = 0;
4539
4540   switch (i)
4541     {
4542 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4543       foreach_vnet_dscp
4544 #undef _
4545     default:
4546       return format (s, "ILLEGAL");
4547     }
4548   s = format (s, "%s", t);
4549   return s;
4550 }
4551
4552 static void
4553 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4554 {
4555   vat_main_t *vam = &vat_main;
4556   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4557
4558   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4559     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4560   else
4561     conform_dscp_str = format (0, "");
4562
4563   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4564     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4565   else
4566     exceed_dscp_str = format (0, "");
4567
4568   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4569     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4570   else
4571     violate_dscp_str = format (0, "");
4572
4573   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4574          "rate type %U, round type %U, %s rate, %s color-aware, "
4575          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4576          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4577          "conform action %U%s, exceed action %U%s, violate action %U%s",
4578          mp->name,
4579          format_policer_type, mp->type,
4580          ntohl (mp->cir),
4581          ntohl (mp->eir),
4582          clib_net_to_host_u64 (mp->cb),
4583          clib_net_to_host_u64 (mp->eb),
4584          format_policer_rate_type, mp->rate_type,
4585          format_policer_round_type, mp->round_type,
4586          mp->single_rate ? "single" : "dual",
4587          mp->color_aware ? "is" : "not",
4588          ntohl (mp->cir_tokens_per_period),
4589          ntohl (mp->pir_tokens_per_period),
4590          ntohl (mp->scale),
4591          ntohl (mp->current_limit),
4592          ntohl (mp->current_bucket),
4593          ntohl (mp->extended_limit),
4594          ntohl (mp->extended_bucket),
4595          clib_net_to_host_u64 (mp->last_update_time),
4596          format_policer_action_type, mp->conform_action.type,
4597          conform_dscp_str,
4598          format_policer_action_type, mp->exceed_action.type,
4599          exceed_dscp_str,
4600          format_policer_action_type, mp->violate_action.type,
4601          violate_dscp_str);
4602
4603   vec_free (conform_dscp_str);
4604   vec_free (exceed_dscp_str);
4605   vec_free (violate_dscp_str);
4606 }
4607
4608 static void vl_api_policer_details_t_handler_json
4609   (vl_api_policer_details_t * mp)
4610 {
4611   vat_main_t *vam = &vat_main;
4612   vat_json_node_t *node;
4613   u8 *rate_type_str, *round_type_str, *type_str;
4614   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4615
4616   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4617   round_type_str =
4618     format (0, "%U", format_policer_round_type, mp->round_type);
4619   type_str = format (0, "%U", format_policer_type, mp->type);
4620   conform_action_str = format (0, "%U", format_policer_action_type,
4621                                mp->conform_action.type);
4622   exceed_action_str = format (0, "%U", format_policer_action_type,
4623                               mp->exceed_action.type);
4624   violate_action_str = format (0, "%U", format_policer_action_type,
4625                                mp->violate_action.type);
4626
4627   if (VAT_JSON_ARRAY != vam->json_tree.type)
4628     {
4629       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4630       vat_json_init_array (&vam->json_tree);
4631     }
4632   node = vat_json_array_add (&vam->json_tree);
4633
4634   vat_json_init_object (node);
4635   vat_json_object_add_string_copy (node, "name", mp->name);
4636   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4637   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4638   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4639   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4640   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4641   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4642   vat_json_object_add_string_copy (node, "type", type_str);
4643   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4644   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4645   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4646   vat_json_object_add_uint (node, "cir_tokens_per_period",
4647                             ntohl (mp->cir_tokens_per_period));
4648   vat_json_object_add_uint (node, "eir_tokens_per_period",
4649                             ntohl (mp->pir_tokens_per_period));
4650   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4651   vat_json_object_add_uint (node, "current_bucket",
4652                             ntohl (mp->current_bucket));
4653   vat_json_object_add_uint (node, "extended_limit",
4654                             ntohl (mp->extended_limit));
4655   vat_json_object_add_uint (node, "extended_bucket",
4656                             ntohl (mp->extended_bucket));
4657   vat_json_object_add_uint (node, "last_update_time",
4658                             ntohl (mp->last_update_time));
4659   vat_json_object_add_string_copy (node, "conform_action",
4660                                    conform_action_str);
4661   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4662     {
4663       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4664       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4665       vec_free (dscp_str);
4666     }
4667   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4668   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4671       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674   vat_json_object_add_string_copy (node, "violate_action",
4675                                    violate_action_str);
4676   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4677     {
4678       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4679       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4680       vec_free (dscp_str);
4681     }
4682
4683   vec_free (rate_type_str);
4684   vec_free (round_type_str);
4685   vec_free (type_str);
4686   vec_free (conform_action_str);
4687   vec_free (exceed_action_str);
4688   vec_free (violate_action_str);
4689 }
4690
4691 static void
4692 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4693                                            mp)
4694 {
4695   vat_main_t *vam = &vat_main;
4696   int i, count = ntohl (mp->count);
4697
4698   if (count > 0)
4699     print (vam->ofp, "classify table ids (%d) : ", count);
4700   for (i = 0; i < count; i++)
4701     {
4702       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4703       print (vam->ofp, (i < count - 1) ? "," : "");
4704     }
4705   vam->retval = ntohl (mp->retval);
4706   vam->result_ready = 1;
4707 }
4708
4709 static void
4710   vl_api_classify_table_ids_reply_t_handler_json
4711   (vl_api_classify_table_ids_reply_t * mp)
4712 {
4713   vat_main_t *vam = &vat_main;
4714   int i, count = ntohl (mp->count);
4715
4716   if (count > 0)
4717     {
4718       vat_json_node_t node;
4719
4720       vat_json_init_object (&node);
4721       for (i = 0; i < count; i++)
4722         {
4723           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4724         }
4725       vat_json_print (vam->ofp, &node);
4726       vat_json_free (&node);
4727     }
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   u32 table_id;
4738
4739   table_id = ntohl (mp->l2_table_id);
4740   if (table_id != ~0)
4741     print (vam->ofp, "l2 table id : %d", table_id);
4742   else
4743     print (vam->ofp, "l2 table id : No input ACL tables configured");
4744   table_id = ntohl (mp->ip4_table_id);
4745   if (table_id != ~0)
4746     print (vam->ofp, "ip4 table id : %d", table_id);
4747   else
4748     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4749   table_id = ntohl (mp->ip6_table_id);
4750   if (table_id != ~0)
4751     print (vam->ofp, "ip6 table id : %d", table_id);
4752   else
4753     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4754   vam->retval = ntohl (mp->retval);
4755   vam->result_ready = 1;
4756 }
4757
4758 static void
4759   vl_api_classify_table_by_interface_reply_t_handler_json
4760   (vl_api_classify_table_by_interface_reply_t * mp)
4761 {
4762   vat_main_t *vam = &vat_main;
4763   vat_json_node_t node;
4764
4765   vat_json_init_object (&node);
4766
4767   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4768   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4769   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4770
4771   vat_json_print (vam->ofp, &node);
4772   vat_json_free (&node);
4773
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static void vl_api_policer_add_del_reply_t_handler
4779   (vl_api_policer_add_del_reply_t * mp)
4780 {
4781   vat_main_t *vam = &vat_main;
4782   i32 retval = ntohl (mp->retval);
4783   if (vam->async_mode)
4784     {
4785       vam->async_errors += (retval < 0);
4786     }
4787   else
4788     {
4789       vam->retval = retval;
4790       vam->result_ready = 1;
4791       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4792         /*
4793          * Note: this is just barely thread-safe, depends on
4794          * the main thread spinning waiting for an answer...
4795          */
4796         errmsg ("policer index %d", ntohl (mp->policer_index));
4797     }
4798 }
4799
4800 static void vl_api_policer_add_del_reply_t_handler_json
4801   (vl_api_policer_add_del_reply_t * mp)
4802 {
4803   vat_main_t *vam = &vat_main;
4804   vat_json_node_t node;
4805
4806   vat_json_init_object (&node);
4807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4808   vat_json_object_add_uint (&node, "policer_index",
4809                             ntohl (mp->policer_index));
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 /* Format hex dump. */
4819 u8 *
4820 format_hex_bytes (u8 * s, va_list * va)
4821 {
4822   u8 *bytes = va_arg (*va, u8 *);
4823   int n_bytes = va_arg (*va, int);
4824   uword i;
4825
4826   /* Print short or long form depending on byte count. */
4827   uword short_form = n_bytes <= 32;
4828   u32 indent = format_get_indent (s);
4829
4830   if (n_bytes == 0)
4831     return s;
4832
4833   for (i = 0; i < n_bytes; i++)
4834     {
4835       if (!short_form && (i % 32) == 0)
4836         s = format (s, "%08x: ", i);
4837       s = format (s, "%02x", bytes[i]);
4838       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4839         s = format (s, "\n%U", format_white_space, indent);
4840     }
4841
4842   return s;
4843 }
4844
4845 static void
4846 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4847                                             * mp)
4848 {
4849   vat_main_t *vam = &vat_main;
4850   i32 retval = ntohl (mp->retval);
4851   if (retval == 0)
4852     {
4853       print (vam->ofp, "classify table info :");
4854       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4855              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4856              ntohl (mp->miss_next_index));
4857       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4858              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4859              ntohl (mp->match_n_vectors));
4860       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4861              ntohl (mp->mask_length));
4862     }
4863   vam->retval = retval;
4864   vam->result_ready = 1;
4865 }
4866
4867 static void
4868   vl_api_classify_table_info_reply_t_handler_json
4869   (vl_api_classify_table_info_reply_t * mp)
4870 {
4871   vat_main_t *vam = &vat_main;
4872   vat_json_node_t node;
4873
4874   i32 retval = ntohl (mp->retval);
4875   if (retval == 0)
4876     {
4877       vat_json_init_object (&node);
4878
4879       vat_json_object_add_int (&node, "sessions",
4880                                ntohl (mp->active_sessions));
4881       vat_json_object_add_int (&node, "nexttbl",
4882                                ntohl (mp->next_table_index));
4883       vat_json_object_add_int (&node, "nextnode",
4884                                ntohl (mp->miss_next_index));
4885       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4886       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4887       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4888       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4889                       ntohl (mp->mask_length), 0);
4890       vat_json_object_add_string_copy (&node, "mask", s);
4891
4892       vat_json_print (vam->ofp, &node);
4893       vat_json_free (&node);
4894     }
4895   vam->retval = ntohl (mp->retval);
4896   vam->result_ready = 1;
4897 }
4898
4899 static void
4900 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4901                                            mp)
4902 {
4903   vat_main_t *vam = &vat_main;
4904
4905   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4906          ntohl (mp->hit_next_index), ntohl (mp->advance),
4907          ntohl (mp->opaque_index));
4908   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4909          ntohl (mp->match_length));
4910 }
4911
4912 static void
4913   vl_api_classify_session_details_t_handler_json
4914   (vl_api_classify_session_details_t * mp)
4915 {
4916   vat_main_t *vam = &vat_main;
4917   vat_json_node_t *node = NULL;
4918
4919   if (VAT_JSON_ARRAY != vam->json_tree.type)
4920     {
4921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4922       vat_json_init_array (&vam->json_tree);
4923     }
4924   node = vat_json_array_add (&vam->json_tree);
4925
4926   vat_json_init_object (node);
4927   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4928   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4929   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4930   u8 *s =
4931     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4932             0);
4933   vat_json_object_add_string_copy (node, "match", s);
4934 }
4935
4936 static void vl_api_pg_create_interface_reply_t_handler
4937   (vl_api_pg_create_interface_reply_t * mp)
4938 {
4939   vat_main_t *vam = &vat_main;
4940
4941   vam->retval = ntohl (mp->retval);
4942   vam->result_ready = 1;
4943 }
4944
4945 static void vl_api_pg_create_interface_reply_t_handler_json
4946   (vl_api_pg_create_interface_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       vat_json_init_object (&node);
4955
4956       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4957
4958       vat_json_print (vam->ofp, &node);
4959       vat_json_free (&node);
4960     }
4961   vam->retval = ntohl (mp->retval);
4962   vam->result_ready = 1;
4963 }
4964
4965 static void vl_api_policer_classify_details_t_handler
4966   (vl_api_policer_classify_details_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969
4970   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4971          ntohl (mp->table_index));
4972 }
4973
4974 static void vl_api_policer_classify_details_t_handler_json
4975   (vl_api_policer_classify_details_t * mp)
4976 {
4977   vat_main_t *vam = &vat_main;
4978   vat_json_node_t *node;
4979
4980   if (VAT_JSON_ARRAY != vam->json_tree.type)
4981     {
4982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4983       vat_json_init_array (&vam->json_tree);
4984     }
4985   node = vat_json_array_add (&vam->json_tree);
4986
4987   vat_json_init_object (node);
4988   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4989   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4990 }
4991
4992 static void vl_api_flow_classify_details_t_handler
4993   (vl_api_flow_classify_details_t * mp)
4994 {
4995   vat_main_t *vam = &vat_main;
4996
4997   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4998          ntohl (mp->table_index));
4999 }
5000
5001 static void vl_api_flow_classify_details_t_handler_json
5002   (vl_api_flow_classify_details_t * mp)
5003 {
5004   vat_main_t *vam = &vat_main;
5005   vat_json_node_t *node;
5006
5007   if (VAT_JSON_ARRAY != vam->json_tree.type)
5008     {
5009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5010       vat_json_init_array (&vam->json_tree);
5011     }
5012   node = vat_json_array_add (&vam->json_tree);
5013
5014   vat_json_init_object (node);
5015   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5016   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5017 }
5018
5019 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5020 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5022 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5023 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5024 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5025 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5029
5030 /*
5031  * Generate boilerplate reply handlers, which
5032  * dig the return value out of the xxx_reply_t API message,
5033  * stick it into vam->retval, and set vam->result_ready
5034  *
5035  * Could also do this by pointing N message decode slots at
5036  * a single function, but that could break in subtle ways.
5037  */
5038
5039 #define foreach_standard_reply_retval_handler           \
5040 _(sw_interface_set_flags_reply)                         \
5041 _(sw_interface_add_del_address_reply)                   \
5042 _(sw_interface_set_rx_mode_reply)                       \
5043 _(sw_interface_set_rx_placement_reply)                  \
5044 _(sw_interface_set_table_reply)                         \
5045 _(sw_interface_set_mpls_enable_reply)                   \
5046 _(sw_interface_set_vpath_reply)                         \
5047 _(sw_interface_set_vxlan_bypass_reply)                  \
5048 _(sw_interface_set_geneve_bypass_reply)                 \
5049 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5050 _(sw_interface_set_l2_bridge_reply)                     \
5051 _(sw_interface_set_bond_weight_reply)                   \
5052 _(bridge_domain_add_del_reply)                          \
5053 _(sw_interface_set_l2_xconnect_reply)                   \
5054 _(l2fib_add_del_reply)                                  \
5055 _(l2fib_flush_int_reply)                                \
5056 _(l2fib_flush_bd_reply)                                 \
5057 _(ip_route_add_del_reply)                               \
5058 _(ip_table_add_del_reply)                               \
5059 _(ip_table_replace_begin_reply)                         \
5060 _(ip_table_flush_reply)                                 \
5061 _(ip_table_replace_end_reply)                           \
5062 _(ip_mroute_add_del_reply)                              \
5063 _(mpls_route_add_del_reply)                             \
5064 _(mpls_table_add_del_reply)                             \
5065 _(mpls_ip_bind_unbind_reply)                            \
5066 _(bier_route_add_del_reply)                             \
5067 _(bier_table_add_del_reply)                             \
5068 _(sw_interface_set_unnumbered_reply)                    \
5069 _(set_ip_flow_hash_reply)                               \
5070 _(sw_interface_ip6_enable_disable_reply)                \
5071 _(l2_patch_add_del_reply)                               \
5072 _(sr_mpls_policy_add_reply)                             \
5073 _(sr_mpls_policy_mod_reply)                             \
5074 _(sr_mpls_policy_del_reply)                             \
5075 _(sr_policy_add_reply)                                  \
5076 _(sr_policy_mod_reply)                                  \
5077 _(sr_policy_del_reply)                                  \
5078 _(sr_localsid_add_del_reply)                            \
5079 _(sr_steering_add_del_reply)                            \
5080 _(classify_add_del_session_reply)                       \
5081 _(classify_set_interface_ip_table_reply)                \
5082 _(classify_set_interface_l2_tables_reply)               \
5083 _(l2tpv3_set_tunnel_cookies_reply)                      \
5084 _(l2tpv3_interface_enable_disable_reply)                \
5085 _(l2tpv3_set_lookup_key_reply)                          \
5086 _(l2_fib_clear_table_reply)                             \
5087 _(l2_interface_efp_filter_reply)                        \
5088 _(l2_interface_vlan_tag_rewrite_reply)                  \
5089 _(modify_vhost_user_if_reply)                           \
5090 _(delete_vhost_user_if_reply)                           \
5091 _(want_l2_macs_events_reply)                            \
5092 _(input_acl_set_interface_reply)                        \
5093 _(ipsec_spd_add_del_reply)                              \
5094 _(ipsec_interface_add_del_spd_reply)                    \
5095 _(ipsec_spd_entry_add_del_reply)                        \
5096 _(ipsec_sad_entry_add_del_reply)                        \
5097 _(ipsec_tunnel_if_add_del_reply)                        \
5098 _(ipsec_tunnel_if_set_sa_reply)                         \
5099 _(delete_loopback_reply)                                \
5100 _(bd_ip_mac_add_del_reply)                              \
5101 _(bd_ip_mac_flush_reply)                                \
5102 _(want_interface_events_reply)                          \
5103 _(cop_interface_enable_disable_reply)                   \
5104 _(cop_whitelist_enable_disable_reply)                   \
5105 _(sw_interface_clear_stats_reply)                       \
5106 _(ioam_enable_reply)                                    \
5107 _(ioam_disable_reply)                                   \
5108 _(one_add_del_locator_reply)                            \
5109 _(one_add_del_local_eid_reply)                          \
5110 _(one_add_del_remote_mapping_reply)                     \
5111 _(one_add_del_adjacency_reply)                          \
5112 _(one_add_del_map_resolver_reply)                       \
5113 _(one_add_del_map_server_reply)                         \
5114 _(one_enable_disable_reply)                             \
5115 _(one_rloc_probe_enable_disable_reply)                  \
5116 _(one_map_register_enable_disable_reply)                \
5117 _(one_map_register_set_ttl_reply)                       \
5118 _(one_set_transport_protocol_reply)                     \
5119 _(one_map_register_fallback_threshold_reply)            \
5120 _(one_pitr_set_locator_set_reply)                       \
5121 _(one_map_request_mode_reply)                           \
5122 _(one_add_del_map_request_itr_rlocs_reply)              \
5123 _(one_eid_table_add_del_map_reply)                      \
5124 _(one_use_petr_reply)                                   \
5125 _(one_stats_enable_disable_reply)                       \
5126 _(one_add_del_l2_arp_entry_reply)                       \
5127 _(one_add_del_ndp_entry_reply)                          \
5128 _(one_stats_flush_reply)                                \
5129 _(one_enable_disable_xtr_mode_reply)                    \
5130 _(one_enable_disable_pitr_mode_reply)                   \
5131 _(one_enable_disable_petr_mode_reply)                   \
5132 _(gpe_enable_disable_reply)                             \
5133 _(gpe_set_encap_mode_reply)                             \
5134 _(gpe_add_del_iface_reply)                              \
5135 _(gpe_add_del_native_fwd_rpath_reply)                   \
5136 _(af_packet_delete_reply)                               \
5137 _(policer_classify_set_interface_reply)                 \
5138 _(set_ipfix_exporter_reply)                             \
5139 _(set_ipfix_classify_stream_reply)                      \
5140 _(ipfix_classify_table_add_del_reply)                   \
5141 _(flow_classify_set_interface_reply)                    \
5142 _(sw_interface_span_enable_disable_reply)               \
5143 _(pg_capture_reply)                                     \
5144 _(pg_enable_disable_reply)                              \
5145 _(ip_source_and_port_range_check_add_del_reply)         \
5146 _(ip_source_and_port_range_check_interface_add_del_reply)\
5147 _(delete_subif_reply)                                   \
5148 _(l2_interface_pbb_tag_rewrite_reply)                   \
5149 _(set_punt_reply)                                       \
5150 _(feature_enable_disable_reply)                         \
5151 _(feature_gso_enable_disable_reply)                     \
5152 _(sw_interface_tag_add_del_reply)                       \
5153 _(sw_interface_add_del_mac_address_reply)               \
5154 _(hw_interface_set_mtu_reply)                           \
5155 _(p2p_ethernet_add_reply)                               \
5156 _(p2p_ethernet_del_reply)                               \
5157 _(lldp_config_reply)                                    \
5158 _(sw_interface_set_lldp_reply)                          \
5159 _(tcp_configure_src_addresses_reply)                    \
5160 _(session_rule_add_del_reply)                           \
5161 _(ip_container_proxy_add_del_reply)                     \
5162 _(output_acl_set_interface_reply)                       \
5163 _(qos_record_enable_disable_reply)
5164
5165 #define _(n)                                    \
5166     static void vl_api_##n##_t_handler          \
5167     (vl_api_##n##_t * mp)                       \
5168     {                                           \
5169         vat_main_t * vam = &vat_main;           \
5170         i32 retval = ntohl(mp->retval);         \
5171         if (vam->async_mode) {                  \
5172             vam->async_errors += (retval < 0);  \
5173         } else {                                \
5174             vam->retval = retval;               \
5175             vam->result_ready = 1;              \
5176         }                                       \
5177     }
5178 foreach_standard_reply_retval_handler;
5179 #undef _
5180
5181 #define _(n)                                    \
5182     static void vl_api_##n##_t_handler_json     \
5183     (vl_api_##n##_t * mp)                       \
5184     {                                           \
5185         vat_main_t * vam = &vat_main;           \
5186         vat_json_node_t node;                   \
5187         vat_json_init_object(&node);            \
5188         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5189         vat_json_print(vam->ofp, &node);        \
5190         vam->retval = ntohl(mp->retval);        \
5191         vam->result_ready = 1;                  \
5192     }
5193 foreach_standard_reply_retval_handler;
5194 #undef _
5195
5196 /*
5197  * Table of message reply handlers, must include boilerplate handlers
5198  * we just generated
5199  */
5200
5201 #define foreach_vpe_api_reply_msg                                       \
5202 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5203 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5204 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5205 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5206 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5207 _(CLI_REPLY, cli_reply)                                                 \
5208 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5209 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5210   sw_interface_add_del_address_reply)                                   \
5211 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5212 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5213 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5214 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5215 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5216 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5217 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5218 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5219 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5220 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5221   sw_interface_set_l2_xconnect_reply)                                   \
5222 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5223   sw_interface_set_l2_bridge_reply)                                     \
5224 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5225 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5226 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5227 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5228 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5229 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5230 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5231 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5232 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5233 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5234 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5235 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5236 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5237 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5238 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5239 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5240 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5241 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5242 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5243 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5244 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5245 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5246 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5247 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5248 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5249 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5250 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5251 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5252 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5253 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5254 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5255 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5256 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5257 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5258   sw_interface_set_unnumbered_reply)                                    \
5259 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5260 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5261 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5262 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5263   sw_interface_ip6_enable_disable_reply)                                \
5264 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5265 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5266 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5267 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5268 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5269 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5270 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5271 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5272 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5273 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5274 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5275 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5276 classify_set_interface_ip_table_reply)                                  \
5277 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5278   classify_set_interface_l2_tables_reply)                               \
5279 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5280 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5281 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5282 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5283 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5284   l2tpv3_interface_enable_disable_reply)                                \
5285 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5286 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5287 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5288 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5289 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5290 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5291 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5292 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5293 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5294 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5295 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5296 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5297 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5298 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5299 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5300 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5301 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5302 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5303 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5304 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5305 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5306 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5307 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5308 _(L2_MACS_EVENT, l2_macs_event)                                         \
5309 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5310 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5311 _(IP_DETAILS, ip_details)                                               \
5312 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5313 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5314 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5315 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5316 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5317 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5318 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5319 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5320 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5321 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5322 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5323 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5324 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5325 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5326 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5327 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5328 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5329 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5330 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5331 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5332 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5333 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5334 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5335 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5336 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5337 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5338 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5339 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5340   one_map_register_enable_disable_reply)                                \
5341 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5342 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5343 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5344 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5345   one_map_register_fallback_threshold_reply)                            \
5346 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5347   one_rloc_probe_enable_disable_reply)                                  \
5348 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5349 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5350 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5351 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5352 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5353 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5354 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5355 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5356 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5357 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5358 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5359 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5360 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5361 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5362 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5363 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5364   show_one_stats_enable_disable_reply)                                  \
5365 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5366 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5367 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5368 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5369 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5370 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5371 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5372 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5373   one_enable_disable_pitr_mode_reply)                                   \
5374 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5375   one_enable_disable_petr_mode_reply)                                   \
5376 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5377 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5378 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5379 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5380 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5381 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5382 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5383 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5384 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5385 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5386 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5387 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5388   gpe_add_del_native_fwd_rpath_reply)                                   \
5389 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5390   gpe_fwd_entry_path_details)                                           \
5391 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5392 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5393   one_add_del_map_request_itr_rlocs_reply)                              \
5394 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5395   one_get_map_request_itr_rlocs_reply)                                  \
5396 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5397 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5398 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5399 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5400 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5401 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5402   show_one_map_register_state_reply)                                    \
5403 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5404 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5405   show_one_map_register_fallback_threshold_reply)                       \
5406 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5407 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5408 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5409 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5410 _(POLICER_DETAILS, policer_details)                                     \
5411 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5412 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5413 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5414 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5415 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5416 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5417 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5418 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5419 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5420 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5421 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5422 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5423 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5424 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5425 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5426 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5427 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5428 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5429 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5430 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5431 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5432 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5433 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5434 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5435  ip_source_and_port_range_check_add_del_reply)                          \
5436 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5437  ip_source_and_port_range_check_interface_add_del_reply)                \
5438 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5439 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5440 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5441 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5442 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5443 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5444 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5445 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5446 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5447 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5448 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5449 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5450 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5451 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5452 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5453 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5454 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5455 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5456 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5457 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5458 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5459 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5460 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5461
5462 #define foreach_standalone_reply_msg                                    \
5463 _(SW_INTERFACE_EVENT, sw_interface_event)
5464
5465 typedef struct
5466 {
5467   u8 *name;
5468   u32 value;
5469 } name_sort_t;
5470
5471 #define STR_VTR_OP_CASE(op)     \
5472     case L2_VTR_ ## op:         \
5473         return "" # op;
5474
5475 static const char *
5476 str_vtr_op (u32 vtr_op)
5477 {
5478   switch (vtr_op)
5479     {
5480       STR_VTR_OP_CASE (DISABLED);
5481       STR_VTR_OP_CASE (PUSH_1);
5482       STR_VTR_OP_CASE (PUSH_2);
5483       STR_VTR_OP_CASE (POP_1);
5484       STR_VTR_OP_CASE (POP_2);
5485       STR_VTR_OP_CASE (TRANSLATE_1_1);
5486       STR_VTR_OP_CASE (TRANSLATE_1_2);
5487       STR_VTR_OP_CASE (TRANSLATE_2_1);
5488       STR_VTR_OP_CASE (TRANSLATE_2_2);
5489     }
5490
5491   return "UNKNOWN";
5492 }
5493
5494 static int
5495 dump_sub_interface_table (vat_main_t * vam)
5496 {
5497   const sw_interface_subif_t *sub = NULL;
5498
5499   if (vam->json_output)
5500     {
5501       clib_warning
5502         ("JSON output supported only for VPE API calls and dump_stats_table");
5503       return -99;
5504     }
5505
5506   print (vam->ofp,
5507          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5508          "Interface", "sw_if_index",
5509          "sub id", "dot1ad", "tags", "outer id",
5510          "inner id", "exact", "default", "outer any", "inner any");
5511
5512   vec_foreach (sub, vam->sw_if_subif_table)
5513   {
5514     print (vam->ofp,
5515            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5516            sub->interface_name,
5517            sub->sw_if_index,
5518            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5519            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5520            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5521            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5522     if (sub->vtr_op != L2_VTR_DISABLED)
5523       {
5524         print (vam->ofp,
5525                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5526                "tag1: %d tag2: %d ]",
5527                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5528                sub->vtr_tag1, sub->vtr_tag2);
5529       }
5530   }
5531
5532   return 0;
5533 }
5534
5535 static int
5536 name_sort_cmp (void *a1, void *a2)
5537 {
5538   name_sort_t *n1 = a1;
5539   name_sort_t *n2 = a2;
5540
5541   return strcmp ((char *) n1->name, (char *) n2->name);
5542 }
5543
5544 static int
5545 dump_interface_table (vat_main_t * vam)
5546 {
5547   hash_pair_t *p;
5548   name_sort_t *nses = 0, *ns;
5549
5550   if (vam->json_output)
5551     {
5552       clib_warning
5553         ("JSON output supported only for VPE API calls and dump_stats_table");
5554       return -99;
5555     }
5556
5557   /* *INDENT-OFF* */
5558   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5559   ({
5560     vec_add2 (nses, ns, 1);
5561     ns->name = (u8 *)(p->key);
5562     ns->value = (u32) p->value[0];
5563   }));
5564   /* *INDENT-ON* */
5565
5566   vec_sort_with_function (nses, name_sort_cmp);
5567
5568   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5569   vec_foreach (ns, nses)
5570   {
5571     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5572   }
5573   vec_free (nses);
5574   return 0;
5575 }
5576
5577 static int
5578 dump_ip_table (vat_main_t * vam, int is_ipv6)
5579 {
5580   const ip_details_t *det = NULL;
5581   const ip_address_details_t *address = NULL;
5582   u32 i = ~0;
5583
5584   print (vam->ofp, "%-12s", "sw_if_index");
5585
5586   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5587   {
5588     i++;
5589     if (!det->present)
5590       {
5591         continue;
5592       }
5593     print (vam->ofp, "%-12d", i);
5594     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5595     if (!det->addr)
5596       {
5597         continue;
5598       }
5599     vec_foreach (address, det->addr)
5600     {
5601       print (vam->ofp,
5602              "            %-30U%-13d",
5603              is_ipv6 ? format_ip6_address : format_ip4_address,
5604              address->ip, address->prefix_length);
5605     }
5606   }
5607
5608   return 0;
5609 }
5610
5611 static int
5612 dump_ipv4_table (vat_main_t * vam)
5613 {
5614   if (vam->json_output)
5615     {
5616       clib_warning
5617         ("JSON output supported only for VPE API calls and dump_stats_table");
5618       return -99;
5619     }
5620
5621   return dump_ip_table (vam, 0);
5622 }
5623
5624 static int
5625 dump_ipv6_table (vat_main_t * vam)
5626 {
5627   if (vam->json_output)
5628     {
5629       clib_warning
5630         ("JSON output supported only for VPE API calls and dump_stats_table");
5631       return -99;
5632     }
5633
5634   return dump_ip_table (vam, 1);
5635 }
5636
5637 /*
5638  * Pass CLI buffers directly in the CLI_INBAND API message,
5639  * instead of an additional shared memory area.
5640  */
5641 static int
5642 exec_inband (vat_main_t * vam)
5643 {
5644   vl_api_cli_inband_t *mp;
5645   unformat_input_t *i = vam->input;
5646   int ret;
5647
5648   if (vec_len (i->buffer) == 0)
5649     return -1;
5650
5651   if (vam->exec_mode == 0 && unformat (i, "mode"))
5652     {
5653       vam->exec_mode = 1;
5654       return 0;
5655     }
5656   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5657     {
5658       vam->exec_mode = 0;
5659       return 0;
5660     }
5661
5662   /*
5663    * In order for the CLI command to work, it
5664    * must be a vector ending in \n, not a C-string ending
5665    * in \n\0.
5666    */
5667   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5668   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5669
5670   S (mp);
5671   W (ret);
5672   /* json responses may or may not include a useful reply... */
5673   if (vec_len (vam->cmd_reply))
5674     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5675   return ret;
5676 }
5677
5678 int
5679 exec (vat_main_t * vam)
5680 {
5681   return exec_inband (vam);
5682 }
5683
5684 static int
5685 api_create_loopback (vat_main_t * vam)
5686 {
5687   unformat_input_t *i = vam->input;
5688   vl_api_create_loopback_t *mp;
5689   vl_api_create_loopback_instance_t *mp_lbi;
5690   u8 mac_address[6];
5691   u8 mac_set = 0;
5692   u8 is_specified = 0;
5693   u32 user_instance = 0;
5694   int ret;
5695
5696   clib_memset (mac_address, 0, sizeof (mac_address));
5697
5698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5699     {
5700       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5701         mac_set = 1;
5702       if (unformat (i, "instance %d", &user_instance))
5703         is_specified = 1;
5704       else
5705         break;
5706     }
5707
5708   if (is_specified)
5709     {
5710       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5711       mp_lbi->is_specified = is_specified;
5712       if (is_specified)
5713         mp_lbi->user_instance = htonl (user_instance);
5714       if (mac_set)
5715         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5716       S (mp_lbi);
5717     }
5718   else
5719     {
5720       /* Construct the API message */
5721       M (CREATE_LOOPBACK, mp);
5722       if (mac_set)
5723         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5724       S (mp);
5725     }
5726
5727   W (ret);
5728   return ret;
5729 }
5730
5731 static int
5732 api_delete_loopback (vat_main_t * vam)
5733 {
5734   unformat_input_t *i = vam->input;
5735   vl_api_delete_loopback_t *mp;
5736   u32 sw_if_index = ~0;
5737   int ret;
5738
5739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5740     {
5741       if (unformat (i, "sw_if_index %d", &sw_if_index))
5742         ;
5743       else
5744         break;
5745     }
5746
5747   if (sw_if_index == ~0)
5748     {
5749       errmsg ("missing sw_if_index");
5750       return -99;
5751     }
5752
5753   /* Construct the API message */
5754   M (DELETE_LOOPBACK, mp);
5755   mp->sw_if_index = ntohl (sw_if_index);
5756
5757   S (mp);
5758   W (ret);
5759   return ret;
5760 }
5761
5762 static int
5763 api_want_interface_events (vat_main_t * vam)
5764 {
5765   unformat_input_t *i = vam->input;
5766   vl_api_want_interface_events_t *mp;
5767   int enable = -1;
5768   int ret;
5769
5770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5771     {
5772       if (unformat (i, "enable"))
5773         enable = 1;
5774       else if (unformat (i, "disable"))
5775         enable = 0;
5776       else
5777         break;
5778     }
5779
5780   if (enable == -1)
5781     {
5782       errmsg ("missing enable|disable");
5783       return -99;
5784     }
5785
5786   M (WANT_INTERFACE_EVENTS, mp);
5787   mp->enable_disable = enable;
5788
5789   vam->interface_event_display = enable;
5790
5791   S (mp);
5792   W (ret);
5793   return ret;
5794 }
5795
5796
5797 /* Note: non-static, called once to set up the initial intfc table */
5798 int
5799 api_sw_interface_dump (vat_main_t * vam)
5800 {
5801   vl_api_sw_interface_dump_t *mp;
5802   vl_api_control_ping_t *mp_ping;
5803   hash_pair_t *p;
5804   name_sort_t *nses = 0, *ns;
5805   sw_interface_subif_t *sub = NULL;
5806   int ret;
5807
5808   /* Toss the old name table */
5809   /* *INDENT-OFF* */
5810   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5811   ({
5812     vec_add2 (nses, ns, 1);
5813     ns->name = (u8 *)(p->key);
5814     ns->value = (u32) p->value[0];
5815   }));
5816   /* *INDENT-ON* */
5817
5818   hash_free (vam->sw_if_index_by_interface_name);
5819
5820   vec_foreach (ns, nses) vec_free (ns->name);
5821
5822   vec_free (nses);
5823
5824   vec_foreach (sub, vam->sw_if_subif_table)
5825   {
5826     vec_free (sub->interface_name);
5827   }
5828   vec_free (vam->sw_if_subif_table);
5829
5830   /* recreate the interface name hash table */
5831   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5832
5833   /*
5834    * Ask for all interface names. Otherwise, the epic catalog of
5835    * name filters becomes ridiculously long, and vat ends up needing
5836    * to be taught about new interface types.
5837    */
5838   M (SW_INTERFACE_DUMP, mp);
5839   S (mp);
5840
5841   /* Use a control ping for synchronization */
5842   MPING (CONTROL_PING, mp_ping);
5843   S (mp_ping);
5844
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_sw_interface_set_flags (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_sw_interface_set_flags_t *mp;
5854   u32 sw_if_index;
5855   u8 sw_if_index_set = 0;
5856   u8 admin_up = 0;
5857   int ret;
5858
5859   /* Parse args required to build the message */
5860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5861     {
5862       if (unformat (i, "admin-up"))
5863         admin_up = 1;
5864       else if (unformat (i, "admin-down"))
5865         admin_up = 0;
5866       else
5867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5868         sw_if_index_set = 1;
5869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5870         sw_if_index_set = 1;
5871       else
5872         break;
5873     }
5874
5875   if (sw_if_index_set == 0)
5876     {
5877       errmsg ("missing interface name or sw_if_index");
5878       return -99;
5879     }
5880
5881   /* Construct the API message */
5882   M (SW_INTERFACE_SET_FLAGS, mp);
5883   mp->sw_if_index = ntohl (sw_if_index);
5884   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5885
5886   /* send it... */
5887   S (mp);
5888
5889   /* Wait for a reply, return the good/bad news... */
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_sw_interface_set_rx_mode (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_rx_mode_t *mp;
5899   u32 sw_if_index;
5900   u8 sw_if_index_set = 0;
5901   int ret;
5902   u8 queue_id_valid = 0;
5903   u32 queue_id;
5904   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5905
5906   /* Parse args required to build the message */
5907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5908     {
5909       if (unformat (i, "queue %d", &queue_id))
5910         queue_id_valid = 1;
5911       else if (unformat (i, "polling"))
5912         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5913       else if (unformat (i, "interrupt"))
5914         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5915       else if (unformat (i, "adaptive"))
5916         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5917       else
5918         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5919         sw_if_index_set = 1;
5920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5921         sw_if_index_set = 1;
5922       else
5923         break;
5924     }
5925
5926   if (sw_if_index_set == 0)
5927     {
5928       errmsg ("missing interface name or sw_if_index");
5929       return -99;
5930     }
5931   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5932     {
5933       errmsg ("missing rx-mode");
5934       return -99;
5935     }
5936
5937   /* Construct the API message */
5938   M (SW_INTERFACE_SET_RX_MODE, mp);
5939   mp->sw_if_index = ntohl (sw_if_index);
5940   mp->mode = (vl_api_rx_mode_t) mode;
5941   mp->queue_id_valid = queue_id_valid;
5942   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5943
5944   /* send it... */
5945   S (mp);
5946
5947   /* Wait for a reply, return the good/bad news... */
5948   W (ret);
5949   return ret;
5950 }
5951
5952 static int
5953 api_sw_interface_set_rx_placement (vat_main_t * vam)
5954 {
5955   unformat_input_t *i = vam->input;
5956   vl_api_sw_interface_set_rx_placement_t *mp;
5957   u32 sw_if_index;
5958   u8 sw_if_index_set = 0;
5959   int ret;
5960   u8 is_main = 0;
5961   u32 queue_id, thread_index;
5962
5963   /* Parse args required to build the message */
5964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965     {
5966       if (unformat (i, "queue %d", &queue_id))
5967         ;
5968       else if (unformat (i, "main"))
5969         is_main = 1;
5970       else if (unformat (i, "worker %d", &thread_index))
5971         ;
5972       else
5973         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5974         sw_if_index_set = 1;
5975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5976         sw_if_index_set = 1;
5977       else
5978         break;
5979     }
5980
5981   if (sw_if_index_set == 0)
5982     {
5983       errmsg ("missing interface name or sw_if_index");
5984       return -99;
5985     }
5986
5987   if (is_main)
5988     thread_index = 0;
5989   /* Construct the API message */
5990   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5991   mp->sw_if_index = ntohl (sw_if_index);
5992   mp->worker_id = ntohl (thread_index);
5993   mp->queue_id = ntohl (queue_id);
5994   mp->is_main = is_main;
5995
5996   /* send it... */
5997   S (mp);
5998   /* Wait for a reply, return the good/bad news... */
5999   W (ret);
6000   return ret;
6001 }
6002
6003 static void vl_api_sw_interface_rx_placement_details_t_handler
6004   (vl_api_sw_interface_rx_placement_details_t * mp)
6005 {
6006   vat_main_t *vam = &vat_main;
6007   u32 worker_id = ntohl (mp->worker_id);
6008
6009   print (vam->ofp,
6010          "\n%-11d %-11s %-6d %-5d %-9s",
6011          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6012          worker_id, ntohl (mp->queue_id),
6013          (mp->mode ==
6014           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6015 }
6016
6017 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6018   (vl_api_sw_interface_rx_placement_details_t * mp)
6019 {
6020   vat_main_t *vam = &vat_main;
6021   vat_json_node_t *node = NULL;
6022
6023   if (VAT_JSON_ARRAY != vam->json_tree.type)
6024     {
6025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6026       vat_json_init_array (&vam->json_tree);
6027     }
6028   node = vat_json_array_add (&vam->json_tree);
6029
6030   vat_json_init_object (node);
6031   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6032   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6033   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6034   vat_json_object_add_uint (node, "mode", mp->mode);
6035 }
6036
6037 static int
6038 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6039 {
6040   unformat_input_t *i = vam->input;
6041   vl_api_sw_interface_rx_placement_dump_t *mp;
6042   vl_api_control_ping_t *mp_ping;
6043   int ret;
6044   u32 sw_if_index;
6045   u8 sw_if_index_set = 0;
6046
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6050         sw_if_index_set++;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         sw_if_index_set++;
6053       else
6054         break;
6055     }
6056
6057   print (vam->ofp,
6058          "\n%-11s %-11s %-6s %-5s %-4s",
6059          "sw_if_index", "main/worker", "thread", "queue", "mode");
6060
6061   /* Dump Interface rx placement */
6062   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6063
6064   if (sw_if_index_set)
6065     mp->sw_if_index = htonl (sw_if_index);
6066   else
6067     mp->sw_if_index = ~0;
6068
6069   S (mp);
6070
6071   /* Use a control ping for synchronization */
6072   MPING (CONTROL_PING, mp_ping);
6073   S (mp_ping);
6074
6075   W (ret);
6076   return ret;
6077 }
6078
6079 static int
6080 api_sw_interface_clear_stats (vat_main_t * vam)
6081 {
6082   unformat_input_t *i = vam->input;
6083   vl_api_sw_interface_clear_stats_t *mp;
6084   u32 sw_if_index;
6085   u8 sw_if_index_set = 0;
6086   int ret;
6087
6088   /* Parse args required to build the message */
6089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090     {
6091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6092         sw_if_index_set = 1;
6093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6094         sw_if_index_set = 1;
6095       else
6096         break;
6097     }
6098
6099   /* Construct the API message */
6100   M (SW_INTERFACE_CLEAR_STATS, mp);
6101
6102   if (sw_if_index_set == 1)
6103     mp->sw_if_index = ntohl (sw_if_index);
6104   else
6105     mp->sw_if_index = ~0;
6106
6107   /* send it... */
6108   S (mp);
6109
6110   /* Wait for a reply, return the good/bad news... */
6111   W (ret);
6112   return ret;
6113 }
6114
6115 static int
6116 api_sw_interface_add_del_address (vat_main_t * vam)
6117 {
6118   unformat_input_t *i = vam->input;
6119   vl_api_sw_interface_add_del_address_t *mp;
6120   u32 sw_if_index;
6121   u8 sw_if_index_set = 0;
6122   u8 is_add = 1, del_all = 0;
6123   u32 address_length = 0;
6124   u8 v4_address_set = 0;
6125   u8 v6_address_set = 0;
6126   ip4_address_t v4address;
6127   ip6_address_t v6address;
6128   int ret;
6129
6130   /* Parse args required to build the message */
6131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6132     {
6133       if (unformat (i, "del-all"))
6134         del_all = 1;
6135       else if (unformat (i, "del"))
6136         is_add = 0;
6137       else
6138         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6139         sw_if_index_set = 1;
6140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6141         sw_if_index_set = 1;
6142       else if (unformat (i, "%U/%d",
6143                          unformat_ip4_address, &v4address, &address_length))
6144         v4_address_set = 1;
6145       else if (unformat (i, "%U/%d",
6146                          unformat_ip6_address, &v6address, &address_length))
6147         v6_address_set = 1;
6148       else
6149         break;
6150     }
6151
6152   if (sw_if_index_set == 0)
6153     {
6154       errmsg ("missing interface name or sw_if_index");
6155       return -99;
6156     }
6157   if (v4_address_set && v6_address_set)
6158     {
6159       errmsg ("both v4 and v6 addresses set");
6160       return -99;
6161     }
6162   if (!v4_address_set && !v6_address_set && !del_all)
6163     {
6164       errmsg ("no addresses set");
6165       return -99;
6166     }
6167
6168   /* Construct the API message */
6169   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6170
6171   mp->sw_if_index = ntohl (sw_if_index);
6172   mp->is_add = is_add;
6173   mp->del_all = del_all;
6174   if (v6_address_set)
6175     {
6176       mp->prefix.address.af = ADDRESS_IP6;
6177       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6178     }
6179   else
6180     {
6181       mp->prefix.address.af = ADDRESS_IP4;
6182       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6183     }
6184   mp->prefix.len = address_length;
6185
6186   /* send it... */
6187   S (mp);
6188
6189   /* Wait for a reply, return good/bad news  */
6190   W (ret);
6191   return ret;
6192 }
6193
6194 static int
6195 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6196 {
6197   unformat_input_t *i = vam->input;
6198   vl_api_sw_interface_set_mpls_enable_t *mp;
6199   u32 sw_if_index;
6200   u8 sw_if_index_set = 0;
6201   u8 enable = 1;
6202   int ret;
6203
6204   /* Parse args required to build the message */
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6208         sw_if_index_set = 1;
6209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6210         sw_if_index_set = 1;
6211       else if (unformat (i, "disable"))
6212         enable = 0;
6213       else if (unformat (i, "dis"))
6214         enable = 0;
6215       else
6216         break;
6217     }
6218
6219   if (sw_if_index_set == 0)
6220     {
6221       errmsg ("missing interface name or sw_if_index");
6222       return -99;
6223     }
6224
6225   /* Construct the API message */
6226   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6227
6228   mp->sw_if_index = ntohl (sw_if_index);
6229   mp->enable = enable;
6230
6231   /* send it... */
6232   S (mp);
6233
6234   /* Wait for a reply... */
6235   W (ret);
6236   return ret;
6237 }
6238
6239 static int
6240 api_sw_interface_set_table (vat_main_t * vam)
6241 {
6242   unformat_input_t *i = vam->input;
6243   vl_api_sw_interface_set_table_t *mp;
6244   u32 sw_if_index, vrf_id = 0;
6245   u8 sw_if_index_set = 0;
6246   u8 is_ipv6 = 0;
6247   int ret;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6255         sw_if_index_set = 1;
6256       else if (unformat (i, "vrf %d", &vrf_id))
6257         ;
6258       else if (unformat (i, "ipv6"))
6259         is_ipv6 = 1;
6260       else
6261         break;
6262     }
6263
6264   if (sw_if_index_set == 0)
6265     {
6266       errmsg ("missing interface name or sw_if_index");
6267       return -99;
6268     }
6269
6270   /* Construct the API message */
6271   M (SW_INTERFACE_SET_TABLE, mp);
6272
6273   mp->sw_if_index = ntohl (sw_if_index);
6274   mp->is_ipv6 = is_ipv6;
6275   mp->vrf_id = ntohl (vrf_id);
6276
6277   /* send it... */
6278   S (mp);
6279
6280   /* Wait for a reply... */
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static void vl_api_sw_interface_get_table_reply_t_handler
6286   (vl_api_sw_interface_get_table_reply_t * mp)
6287 {
6288   vat_main_t *vam = &vat_main;
6289
6290   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6291
6292   vam->retval = ntohl (mp->retval);
6293   vam->result_ready = 1;
6294
6295 }
6296
6297 static void vl_api_sw_interface_get_table_reply_t_handler_json
6298   (vl_api_sw_interface_get_table_reply_t * mp)
6299 {
6300   vat_main_t *vam = &vat_main;
6301   vat_json_node_t node;
6302
6303   vat_json_init_object (&node);
6304   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6305   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6306
6307   vat_json_print (vam->ofp, &node);
6308   vat_json_free (&node);
6309
6310   vam->retval = ntohl (mp->retval);
6311   vam->result_ready = 1;
6312 }
6313
6314 static int
6315 api_sw_interface_get_table (vat_main_t * vam)
6316 {
6317   unformat_input_t *i = vam->input;
6318   vl_api_sw_interface_get_table_t *mp;
6319   u32 sw_if_index;
6320   u8 sw_if_index_set = 0;
6321   u8 is_ipv6 = 0;
6322   int ret;
6323
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6327         sw_if_index_set = 1;
6328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "ipv6"))
6331         is_ipv6 = 1;
6332       else
6333         break;
6334     }
6335
6336   if (sw_if_index_set == 0)
6337     {
6338       errmsg ("missing interface name or sw_if_index");
6339       return -99;
6340     }
6341
6342   M (SW_INTERFACE_GET_TABLE, mp);
6343   mp->sw_if_index = htonl (sw_if_index);
6344   mp->is_ipv6 = is_ipv6;
6345
6346   S (mp);
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_sw_interface_set_vpath (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_sw_interface_set_vpath_t *mp;
6356   u32 sw_if_index = 0;
6357   u8 sw_if_index_set = 0;
6358   u8 is_enable = 0;
6359   int ret;
6360
6361   /* Parse args required to build the message */
6362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6363     {
6364       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6365         sw_if_index_set = 1;
6366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "enable"))
6369         is_enable = 1;
6370       else if (unformat (i, "disable"))
6371         is_enable = 0;
6372       else
6373         break;
6374     }
6375
6376   if (sw_if_index_set == 0)
6377     {
6378       errmsg ("missing interface name or sw_if_index");
6379       return -99;
6380     }
6381
6382   /* Construct the API message */
6383   M (SW_INTERFACE_SET_VPATH, mp);
6384
6385   mp->sw_if_index = ntohl (sw_if_index);
6386   mp->enable = is_enable;
6387
6388   /* send it... */
6389   S (mp);
6390
6391   /* Wait for a reply... */
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6401   u32 sw_if_index = 0;
6402   u8 sw_if_index_set = 0;
6403   u8 is_enable = 1;
6404   u8 is_ipv6 = 0;
6405   int ret;
6406
6407   /* Parse args required to build the message */
6408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6409     {
6410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6411         sw_if_index_set = 1;
6412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "enable"))
6415         is_enable = 1;
6416       else if (unformat (i, "disable"))
6417         is_enable = 0;
6418       else if (unformat (i, "ip4"))
6419         is_ipv6 = 0;
6420       else if (unformat (i, "ip6"))
6421         is_ipv6 = 1;
6422       else
6423         break;
6424     }
6425
6426   if (sw_if_index_set == 0)
6427     {
6428       errmsg ("missing interface name or sw_if_index");
6429       return -99;
6430     }
6431
6432   /* Construct the API message */
6433   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6434
6435   mp->sw_if_index = ntohl (sw_if_index);
6436   mp->enable = is_enable;
6437   mp->is_ipv6 = is_ipv6;
6438
6439   /* send it... */
6440   S (mp);
6441
6442   /* Wait for a reply... */
6443   W (ret);
6444   return ret;
6445 }
6446
6447 static int
6448 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6449 {
6450   unformat_input_t *i = vam->input;
6451   vl_api_sw_interface_set_geneve_bypass_t *mp;
6452   u32 sw_if_index = 0;
6453   u8 sw_if_index_set = 0;
6454   u8 is_enable = 1;
6455   u8 is_ipv6 = 0;
6456   int ret;
6457
6458   /* Parse args required to build the message */
6459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6460     {
6461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6462         sw_if_index_set = 1;
6463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6464         sw_if_index_set = 1;
6465       else if (unformat (i, "enable"))
6466         is_enable = 1;
6467       else if (unformat (i, "disable"))
6468         is_enable = 0;
6469       else if (unformat (i, "ip4"))
6470         is_ipv6 = 0;
6471       else if (unformat (i, "ip6"))
6472         is_ipv6 = 1;
6473       else
6474         break;
6475     }
6476
6477   if (sw_if_index_set == 0)
6478     {
6479       errmsg ("missing interface name or sw_if_index");
6480       return -99;
6481     }
6482
6483   /* Construct the API message */
6484   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6485
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->enable = is_enable;
6488   mp->is_ipv6 = is_ipv6;
6489
6490   /* send it... */
6491   S (mp);
6492
6493   /* Wait for a reply... */
6494   W (ret);
6495   return ret;
6496 }
6497
6498 static int
6499 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6500 {
6501   unformat_input_t *i = vam->input;
6502   vl_api_sw_interface_set_l2_xconnect_t *mp;
6503   u32 rx_sw_if_index;
6504   u8 rx_sw_if_index_set = 0;
6505   u32 tx_sw_if_index;
6506   u8 tx_sw_if_index_set = 0;
6507   u8 enable = 1;
6508   int ret;
6509
6510   /* Parse args required to build the message */
6511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6512     {
6513       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6514         rx_sw_if_index_set = 1;
6515       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6516         tx_sw_if_index_set = 1;
6517       else if (unformat (i, "rx"))
6518         {
6519           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520             {
6521               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6522                             &rx_sw_if_index))
6523                 rx_sw_if_index_set = 1;
6524             }
6525           else
6526             break;
6527         }
6528       else if (unformat (i, "tx"))
6529         {
6530           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6531             {
6532               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6533                             &tx_sw_if_index))
6534                 tx_sw_if_index_set = 1;
6535             }
6536           else
6537             break;
6538         }
6539       else if (unformat (i, "enable"))
6540         enable = 1;
6541       else if (unformat (i, "disable"))
6542         enable = 0;
6543       else
6544         break;
6545     }
6546
6547   if (rx_sw_if_index_set == 0)
6548     {
6549       errmsg ("missing rx interface name or rx_sw_if_index");
6550       return -99;
6551     }
6552
6553   if (enable && (tx_sw_if_index_set == 0))
6554     {
6555       errmsg ("missing tx interface name or tx_sw_if_index");
6556       return -99;
6557     }
6558
6559   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6560
6561   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6562   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6563   mp->enable = enable;
6564
6565   S (mp);
6566   W (ret);
6567   return ret;
6568 }
6569
6570 static int
6571 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_l2_bridge_t *mp;
6575   vl_api_l2_port_type_t port_type;
6576   u32 rx_sw_if_index;
6577   u8 rx_sw_if_index_set = 0;
6578   u32 bd_id;
6579   u8 bd_id_set = 0;
6580   u32 shg = 0;
6581   u8 enable = 1;
6582   int ret;
6583
6584   port_type = L2_API_PORT_TYPE_NORMAL;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "bd_id %d", &bd_id))
6592         bd_id_set = 1;
6593       else
6594         if (unformat
6595             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6596         rx_sw_if_index_set = 1;
6597       else if (unformat (i, "shg %d", &shg))
6598         ;
6599       else if (unformat (i, "bvi"))
6600         port_type = L2_API_PORT_TYPE_BVI;
6601       else if (unformat (i, "uu-fwd"))
6602         port_type = L2_API_PORT_TYPE_UU_FWD;
6603       else if (unformat (i, "enable"))
6604         enable = 1;
6605       else if (unformat (i, "disable"))
6606         enable = 0;
6607       else
6608         break;
6609     }
6610
6611   if (rx_sw_if_index_set == 0)
6612     {
6613       errmsg ("missing rx interface name or sw_if_index");
6614       return -99;
6615     }
6616
6617   if (enable && (bd_id_set == 0))
6618     {
6619       errmsg ("missing bridge domain");
6620       return -99;
6621     }
6622
6623   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6624
6625   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6626   mp->bd_id = ntohl (bd_id);
6627   mp->shg = (u8) shg;
6628   mp->port_type = ntohl (port_type);
6629   mp->enable = enable;
6630
6631   S (mp);
6632   W (ret);
6633   return ret;
6634 }
6635
6636 static int
6637 api_bridge_domain_dump (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_bridge_domain_dump_t *mp;
6641   vl_api_control_ping_t *mp_ping;
6642   u32 bd_id = ~0;
6643   int ret;
6644
6645   /* Parse args required to build the message */
6646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6647     {
6648       if (unformat (i, "bd_id %d", &bd_id))
6649         ;
6650       else
6651         break;
6652     }
6653
6654   M (BRIDGE_DOMAIN_DUMP, mp);
6655   mp->bd_id = ntohl (bd_id);
6656   S (mp);
6657
6658   /* Use a control ping for synchronization */
6659   MPING (CONTROL_PING, mp_ping);
6660   S (mp_ping);
6661
6662   W (ret);
6663   return ret;
6664 }
6665
6666 static int
6667 api_bridge_domain_add_del (vat_main_t * vam)
6668 {
6669   unformat_input_t *i = vam->input;
6670   vl_api_bridge_domain_add_del_t *mp;
6671   u32 bd_id = ~0;
6672   u8 is_add = 1;
6673   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6674   u8 *bd_tag = NULL;
6675   u32 mac_age = 0;
6676   int ret;
6677
6678   /* Parse args required to build the message */
6679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6680     {
6681       if (unformat (i, "bd_id %d", &bd_id))
6682         ;
6683       else if (unformat (i, "flood %d", &flood))
6684         ;
6685       else if (unformat (i, "uu-flood %d", &uu_flood))
6686         ;
6687       else if (unformat (i, "forward %d", &forward))
6688         ;
6689       else if (unformat (i, "learn %d", &learn))
6690         ;
6691       else if (unformat (i, "arp-term %d", &arp_term))
6692         ;
6693       else if (unformat (i, "mac-age %d", &mac_age))
6694         ;
6695       else if (unformat (i, "bd-tag %s", &bd_tag))
6696         ;
6697       else if (unformat (i, "del"))
6698         {
6699           is_add = 0;
6700           flood = uu_flood = forward = learn = 0;
6701         }
6702       else
6703         break;
6704     }
6705
6706   if (bd_id == ~0)
6707     {
6708       errmsg ("missing bridge domain");
6709       ret = -99;
6710       goto done;
6711     }
6712
6713   if (mac_age > 255)
6714     {
6715       errmsg ("mac age must be less than 256 ");
6716       ret = -99;
6717       goto done;
6718     }
6719
6720   if ((bd_tag) && (vec_len (bd_tag) > 63))
6721     {
6722       errmsg ("bd-tag cannot be longer than 63");
6723       ret = -99;
6724       goto done;
6725     }
6726
6727   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6728
6729   mp->bd_id = ntohl (bd_id);
6730   mp->flood = flood;
6731   mp->uu_flood = uu_flood;
6732   mp->forward = forward;
6733   mp->learn = learn;
6734   mp->arp_term = arp_term;
6735   mp->is_add = is_add;
6736   mp->mac_age = (u8) mac_age;
6737   if (bd_tag)
6738     {
6739       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6740       mp->bd_tag[vec_len (bd_tag)] = 0;
6741     }
6742   S (mp);
6743   W (ret);
6744
6745 done:
6746   vec_free (bd_tag);
6747   return ret;
6748 }
6749
6750 static int
6751 api_l2fib_flush_bd (vat_main_t * vam)
6752 {
6753   unformat_input_t *i = vam->input;
6754   vl_api_l2fib_flush_bd_t *mp;
6755   u32 bd_id = ~0;
6756   int ret;
6757
6758   /* Parse args required to build the message */
6759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6760     {
6761       if (unformat (i, "bd_id %d", &bd_id));
6762       else
6763         break;
6764     }
6765
6766   if (bd_id == ~0)
6767     {
6768       errmsg ("missing bridge domain");
6769       return -99;
6770     }
6771
6772   M (L2FIB_FLUSH_BD, mp);
6773
6774   mp->bd_id = htonl (bd_id);
6775
6776   S (mp);
6777   W (ret);
6778   return ret;
6779 }
6780
6781 static int
6782 api_l2fib_flush_int (vat_main_t * vam)
6783 {
6784   unformat_input_t *i = vam->input;
6785   vl_api_l2fib_flush_int_t *mp;
6786   u32 sw_if_index = ~0;
6787   int ret;
6788
6789   /* Parse args required to build the message */
6790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791     {
6792       if (unformat (i, "sw_if_index %d", &sw_if_index));
6793       else
6794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6795       else
6796         break;
6797     }
6798
6799   if (sw_if_index == ~0)
6800     {
6801       errmsg ("missing interface name or sw_if_index");
6802       return -99;
6803     }
6804
6805   M (L2FIB_FLUSH_INT, mp);
6806
6807   mp->sw_if_index = ntohl (sw_if_index);
6808
6809   S (mp);
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_l2fib_add_del (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_l2fib_add_del_t *mp;
6819   f64 timeout;
6820   u8 mac[6] = { 0 };
6821   u8 mac_set = 0;
6822   u32 bd_id;
6823   u8 bd_id_set = 0;
6824   u32 sw_if_index = 0;
6825   u8 sw_if_index_set = 0;
6826   u8 is_add = 1;
6827   u8 static_mac = 0;
6828   u8 filter_mac = 0;
6829   u8 bvi_mac = 0;
6830   int count = 1;
6831   f64 before = 0;
6832   int j;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6838         mac_set = 1;
6839       else if (unformat (i, "bd_id %d", &bd_id))
6840         bd_id_set = 1;
6841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6842         sw_if_index_set = 1;
6843       else if (unformat (i, "sw_if"))
6844         {
6845           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846             {
6847               if (unformat
6848                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6849                 sw_if_index_set = 1;
6850             }
6851           else
6852             break;
6853         }
6854       else if (unformat (i, "static"))
6855         static_mac = 1;
6856       else if (unformat (i, "filter"))
6857         {
6858           filter_mac = 1;
6859           static_mac = 1;
6860         }
6861       else if (unformat (i, "bvi"))
6862         {
6863           bvi_mac = 1;
6864           static_mac = 1;
6865         }
6866       else if (unformat (i, "del"))
6867         is_add = 0;
6868       else if (unformat (i, "count %d", &count))
6869         ;
6870       else
6871         break;
6872     }
6873
6874   if (mac_set == 0)
6875     {
6876       errmsg ("missing mac address");
6877       return -99;
6878     }
6879
6880   if (bd_id_set == 0)
6881     {
6882       errmsg ("missing bridge domain");
6883       return -99;
6884     }
6885
6886   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6887     {
6888       errmsg ("missing interface name or sw_if_index");
6889       return -99;
6890     }
6891
6892   if (count > 1)
6893     {
6894       /* Turn on async mode */
6895       vam->async_mode = 1;
6896       vam->async_errors = 0;
6897       before = vat_time_now (vam);
6898     }
6899
6900   for (j = 0; j < count; j++)
6901     {
6902       M (L2FIB_ADD_DEL, mp);
6903
6904       clib_memcpy (mp->mac, mac, 6);
6905       mp->bd_id = ntohl (bd_id);
6906       mp->is_add = is_add;
6907       mp->sw_if_index = ntohl (sw_if_index);
6908
6909       if (is_add)
6910         {
6911           mp->static_mac = static_mac;
6912           mp->filter_mac = filter_mac;
6913           mp->bvi_mac = bvi_mac;
6914         }
6915       increment_mac_address (mac);
6916       /* send it... */
6917       S (mp);
6918     }
6919
6920   if (count > 1)
6921     {
6922       vl_api_control_ping_t *mp_ping;
6923       f64 after;
6924
6925       /* Shut off async mode */
6926       vam->async_mode = 0;
6927
6928       MPING (CONTROL_PING, mp_ping);
6929       S (mp_ping);
6930
6931       timeout = vat_time_now (vam) + 1.0;
6932       while (vat_time_now (vam) < timeout)
6933         if (vam->result_ready == 1)
6934           goto out;
6935       vam->retval = -99;
6936
6937     out:
6938       if (vam->retval == -99)
6939         errmsg ("timeout");
6940
6941       if (vam->async_errors > 0)
6942         {
6943           errmsg ("%d asynchronous errors", vam->async_errors);
6944           vam->retval = -98;
6945         }
6946       vam->async_errors = 0;
6947       after = vat_time_now (vam);
6948
6949       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6950              count, after - before, count / (after - before));
6951     }
6952   else
6953     {
6954       int ret;
6955
6956       /* Wait for a reply... */
6957       W (ret);
6958       return ret;
6959     }
6960   /* Return the good/bad news */
6961   return (vam->retval);
6962 }
6963
6964 static int
6965 api_bridge_domain_set_mac_age (vat_main_t * vam)
6966 {
6967   unformat_input_t *i = vam->input;
6968   vl_api_bridge_domain_set_mac_age_t *mp;
6969   u32 bd_id = ~0;
6970   u32 mac_age = 0;
6971   int ret;
6972
6973   /* Parse args required to build the message */
6974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6975     {
6976       if (unformat (i, "bd_id %d", &bd_id));
6977       else if (unformat (i, "mac-age %d", &mac_age));
6978       else
6979         break;
6980     }
6981
6982   if (bd_id == ~0)
6983     {
6984       errmsg ("missing bridge domain");
6985       return -99;
6986     }
6987
6988   if (mac_age > 255)
6989     {
6990       errmsg ("mac age must be less than 256 ");
6991       return -99;
6992     }
6993
6994   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6995
6996   mp->bd_id = htonl (bd_id);
6997   mp->mac_age = (u8) mac_age;
6998
6999   S (mp);
7000   W (ret);
7001   return ret;
7002 }
7003
7004 static int
7005 api_l2_flags (vat_main_t * vam)
7006 {
7007   unformat_input_t *i = vam->input;
7008   vl_api_l2_flags_t *mp;
7009   u32 sw_if_index;
7010   u32 flags = 0;
7011   u8 sw_if_index_set = 0;
7012   u8 is_set = 0;
7013   int ret;
7014
7015   /* Parse args required to build the message */
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "sw_if_index %d", &sw_if_index))
7019         sw_if_index_set = 1;
7020       else if (unformat (i, "sw_if"))
7021         {
7022           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023             {
7024               if (unformat
7025                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7026                 sw_if_index_set = 1;
7027             }
7028           else
7029             break;
7030         }
7031       else if (unformat (i, "learn"))
7032         flags |= L2_LEARN;
7033       else if (unformat (i, "forward"))
7034         flags |= L2_FWD;
7035       else if (unformat (i, "flood"))
7036         flags |= L2_FLOOD;
7037       else if (unformat (i, "uu-flood"))
7038         flags |= L2_UU_FLOOD;
7039       else if (unformat (i, "arp-term"))
7040         flags |= L2_ARP_TERM;
7041       else if (unformat (i, "off"))
7042         is_set = 0;
7043       else if (unformat (i, "disable"))
7044         is_set = 0;
7045       else
7046         break;
7047     }
7048
7049   if (sw_if_index_set == 0)
7050     {
7051       errmsg ("missing interface name or sw_if_index");
7052       return -99;
7053     }
7054
7055   M (L2_FLAGS, mp);
7056
7057   mp->sw_if_index = ntohl (sw_if_index);
7058   mp->feature_bitmap = ntohl (flags);
7059   mp->is_set = is_set;
7060
7061   S (mp);
7062   W (ret);
7063   return ret;
7064 }
7065
7066 static int
7067 api_bridge_flags (vat_main_t * vam)
7068 {
7069   unformat_input_t *i = vam->input;
7070   vl_api_bridge_flags_t *mp;
7071   u32 bd_id;
7072   u8 bd_id_set = 0;
7073   u8 is_set = 1;
7074   bd_flags_t flags = 0;
7075   int ret;
7076
7077   /* Parse args required to build the message */
7078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7079     {
7080       if (unformat (i, "bd_id %d", &bd_id))
7081         bd_id_set = 1;
7082       else if (unformat (i, "learn"))
7083         flags |= BRIDGE_API_FLAG_LEARN;
7084       else if (unformat (i, "forward"))
7085         flags |= BRIDGE_API_FLAG_FWD;
7086       else if (unformat (i, "flood"))
7087         flags |= BRIDGE_API_FLAG_FLOOD;
7088       else if (unformat (i, "uu-flood"))
7089         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7090       else if (unformat (i, "arp-term"))
7091         flags |= BRIDGE_API_FLAG_ARP_TERM;
7092       else if (unformat (i, "off"))
7093         is_set = 0;
7094       else if (unformat (i, "disable"))
7095         is_set = 0;
7096       else
7097         break;
7098     }
7099
7100   if (bd_id_set == 0)
7101     {
7102       errmsg ("missing bridge domain");
7103       return -99;
7104     }
7105
7106   M (BRIDGE_FLAGS, mp);
7107
7108   mp->bd_id = ntohl (bd_id);
7109   mp->flags = ntohl (flags);
7110   mp->is_set = is_set;
7111
7112   S (mp);
7113   W (ret);
7114   return ret;
7115 }
7116
7117 static int
7118 api_bd_ip_mac_add_del (vat_main_t * vam)
7119 {
7120   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7121   vl_api_mac_address_t mac = { 0 };
7122   unformat_input_t *i = vam->input;
7123   vl_api_bd_ip_mac_add_del_t *mp;
7124   u32 bd_id;
7125   u8 is_add = 1;
7126   u8 bd_id_set = 0;
7127   u8 ip_set = 0;
7128   u8 mac_set = 0;
7129   int ret;
7130
7131
7132   /* Parse args required to build the message */
7133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7134     {
7135       if (unformat (i, "bd_id %d", &bd_id))
7136         {
7137           bd_id_set++;
7138         }
7139       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7140         {
7141           ip_set++;
7142         }
7143       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7144         {
7145           mac_set++;
7146         }
7147       else if (unformat (i, "del"))
7148         is_add = 0;
7149       else
7150         break;
7151     }
7152
7153   if (bd_id_set == 0)
7154     {
7155       errmsg ("missing bridge domain");
7156       return -99;
7157     }
7158   else if (ip_set == 0)
7159     {
7160       errmsg ("missing IP address");
7161       return -99;
7162     }
7163   else if (mac_set == 0)
7164     {
7165       errmsg ("missing MAC address");
7166       return -99;
7167     }
7168
7169   M (BD_IP_MAC_ADD_DEL, mp);
7170
7171   mp->entry.bd_id = ntohl (bd_id);
7172   mp->is_add = is_add;
7173
7174   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7175   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7176
7177   S (mp);
7178   W (ret);
7179   return ret;
7180 }
7181
7182 static int
7183 api_bd_ip_mac_flush (vat_main_t * vam)
7184 {
7185   unformat_input_t *i = vam->input;
7186   vl_api_bd_ip_mac_flush_t *mp;
7187   u32 bd_id;
7188   u8 bd_id_set = 0;
7189   int ret;
7190
7191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7192     {
7193       if (unformat (i, "bd_id %d", &bd_id))
7194         {
7195           bd_id_set++;
7196         }
7197       else
7198         break;
7199     }
7200
7201   if (bd_id_set == 0)
7202     {
7203       errmsg ("missing bridge domain");
7204       return -99;
7205     }
7206
7207   M (BD_IP_MAC_FLUSH, mp);
7208
7209   mp->bd_id = ntohl (bd_id);
7210
7211   S (mp);
7212   W (ret);
7213   return ret;
7214 }
7215
7216 static void vl_api_bd_ip_mac_details_t_handler
7217   (vl_api_bd_ip_mac_details_t * mp)
7218 {
7219   vat_main_t *vam = &vat_main;
7220
7221   print (vam->ofp,
7222          "\n%-5d %U %U",
7223          ntohl (mp->entry.bd_id),
7224          format_vl_api_mac_address, mp->entry.mac,
7225          format_vl_api_address, &mp->entry.ip);
7226 }
7227
7228 static void vl_api_bd_ip_mac_details_t_handler_json
7229   (vl_api_bd_ip_mac_details_t * mp)
7230 {
7231   vat_main_t *vam = &vat_main;
7232   vat_json_node_t *node = NULL;
7233
7234   if (VAT_JSON_ARRAY != vam->json_tree.type)
7235     {
7236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7237       vat_json_init_array (&vam->json_tree);
7238     }
7239   node = vat_json_array_add (&vam->json_tree);
7240
7241   vat_json_init_object (node);
7242   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7243   vat_json_object_add_string_copy (node, "mac_address",
7244                                    format (0, "%U", format_vl_api_mac_address,
7245                                            &mp->entry.mac));
7246   u8 *ip = 0;
7247
7248   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7249   vat_json_object_add_string_copy (node, "ip_address", ip);
7250   vec_free (ip);
7251 }
7252
7253 static int
7254 api_bd_ip_mac_dump (vat_main_t * vam)
7255 {
7256   unformat_input_t *i = vam->input;
7257   vl_api_bd_ip_mac_dump_t *mp;
7258   vl_api_control_ping_t *mp_ping;
7259   int ret;
7260   u32 bd_id;
7261   u8 bd_id_set = 0;
7262
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264     {
7265       if (unformat (i, "bd_id %d", &bd_id))
7266         {
7267           bd_id_set++;
7268         }
7269       else
7270         break;
7271     }
7272
7273   print (vam->ofp,
7274          "\n%-5s %-7s %-20s %-30s",
7275          "bd_id", "is_ipv6", "mac_address", "ip_address");
7276
7277   /* Dump Bridge Domain Ip to Mac entries */
7278   M (BD_IP_MAC_DUMP, mp);
7279
7280   if (bd_id_set)
7281     mp->bd_id = htonl (bd_id);
7282   else
7283     mp->bd_id = ~0;
7284
7285   S (mp);
7286
7287   /* Use a control ping for synchronization */
7288   MPING (CONTROL_PING, mp_ping);
7289   S (mp_ping);
7290
7291   W (ret);
7292   return ret;
7293 }
7294
7295 static int
7296 api_tap_create_v2 (vat_main_t * vam)
7297 {
7298   unformat_input_t *i = vam->input;
7299   vl_api_tap_create_v2_t *mp;
7300   u8 mac_address[6];
7301   u8 random_mac = 1;
7302   u32 id = ~0;
7303   u32 num_rx_queues = 0;
7304   u8 *host_if_name = 0;
7305   u8 host_if_name_set = 0;
7306   u8 *host_ns = 0;
7307   u8 host_ns_set = 0;
7308   u8 host_mac_addr[6];
7309   u8 host_mac_addr_set = 0;
7310   u8 *host_bridge = 0;
7311   u8 host_bridge_set = 0;
7312   u8 host_ip4_prefix_set = 0;
7313   u8 host_ip6_prefix_set = 0;
7314   ip4_address_t host_ip4_addr;
7315   ip4_address_t host_ip4_gw;
7316   u8 host_ip4_gw_set = 0;
7317   u32 host_ip4_prefix_len = 0;
7318   ip6_address_t host_ip6_addr;
7319   ip6_address_t host_ip6_gw;
7320   u8 host_ip6_gw_set = 0;
7321   u32 host_ip6_prefix_len = 0;
7322   u32 host_mtu_size = 0;
7323   u8 host_mtu_set = 0;
7324   u32 tap_flags = 0;
7325   int ret;
7326   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7327
7328   clib_memset (mac_address, 0, sizeof (mac_address));
7329
7330   /* Parse args required to build the message */
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "id %u", &id))
7334         ;
7335       else
7336         if (unformat
7337             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7338         random_mac = 0;
7339       else if (unformat (i, "host-if-name %s", &host_if_name))
7340         host_if_name_set = 1;
7341       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7342         ;
7343       else if (unformat (i, "host-ns %s", &host_ns))
7344         host_ns_set = 1;
7345       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7346                          host_mac_addr))
7347         host_mac_addr_set = 1;
7348       else if (unformat (i, "host-bridge %s", &host_bridge))
7349         host_bridge_set = 1;
7350       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7351                          &host_ip4_addr, &host_ip4_prefix_len))
7352         host_ip4_prefix_set = 1;
7353       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7354                          &host_ip6_addr, &host_ip6_prefix_len))
7355         host_ip6_prefix_set = 1;
7356       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7357                          &host_ip4_gw))
7358         host_ip4_gw_set = 1;
7359       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7360                          &host_ip6_gw))
7361         host_ip6_gw_set = 1;
7362       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7363         ;
7364       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7365         ;
7366       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7367         host_mtu_set = 1;
7368       else if (unformat (i, "no-gso"))
7369         tap_flags &= ~TAP_FLAG_GSO;
7370       else if (unformat (i, "gso"))
7371         tap_flags |= TAP_FLAG_GSO;
7372       else if (unformat (i, "csum-offload"))
7373         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7374       else if (unformat (i, "persist"))
7375         tap_flags |= TAP_FLAG_PERSIST;
7376       else if (unformat (i, "attach"))
7377         tap_flags |= TAP_FLAG_ATTACH;
7378       else
7379         break;
7380     }
7381
7382   if (vec_len (host_if_name) > 63)
7383     {
7384       errmsg ("tap name too long. ");
7385       return -99;
7386     }
7387   if (vec_len (host_ns) > 63)
7388     {
7389       errmsg ("host name space too long. ");
7390       return -99;
7391     }
7392   if (vec_len (host_bridge) > 63)
7393     {
7394       errmsg ("host bridge name too long. ");
7395       return -99;
7396     }
7397   if (host_ip4_prefix_len > 32)
7398     {
7399       errmsg ("host ip4 prefix length not valid. ");
7400       return -99;
7401     }
7402   if (host_ip6_prefix_len > 128)
7403     {
7404       errmsg ("host ip6 prefix length not valid. ");
7405       return -99;
7406     }
7407   if (!is_pow2 (rx_ring_sz))
7408     {
7409       errmsg ("rx ring size must be power of 2. ");
7410       return -99;
7411     }
7412   if (rx_ring_sz > 32768)
7413     {
7414       errmsg ("rx ring size must be 32768 or lower. ");
7415       return -99;
7416     }
7417   if (!is_pow2 (tx_ring_sz))
7418     {
7419       errmsg ("tx ring size must be power of 2. ");
7420       return -99;
7421     }
7422   if (tx_ring_sz > 32768)
7423     {
7424       errmsg ("tx ring size must be 32768 or lower. ");
7425       return -99;
7426     }
7427   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7428     {
7429       errmsg ("host MTU size must be in between 64 and 65355. ");
7430       return -99;
7431     }
7432
7433   /* Construct the API message */
7434   M (TAP_CREATE_V2, mp);
7435
7436   mp->id = ntohl (id);
7437   mp->use_random_mac = random_mac;
7438   mp->num_rx_queues = (u8) num_rx_queues;
7439   mp->tx_ring_sz = ntohs (tx_ring_sz);
7440   mp->rx_ring_sz = ntohs (rx_ring_sz);
7441   mp->host_mtu_set = host_mtu_set;
7442   mp->host_mtu_size = ntohl (host_mtu_size);
7443   mp->host_mac_addr_set = host_mac_addr_set;
7444   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7445   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7446   mp->host_ip4_gw_set = host_ip4_gw_set;
7447   mp->host_ip6_gw_set = host_ip6_gw_set;
7448   mp->tap_flags = ntohl (tap_flags);
7449   mp->host_namespace_set = host_ns_set;
7450   mp->host_if_name_set = host_if_name_set;
7451   mp->host_bridge_set = host_bridge_set;
7452
7453   if (random_mac == 0)
7454     clib_memcpy (mp->mac_address, mac_address, 6);
7455   if (host_mac_addr_set)
7456     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7457   if (host_if_name_set)
7458     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7459   if (host_ns_set)
7460     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7461   if (host_bridge_set)
7462     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7463   if (host_ip4_prefix_set)
7464     {
7465       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7466       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7467     }
7468   if (host_ip6_prefix_set)
7469     {
7470       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7471       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7472     }
7473   if (host_ip4_gw_set)
7474     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7475   if (host_ip6_gw_set)
7476     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7477
7478   vec_free (host_ns);
7479   vec_free (host_if_name);
7480   vec_free (host_bridge);
7481
7482   /* send it... */
7483   S (mp);
7484
7485   /* Wait for a reply... */
7486   W (ret);
7487   return ret;
7488 }
7489
7490 static int
7491 api_tap_delete_v2 (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_tap_delete_v2_t *mp;
7495   u32 sw_if_index = ~0;
7496   u8 sw_if_index_set = 0;
7497   int ret;
7498
7499   /* Parse args required to build the message */
7500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7501     {
7502       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7503         sw_if_index_set = 1;
7504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7505         sw_if_index_set = 1;
7506       else
7507         break;
7508     }
7509
7510   if (sw_if_index_set == 0)
7511     {
7512       errmsg ("missing vpp interface name. ");
7513       return -99;
7514     }
7515
7516   /* Construct the API message */
7517   M (TAP_DELETE_V2, mp);
7518
7519   mp->sw_if_index = ntohl (sw_if_index);
7520
7521   /* send it... */
7522   S (mp);
7523
7524   /* Wait for a reply... */
7525   W (ret);
7526   return ret;
7527 }
7528
7529 uword
7530 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7531 {
7532   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7533   u32 x[4];
7534
7535   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7536     return 0;
7537
7538   addr->domain = x[0];
7539   addr->bus = x[1];
7540   addr->slot = x[2];
7541   addr->function = x[3];
7542
7543   return 1;
7544 }
7545
7546 static int
7547 api_virtio_pci_create (vat_main_t * vam)
7548 {
7549   unformat_input_t *i = vam->input;
7550   vl_api_virtio_pci_create_t *mp;
7551   u8 mac_address[6];
7552   u8 random_mac = 1;
7553   u8 gso_enabled = 0;
7554   u8 checksum_offload_enabled = 0;
7555   u32 pci_addr = 0;
7556   u64 features = (u64) ~ (0ULL);
7557   int ret;
7558
7559   clib_memset (mac_address, 0, sizeof (mac_address));
7560
7561   /* Parse args required to build the message */
7562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7563     {
7564       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7565         {
7566           random_mac = 0;
7567         }
7568       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7569         ;
7570       else if (unformat (i, "features 0x%llx", &features))
7571         ;
7572       else if (unformat (i, "gso-enabled"))
7573         gso_enabled = 1;
7574       else if (unformat (i, "csum-offload-enabled"))
7575         checksum_offload_enabled = 1;
7576       else
7577         break;
7578     }
7579
7580   if (pci_addr == 0)
7581     {
7582       errmsg ("pci address must be non zero. ");
7583       return -99;
7584     }
7585
7586   /* Construct the API message */
7587   M (VIRTIO_PCI_CREATE, mp);
7588
7589   mp->use_random_mac = random_mac;
7590
7591   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7592   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7593   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7594   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7595
7596   mp->features = clib_host_to_net_u64 (features);
7597   mp->gso_enabled = gso_enabled;
7598   mp->checksum_offload_enabled = checksum_offload_enabled;
7599
7600   if (random_mac == 0)
7601     clib_memcpy (mp->mac_address, mac_address, 6);
7602
7603   /* send it... */
7604   S (mp);
7605
7606   /* Wait for a reply... */
7607   W (ret);
7608   return ret;
7609 }
7610
7611 static int
7612 api_virtio_pci_delete (vat_main_t * vam)
7613 {
7614   unformat_input_t *i = vam->input;
7615   vl_api_virtio_pci_delete_t *mp;
7616   u32 sw_if_index = ~0;
7617   u8 sw_if_index_set = 0;
7618   int ret;
7619
7620   /* Parse args required to build the message */
7621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7622     {
7623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7624         sw_if_index_set = 1;
7625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7626         sw_if_index_set = 1;
7627       else
7628         break;
7629     }
7630
7631   if (sw_if_index_set == 0)
7632     {
7633       errmsg ("missing vpp interface name. ");
7634       return -99;
7635     }
7636
7637   /* Construct the API message */
7638   M (VIRTIO_PCI_DELETE, mp);
7639
7640   mp->sw_if_index = htonl (sw_if_index);
7641
7642   /* send it... */
7643   S (mp);
7644
7645   /* Wait for a reply... */
7646   W (ret);
7647   return ret;
7648 }
7649
7650 static int
7651 api_bond_create (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_bond_create_t *mp;
7655   u8 mac_address[6];
7656   u8 custom_mac = 0;
7657   int ret;
7658   u8 mode;
7659   u8 lb;
7660   u8 mode_is_set = 0;
7661   u32 id = ~0;
7662   u8 numa_only = 0;
7663
7664   clib_memset (mac_address, 0, sizeof (mac_address));
7665   lb = BOND_LB_L2;
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7671         mode_is_set = 1;
7672       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7673                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7674         ;
7675       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7676                          mac_address))
7677         custom_mac = 1;
7678       else if (unformat (i, "numa-only"))
7679         numa_only = 1;
7680       else if (unformat (i, "id %u", &id))
7681         ;
7682       else
7683         break;
7684     }
7685
7686   if (mode_is_set == 0)
7687     {
7688       errmsg ("Missing bond mode. ");
7689       return -99;
7690     }
7691
7692   /* Construct the API message */
7693   M (BOND_CREATE, mp);
7694
7695   mp->use_custom_mac = custom_mac;
7696
7697   mp->mode = htonl (mode);
7698   mp->lb = htonl (lb);
7699   mp->id = htonl (id);
7700   mp->numa_only = numa_only;
7701
7702   if (custom_mac)
7703     clib_memcpy (mp->mac_address, mac_address, 6);
7704
7705   /* send it... */
7706   S (mp);
7707
7708   /* Wait for a reply... */
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_bond_delete (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_bond_delete_t *mp;
7718   u32 sw_if_index = ~0;
7719   u8 sw_if_index_set = 0;
7720   int ret;
7721
7722   /* Parse args required to build the message */
7723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7724     {
7725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7726         sw_if_index_set = 1;
7727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7728         sw_if_index_set = 1;
7729       else
7730         break;
7731     }
7732
7733   if (sw_if_index_set == 0)
7734     {
7735       errmsg ("missing vpp interface name. ");
7736       return -99;
7737     }
7738
7739   /* Construct the API message */
7740   M (BOND_DELETE, mp);
7741
7742   mp->sw_if_index = ntohl (sw_if_index);
7743
7744   /* send it... */
7745   S (mp);
7746
7747   /* Wait for a reply... */
7748   W (ret);
7749   return ret;
7750 }
7751
7752 static int
7753 api_bond_enslave (vat_main_t * vam)
7754 {
7755   unformat_input_t *i = vam->input;
7756   vl_api_bond_enslave_t *mp;
7757   u32 bond_sw_if_index;
7758   int ret;
7759   u8 is_passive;
7760   u8 is_long_timeout;
7761   u32 bond_sw_if_index_is_set = 0;
7762   u32 sw_if_index;
7763   u8 sw_if_index_is_set = 0;
7764
7765   /* Parse args required to build the message */
7766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7767     {
7768       if (unformat (i, "sw_if_index %d", &sw_if_index))
7769         sw_if_index_is_set = 1;
7770       else if (unformat (i, "bond %u", &bond_sw_if_index))
7771         bond_sw_if_index_is_set = 1;
7772       else if (unformat (i, "passive %d", &is_passive))
7773         ;
7774       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7775         ;
7776       else
7777         break;
7778     }
7779
7780   if (bond_sw_if_index_is_set == 0)
7781     {
7782       errmsg ("Missing bond sw_if_index. ");
7783       return -99;
7784     }
7785   if (sw_if_index_is_set == 0)
7786     {
7787       errmsg ("Missing slave sw_if_index. ");
7788       return -99;
7789     }
7790
7791   /* Construct the API message */
7792   M (BOND_ENSLAVE, mp);
7793
7794   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7795   mp->sw_if_index = ntohl (sw_if_index);
7796   mp->is_long_timeout = is_long_timeout;
7797   mp->is_passive = is_passive;
7798
7799   /* send it... */
7800   S (mp);
7801
7802   /* Wait for a reply... */
7803   W (ret);
7804   return ret;
7805 }
7806
7807 static int
7808 api_bond_detach_slave (vat_main_t * vam)
7809 {
7810   unformat_input_t *i = vam->input;
7811   vl_api_bond_detach_slave_t *mp;
7812   u32 sw_if_index = ~0;
7813   u8 sw_if_index_set = 0;
7814   int ret;
7815
7816   /* Parse args required to build the message */
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7820         sw_if_index_set = 1;
7821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7822         sw_if_index_set = 1;
7823       else
7824         break;
7825     }
7826
7827   if (sw_if_index_set == 0)
7828     {
7829       errmsg ("missing vpp interface name. ");
7830       return -99;
7831     }
7832
7833   /* Construct the API message */
7834   M (BOND_DETACH_SLAVE, mp);
7835
7836   mp->sw_if_index = ntohl (sw_if_index);
7837
7838   /* send it... */
7839   S (mp);
7840
7841   /* Wait for a reply... */
7842   W (ret);
7843   return ret;
7844 }
7845
7846 static int
7847 api_ip_table_add_del (vat_main_t * vam)
7848 {
7849   unformat_input_t *i = vam->input;
7850   vl_api_ip_table_add_del_t *mp;
7851   u32 table_id = ~0;
7852   u8 is_ipv6 = 0;
7853   u8 is_add = 1;
7854   int ret = 0;
7855
7856   /* Parse args required to build the message */
7857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7858     {
7859       if (unformat (i, "ipv6"))
7860         is_ipv6 = 1;
7861       else if (unformat (i, "del"))
7862         is_add = 0;
7863       else if (unformat (i, "add"))
7864         is_add = 1;
7865       else if (unformat (i, "table %d", &table_id))
7866         ;
7867       else
7868         {
7869           clib_warning ("parse error '%U'", format_unformat_error, i);
7870           return -99;
7871         }
7872     }
7873
7874   if (~0 == table_id)
7875     {
7876       errmsg ("missing table-ID");
7877       return -99;
7878     }
7879
7880   /* Construct the API message */
7881   M (IP_TABLE_ADD_DEL, mp);
7882
7883   mp->table.table_id = ntohl (table_id);
7884   mp->table.is_ip6 = is_ipv6;
7885   mp->is_add = is_add;
7886
7887   /* send it... */
7888   S (mp);
7889
7890   /* Wait for a reply... */
7891   W (ret);
7892
7893   return ret;
7894 }
7895
7896 uword
7897 unformat_fib_path (unformat_input_t * input, va_list * args)
7898 {
7899   vat_main_t *vam = va_arg (*args, vat_main_t *);
7900   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7901   u32 weight, preference;
7902   mpls_label_t out_label;
7903
7904   clib_memset (path, 0, sizeof (*path));
7905   path->weight = 1;
7906   path->sw_if_index = ~0;
7907   path->rpf_id = ~0;
7908   path->n_labels = 0;
7909
7910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7911     {
7912       if (unformat (input, "%U %U",
7913                     unformat_vl_api_ip4_address,
7914                     &path->nh.address.ip4,
7915                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7916         {
7917           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7918         }
7919       else if (unformat (input, "%U %U",
7920                          unformat_vl_api_ip6_address,
7921                          &path->nh.address.ip6,
7922                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7923         {
7924           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7925         }
7926       else if (unformat (input, "weight %u", &weight))
7927         {
7928           path->weight = weight;
7929         }
7930       else if (unformat (input, "preference %u", &preference))
7931         {
7932           path->preference = preference;
7933         }
7934       else if (unformat (input, "%U next-hop-table %d",
7935                          unformat_vl_api_ip4_address,
7936                          &path->nh.address.ip4, &path->table_id))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7939         }
7940       else if (unformat (input, "%U next-hop-table %d",
7941                          unformat_vl_api_ip6_address,
7942                          &path->nh.address.ip6, &path->table_id))
7943         {
7944           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7945         }
7946       else if (unformat (input, "%U",
7947                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7948         {
7949           /*
7950            * the recursive next-hops are by default in the default table
7951            */
7952           path->table_id = 0;
7953           path->sw_if_index = ~0;
7954           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7955         }
7956       else if (unformat (input, "%U",
7957                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7958         {
7959           /*
7960            * the recursive next-hops are by default in the default table
7961            */
7962           path->table_id = 0;
7963           path->sw_if_index = ~0;
7964           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7965         }
7966       else if (unformat (input, "resolve-via-host"))
7967         {
7968           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7969         }
7970       else if (unformat (input, "resolve-via-attached"))
7971         {
7972           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7973         }
7974       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7975         {
7976           path->type = FIB_API_PATH_TYPE_LOCAL;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7979         }
7980       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7981         {
7982           path->type = FIB_API_PATH_TYPE_LOCAL;
7983           path->sw_if_index = ~0;
7984           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7985         }
7986       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7987         ;
7988       else if (unformat (input, "via-label %d", &path->nh.via_label))
7989         {
7990           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7991           path->sw_if_index = ~0;
7992         }
7993       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7994         {
7995           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7996           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7997         }
7998       else if (unformat (input, "local"))
7999         {
8000           path->type = FIB_API_PATH_TYPE_LOCAL;
8001         }
8002       else if (unformat (input, "out-labels"))
8003         {
8004           while (unformat (input, "%d", &out_label))
8005             {
8006               path->label_stack[path->n_labels].label = out_label;
8007               path->label_stack[path->n_labels].is_uniform = 0;
8008               path->label_stack[path->n_labels].ttl = 64;
8009               path->n_labels++;
8010             }
8011         }
8012       else if (unformat (input, "via"))
8013         {
8014           /* new path, back up and return */
8015           unformat_put_input (input);
8016           unformat_put_input (input);
8017           unformat_put_input (input);
8018           unformat_put_input (input);
8019           break;
8020         }
8021       else
8022         {
8023           return (0);
8024         }
8025     }
8026
8027   path->proto = ntohl (path->proto);
8028   path->type = ntohl (path->type);
8029   path->flags = ntohl (path->flags);
8030   path->table_id = ntohl (path->table_id);
8031   path->sw_if_index = ntohl (path->sw_if_index);
8032
8033   return (1);
8034 }
8035
8036 static int
8037 api_ip_route_add_del (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_route_add_del_t *mp;
8041   u32 vrf_id = 0;
8042   u8 is_add = 1;
8043   u8 is_multipath = 0;
8044   u8 prefix_set = 0;
8045   u8 path_count = 0;
8046   vl_api_prefix_t pfx = { };
8047   vl_api_fib_path_t paths[8];
8048   int count = 1;
8049   int j;
8050   f64 before = 0;
8051   u32 random_add_del = 0;
8052   u32 *random_vector = 0;
8053   u32 random_seed = 0xdeaddabe;
8054
8055   /* Parse args required to build the message */
8056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8057     {
8058       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8059         prefix_set = 1;
8060       else if (unformat (i, "del"))
8061         is_add = 0;
8062       else if (unformat (i, "add"))
8063         is_add = 1;
8064       else if (unformat (i, "vrf %d", &vrf_id))
8065         ;
8066       else if (unformat (i, "count %d", &count))
8067         ;
8068       else if (unformat (i, "random"))
8069         random_add_del = 1;
8070       else if (unformat (i, "multipath"))
8071         is_multipath = 1;
8072       else if (unformat (i, "seed %d", &random_seed))
8073         ;
8074       else
8075         if (unformat
8076             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8077         {
8078           path_count++;
8079           if (8 == path_count)
8080             {
8081               errmsg ("max 8 paths");
8082               return -99;
8083             }
8084         }
8085       else
8086         {
8087           clib_warning ("parse error '%U'", format_unformat_error, i);
8088           return -99;
8089         }
8090     }
8091
8092   if (!path_count)
8093     {
8094       errmsg ("specify a path; via ...");
8095       return -99;
8096     }
8097   if (prefix_set == 0)
8098     {
8099       errmsg ("missing prefix");
8100       return -99;
8101     }
8102
8103   /* Generate a pile of unique, random routes */
8104   if (random_add_del)
8105     {
8106       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8107       u32 this_random_address;
8108       uword *random_hash;
8109
8110       random_hash = hash_create (count, sizeof (uword));
8111
8112       hash_set (random_hash, i->as_u32, 1);
8113       for (j = 0; j <= count; j++)
8114         {
8115           do
8116             {
8117               this_random_address = random_u32 (&random_seed);
8118               this_random_address =
8119                 clib_host_to_net_u32 (this_random_address);
8120             }
8121           while (hash_get (random_hash, this_random_address));
8122           vec_add1 (random_vector, this_random_address);
8123           hash_set (random_hash, this_random_address, 1);
8124         }
8125       hash_free (random_hash);
8126       set_ip4_address (&pfx.address, random_vector[0]);
8127     }
8128
8129   if (count > 1)
8130     {
8131       /* Turn on async mode */
8132       vam->async_mode = 1;
8133       vam->async_errors = 0;
8134       before = vat_time_now (vam);
8135     }
8136
8137   for (j = 0; j < count; j++)
8138     {
8139       /* Construct the API message */
8140       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8141
8142       mp->is_add = is_add;
8143       mp->is_multipath = is_multipath;
8144
8145       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8146       mp->route.table_id = ntohl (vrf_id);
8147       mp->route.n_paths = path_count;
8148
8149       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8150
8151       if (random_add_del)
8152         set_ip4_address (&pfx.address, random_vector[j + 1]);
8153       else
8154         increment_address (&pfx.address);
8155       /* send it... */
8156       S (mp);
8157       /* If we receive SIGTERM, stop now... */
8158       if (vam->do_exit)
8159         break;
8160     }
8161
8162   /* When testing multiple add/del ops, use a control-ping to sync */
8163   if (count > 1)
8164     {
8165       vl_api_control_ping_t *mp_ping;
8166       f64 after;
8167       f64 timeout;
8168
8169       /* Shut off async mode */
8170       vam->async_mode = 0;
8171
8172       MPING (CONTROL_PING, mp_ping);
8173       S (mp_ping);
8174
8175       timeout = vat_time_now (vam) + 1.0;
8176       while (vat_time_now (vam) < timeout)
8177         if (vam->result_ready == 1)
8178           goto out;
8179       vam->retval = -99;
8180
8181     out:
8182       if (vam->retval == -99)
8183         errmsg ("timeout");
8184
8185       if (vam->async_errors > 0)
8186         {
8187           errmsg ("%d asynchronous errors", vam->async_errors);
8188           vam->retval = -98;
8189         }
8190       vam->async_errors = 0;
8191       after = vat_time_now (vam);
8192
8193       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8194       if (j > 0)
8195         count = j;
8196
8197       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8198              count, after - before, count / (after - before));
8199     }
8200   else
8201     {
8202       int ret;
8203
8204       /* Wait for a reply... */
8205       W (ret);
8206       return ret;
8207     }
8208
8209   /* Return the good/bad news */
8210   return (vam->retval);
8211 }
8212
8213 static int
8214 api_ip_mroute_add_del (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   u8 path_set = 0, prefix_set = 0, is_add = 1;
8218   vl_api_ip_mroute_add_del_t *mp;
8219   mfib_entry_flags_t eflags = 0;
8220   vl_api_mfib_path_t path;
8221   vl_api_mprefix_t pfx = { };
8222   u32 vrf_id = 0;
8223   int ret;
8224
8225   /* Parse args required to build the message */
8226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8227     {
8228       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8229         {
8230           prefix_set = 1;
8231           pfx.grp_address_length = htons (pfx.grp_address_length);
8232         }
8233       else if (unformat (i, "del"))
8234         is_add = 0;
8235       else if (unformat (i, "add"))
8236         is_add = 1;
8237       else if (unformat (i, "vrf %d", &vrf_id))
8238         ;
8239       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8240         path.itf_flags = htonl (path.itf_flags);
8241       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8242         ;
8243       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8244         path_set = 1;
8245       else
8246         {
8247           clib_warning ("parse error '%U'", format_unformat_error, i);
8248           return -99;
8249         }
8250     }
8251
8252   if (prefix_set == 0)
8253     {
8254       errmsg ("missing addresses\n");
8255       return -99;
8256     }
8257   if (path_set == 0)
8258     {
8259       errmsg ("missing path\n");
8260       return -99;
8261     }
8262
8263   /* Construct the API message */
8264   M (IP_MROUTE_ADD_DEL, mp);
8265
8266   mp->is_add = is_add;
8267   mp->is_multipath = 1;
8268
8269   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8270   mp->route.table_id = htonl (vrf_id);
8271   mp->route.n_paths = 1;
8272   mp->route.entry_flags = htonl (eflags);
8273
8274   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8275
8276   /* send it... */
8277   S (mp);
8278   /* Wait for a reply... */
8279   W (ret);
8280   return ret;
8281 }
8282
8283 static int
8284 api_mpls_table_add_del (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_mpls_table_add_del_t *mp;
8288   u32 table_id = ~0;
8289   u8 is_add = 1;
8290   int ret = 0;
8291
8292   /* Parse args required to build the message */
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "table %d", &table_id))
8296         ;
8297       else if (unformat (i, "del"))
8298         is_add = 0;
8299       else if (unformat (i, "add"))
8300         is_add = 1;
8301       else
8302         {
8303           clib_warning ("parse error '%U'", format_unformat_error, i);
8304           return -99;
8305         }
8306     }
8307
8308   if (~0 == table_id)
8309     {
8310       errmsg ("missing table-ID");
8311       return -99;
8312     }
8313
8314   /* Construct the API message */
8315   M (MPLS_TABLE_ADD_DEL, mp);
8316
8317   mp->mt_table.mt_table_id = ntohl (table_id);
8318   mp->mt_is_add = is_add;
8319
8320   /* send it... */
8321   S (mp);
8322
8323   /* Wait for a reply... */
8324   W (ret);
8325
8326   return ret;
8327 }
8328
8329 static int
8330 api_mpls_route_add_del (vat_main_t * vam)
8331 {
8332   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8333   mpls_label_t local_label = MPLS_LABEL_INVALID;
8334   unformat_input_t *i = vam->input;
8335   vl_api_mpls_route_add_del_t *mp;
8336   vl_api_fib_path_t paths[8];
8337   int count = 1, j;
8338   f64 before = 0;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "%d", &local_label))
8344         ;
8345       else if (unformat (i, "eos"))
8346         is_eos = 1;
8347       else if (unformat (i, "non-eos"))
8348         is_eos = 0;
8349       else if (unformat (i, "del"))
8350         is_add = 0;
8351       else if (unformat (i, "add"))
8352         is_add = 1;
8353       else if (unformat (i, "multipath"))
8354         is_multipath = 1;
8355       else if (unformat (i, "count %d", &count))
8356         ;
8357       else
8358         if (unformat
8359             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8360         {
8361           path_count++;
8362           if (8 == path_count)
8363             {
8364               errmsg ("max 8 paths");
8365               return -99;
8366             }
8367         }
8368       else
8369         {
8370           clib_warning ("parse error '%U'", format_unformat_error, i);
8371           return -99;
8372         }
8373     }
8374
8375   if (!path_count)
8376     {
8377       errmsg ("specify a path; via ...");
8378       return -99;
8379     }
8380
8381   if (MPLS_LABEL_INVALID == local_label)
8382     {
8383       errmsg ("missing label");
8384       return -99;
8385     }
8386
8387   if (count > 1)
8388     {
8389       /* Turn on async mode */
8390       vam->async_mode = 1;
8391       vam->async_errors = 0;
8392       before = vat_time_now (vam);
8393     }
8394
8395   for (j = 0; j < count; j++)
8396     {
8397       /* Construct the API message */
8398       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8399
8400       mp->mr_is_add = is_add;
8401       mp->mr_is_multipath = is_multipath;
8402
8403       mp->mr_route.mr_label = local_label;
8404       mp->mr_route.mr_eos = is_eos;
8405       mp->mr_route.mr_table_id = 0;
8406       mp->mr_route.mr_n_paths = path_count;
8407
8408       clib_memcpy (&mp->mr_route.mr_paths, paths,
8409                    sizeof (paths[0]) * path_count);
8410
8411       local_label++;
8412
8413       /* send it... */
8414       S (mp);
8415       /* If we receive SIGTERM, stop now... */
8416       if (vam->do_exit)
8417         break;
8418     }
8419
8420   /* When testing multiple add/del ops, use a control-ping to sync */
8421   if (count > 1)
8422     {
8423       vl_api_control_ping_t *mp_ping;
8424       f64 after;
8425       f64 timeout;
8426
8427       /* Shut off async mode */
8428       vam->async_mode = 0;
8429
8430       MPING (CONTROL_PING, mp_ping);
8431       S (mp_ping);
8432
8433       timeout = vat_time_now (vam) + 1.0;
8434       while (vat_time_now (vam) < timeout)
8435         if (vam->result_ready == 1)
8436           goto out;
8437       vam->retval = -99;
8438
8439     out:
8440       if (vam->retval == -99)
8441         errmsg ("timeout");
8442
8443       if (vam->async_errors > 0)
8444         {
8445           errmsg ("%d asynchronous errors", vam->async_errors);
8446           vam->retval = -98;
8447         }
8448       vam->async_errors = 0;
8449       after = vat_time_now (vam);
8450
8451       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8452       if (j > 0)
8453         count = j;
8454
8455       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8456              count, after - before, count / (after - before));
8457     }
8458   else
8459     {
8460       int ret;
8461
8462       /* Wait for a reply... */
8463       W (ret);
8464       return ret;
8465     }
8466
8467   /* Return the good/bad news */
8468   return (vam->retval);
8469   return (0);
8470 }
8471
8472 static int
8473 api_mpls_ip_bind_unbind (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_mpls_ip_bind_unbind_t *mp;
8477   u32 ip_table_id = 0;
8478   u8 is_bind = 1;
8479   vl_api_prefix_t pfx;
8480   u8 prefix_set = 0;
8481   mpls_label_t local_label = MPLS_LABEL_INVALID;
8482   int ret;
8483
8484   /* Parse args required to build the message */
8485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8486     {
8487       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8488         prefix_set = 1;
8489       else if (unformat (i, "%d", &local_label))
8490         ;
8491       else if (unformat (i, "table-id %d", &ip_table_id))
8492         ;
8493       else if (unformat (i, "unbind"))
8494         is_bind = 0;
8495       else if (unformat (i, "bind"))
8496         is_bind = 1;
8497       else
8498         {
8499           clib_warning ("parse error '%U'", format_unformat_error, i);
8500           return -99;
8501         }
8502     }
8503
8504   if (!prefix_set)
8505     {
8506       errmsg ("IP prefix not set");
8507       return -99;
8508     }
8509
8510   if (MPLS_LABEL_INVALID == local_label)
8511     {
8512       errmsg ("missing label");
8513       return -99;
8514     }
8515
8516   /* Construct the API message */
8517   M (MPLS_IP_BIND_UNBIND, mp);
8518
8519   mp->mb_is_bind = is_bind;
8520   mp->mb_ip_table_id = ntohl (ip_table_id);
8521   mp->mb_mpls_table_id = 0;
8522   mp->mb_label = ntohl (local_label);
8523   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8524
8525   /* send it... */
8526   S (mp);
8527
8528   /* Wait for a reply... */
8529   W (ret);
8530   return ret;
8531   return (0);
8532 }
8533
8534 static int
8535 api_sr_mpls_policy_add (vat_main_t * vam)
8536 {
8537   unformat_input_t *i = vam->input;
8538   vl_api_sr_mpls_policy_add_t *mp;
8539   u32 bsid = 0;
8540   u32 weight = 1;
8541   u8 type = 0;
8542   u8 n_segments = 0;
8543   u32 sid;
8544   u32 *segments = NULL;
8545   int ret;
8546
8547   /* Parse args required to build the message */
8548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8549     {
8550       if (unformat (i, "bsid %d", &bsid))
8551         ;
8552       else if (unformat (i, "weight %d", &weight))
8553         ;
8554       else if (unformat (i, "spray"))
8555         type = 1;
8556       else if (unformat (i, "next %d", &sid))
8557         {
8558           n_segments += 1;
8559           vec_add1 (segments, htonl (sid));
8560         }
8561       else
8562         {
8563           clib_warning ("parse error '%U'", format_unformat_error, i);
8564           return -99;
8565         }
8566     }
8567
8568   if (bsid == 0)
8569     {
8570       errmsg ("bsid not set");
8571       return -99;
8572     }
8573
8574   if (n_segments == 0)
8575     {
8576       errmsg ("no sid in segment stack");
8577       return -99;
8578     }
8579
8580   /* Construct the API message */
8581   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8582
8583   mp->bsid = htonl (bsid);
8584   mp->weight = htonl (weight);
8585   mp->is_spray = type;
8586   mp->n_segments = n_segments;
8587   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8588   vec_free (segments);
8589
8590   /* send it... */
8591   S (mp);
8592
8593   /* Wait for a reply... */
8594   W (ret);
8595   return ret;
8596 }
8597
8598 static int
8599 api_sr_mpls_policy_del (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_sr_mpls_policy_del_t *mp;
8603   u32 bsid = 0;
8604   int ret;
8605
8606   /* Parse args required to build the message */
8607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8608     {
8609       if (unformat (i, "bsid %d", &bsid))
8610         ;
8611       else
8612         {
8613           clib_warning ("parse error '%U'", format_unformat_error, i);
8614           return -99;
8615         }
8616     }
8617
8618   if (bsid == 0)
8619     {
8620       errmsg ("bsid not set");
8621       return -99;
8622     }
8623
8624   /* Construct the API message */
8625   M (SR_MPLS_POLICY_DEL, mp);
8626
8627   mp->bsid = htonl (bsid);
8628
8629   /* send it... */
8630   S (mp);
8631
8632   /* Wait for a reply... */
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_bier_table_add_del (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_bier_table_add_del_t *mp;
8642   u8 is_add = 1;
8643   u32 set = 0, sub_domain = 0, hdr_len = 3;
8644   mpls_label_t local_label = MPLS_LABEL_INVALID;
8645   int ret;
8646
8647   /* Parse args required to build the message */
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "sub-domain %d", &sub_domain))
8651         ;
8652       else if (unformat (i, "set %d", &set))
8653         ;
8654       else if (unformat (i, "label %d", &local_label))
8655         ;
8656       else if (unformat (i, "hdr-len %d", &hdr_len))
8657         ;
8658       else if (unformat (i, "add"))
8659         is_add = 1;
8660       else if (unformat (i, "del"))
8661         is_add = 0;
8662       else
8663         {
8664           clib_warning ("parse error '%U'", format_unformat_error, i);
8665           return -99;
8666         }
8667     }
8668
8669   if (MPLS_LABEL_INVALID == local_label)
8670     {
8671       errmsg ("missing label\n");
8672       return -99;
8673     }
8674
8675   /* Construct the API message */
8676   M (BIER_TABLE_ADD_DEL, mp);
8677
8678   mp->bt_is_add = is_add;
8679   mp->bt_label = ntohl (local_label);
8680   mp->bt_tbl_id.bt_set = set;
8681   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8682   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8683
8684   /* send it... */
8685   S (mp);
8686
8687   /* Wait for a reply... */
8688   W (ret);
8689
8690   return (ret);
8691 }
8692
8693 static int
8694 api_bier_route_add_del (vat_main_t * vam)
8695 {
8696   unformat_input_t *i = vam->input;
8697   vl_api_bier_route_add_del_t *mp;
8698   u8 is_add = 1;
8699   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8700   ip4_address_t v4_next_hop_address;
8701   ip6_address_t v6_next_hop_address;
8702   u8 next_hop_set = 0;
8703   u8 next_hop_proto_is_ip4 = 1;
8704   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8705   int ret;
8706
8707   /* Parse args required to build the message */
8708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8709     {
8710       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8711         {
8712           next_hop_proto_is_ip4 = 1;
8713           next_hop_set = 1;
8714         }
8715       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8716         {
8717           next_hop_proto_is_ip4 = 0;
8718           next_hop_set = 1;
8719         }
8720       if (unformat (i, "sub-domain %d", &sub_domain))
8721         ;
8722       else if (unformat (i, "set %d", &set))
8723         ;
8724       else if (unformat (i, "hdr-len %d", &hdr_len))
8725         ;
8726       else if (unformat (i, "bp %d", &bp))
8727         ;
8728       else if (unformat (i, "add"))
8729         is_add = 1;
8730       else if (unformat (i, "del"))
8731         is_add = 0;
8732       else if (unformat (i, "out-label %d", &next_hop_out_label))
8733         ;
8734       else
8735         {
8736           clib_warning ("parse error '%U'", format_unformat_error, i);
8737           return -99;
8738         }
8739     }
8740
8741   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8742     {
8743       errmsg ("next hop / label set\n");
8744       return -99;
8745     }
8746   if (0 == bp)
8747     {
8748       errmsg ("bit=position not set\n");
8749       return -99;
8750     }
8751
8752   /* Construct the API message */
8753   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8754
8755   mp->br_is_add = is_add;
8756   mp->br_route.br_tbl_id.bt_set = set;
8757   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8758   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8759   mp->br_route.br_bp = ntohs (bp);
8760   mp->br_route.br_n_paths = 1;
8761   mp->br_route.br_paths[0].n_labels = 1;
8762   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8763   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8764                                     FIB_API_PATH_NH_PROTO_IP4 :
8765                                     FIB_API_PATH_NH_PROTO_IP6);
8766
8767   if (next_hop_proto_is_ip4)
8768     {
8769       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8770                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8771     }
8772   else
8773     {
8774       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8775                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8776     }
8777
8778   /* send it... */
8779   S (mp);
8780
8781   /* Wait for a reply... */
8782   W (ret);
8783
8784   return (ret);
8785 }
8786
8787 static int
8788 api_mpls_tunnel_add_del (vat_main_t * vam)
8789 {
8790   unformat_input_t *i = vam->input;
8791   vl_api_mpls_tunnel_add_del_t *mp;
8792
8793   vl_api_fib_path_t paths[8];
8794   u32 sw_if_index = ~0;
8795   u8 path_count = 0;
8796   u8 l2_only = 0;
8797   u8 is_add = 1;
8798   int ret;
8799
8800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8801     {
8802       if (unformat (i, "add"))
8803         is_add = 1;
8804       else
8805         if (unformat
8806             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8807         is_add = 0;
8808       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8809         is_add = 0;
8810       else if (unformat (i, "l2-only"))
8811         l2_only = 1;
8812       else
8813         if (unformat
8814             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8815         {
8816           path_count++;
8817           if (8 == path_count)
8818             {
8819               errmsg ("max 8 paths");
8820               return -99;
8821             }
8822         }
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8831
8832   mp->mt_is_add = is_add;
8833   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8834   mp->mt_tunnel.mt_l2_only = l2_only;
8835   mp->mt_tunnel.mt_is_multicast = 0;
8836   mp->mt_tunnel.mt_n_paths = path_count;
8837
8838   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8839                sizeof (paths[0]) * path_count);
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_sw_interface_set_unnumbered (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_sw_interface_set_unnumbered_t *mp;
8851   u32 sw_if_index;
8852   u32 unnum_sw_index = ~0;
8853   u8 is_add = 1;
8854   u8 sw_if_index_set = 0;
8855   int ret;
8856
8857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8862         sw_if_index_set = 1;
8863       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8864         ;
8865       else if (unformat (i, "del"))
8866         is_add = 0;
8867       else
8868         {
8869           clib_warning ("parse error '%U'", format_unformat_error, i);
8870           return -99;
8871         }
8872     }
8873
8874   if (sw_if_index_set == 0)
8875     {
8876       errmsg ("missing interface name or sw_if_index");
8877       return -99;
8878     }
8879
8880   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8881
8882   mp->sw_if_index = ntohl (sw_if_index);
8883   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8884   mp->is_add = is_add;
8885
8886   S (mp);
8887   W (ret);
8888   return ret;
8889 }
8890
8891
8892 static int
8893 api_create_vlan_subif (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_create_vlan_subif_t *mp;
8897   u32 sw_if_index;
8898   u8 sw_if_index_set = 0;
8899   u32 vlan_id;
8900   u8 vlan_id_set = 0;
8901   int ret;
8902
8903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8904     {
8905       if (unformat (i, "sw_if_index %d", &sw_if_index))
8906         sw_if_index_set = 1;
8907       else
8908         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8909         sw_if_index_set = 1;
8910       else if (unformat (i, "vlan %d", &vlan_id))
8911         vlan_id_set = 1;
8912       else
8913         {
8914           clib_warning ("parse error '%U'", format_unformat_error, i);
8915           return -99;
8916         }
8917     }
8918
8919   if (sw_if_index_set == 0)
8920     {
8921       errmsg ("missing interface name or sw_if_index");
8922       return -99;
8923     }
8924
8925   if (vlan_id_set == 0)
8926     {
8927       errmsg ("missing vlan_id");
8928       return -99;
8929     }
8930   M (CREATE_VLAN_SUBIF, mp);
8931
8932   mp->sw_if_index = ntohl (sw_if_index);
8933   mp->vlan_id = ntohl (vlan_id);
8934
8935   S (mp);
8936   W (ret);
8937   return ret;
8938 }
8939
8940 #define foreach_create_subif_bit                \
8941 _(no_tags)                                      \
8942 _(one_tag)                                      \
8943 _(two_tags)                                     \
8944 _(dot1ad)                                       \
8945 _(exact_match)                                  \
8946 _(default_sub)                                  \
8947 _(outer_vlan_id_any)                            \
8948 _(inner_vlan_id_any)
8949
8950 #define foreach_create_subif_flag               \
8951 _(0, "no_tags")                                 \
8952 _(1, "one_tag")                                 \
8953 _(2, "two_tags")                                \
8954 _(3, "dot1ad")                                  \
8955 _(4, "exact_match")                             \
8956 _(5, "default_sub")                             \
8957 _(6, "outer_vlan_id_any")                       \
8958 _(7, "inner_vlan_id_any")
8959
8960 static int
8961 api_create_subif (vat_main_t * vam)
8962 {
8963   unformat_input_t *i = vam->input;
8964   vl_api_create_subif_t *mp;
8965   u32 sw_if_index;
8966   u8 sw_if_index_set = 0;
8967   u32 sub_id;
8968   u8 sub_id_set = 0;
8969   u32 __attribute__ ((unused)) no_tags = 0;
8970   u32 __attribute__ ((unused)) one_tag = 0;
8971   u32 __attribute__ ((unused)) two_tags = 0;
8972   u32 __attribute__ ((unused)) dot1ad = 0;
8973   u32 __attribute__ ((unused)) exact_match = 0;
8974   u32 __attribute__ ((unused)) default_sub = 0;
8975   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8976   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8977   u32 tmp;
8978   u16 outer_vlan_id = 0;
8979   u16 inner_vlan_id = 0;
8980   int ret;
8981
8982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8983     {
8984       if (unformat (i, "sw_if_index %d", &sw_if_index))
8985         sw_if_index_set = 1;
8986       else
8987         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8988         sw_if_index_set = 1;
8989       else if (unformat (i, "sub_id %d", &sub_id))
8990         sub_id_set = 1;
8991       else if (unformat (i, "outer_vlan_id %d", &tmp))
8992         outer_vlan_id = tmp;
8993       else if (unformat (i, "inner_vlan_id %d", &tmp))
8994         inner_vlan_id = tmp;
8995
8996 #define _(a) else if (unformat (i, #a)) a = 1 ;
8997       foreach_create_subif_bit
8998 #undef _
8999         else
9000         {
9001           clib_warning ("parse error '%U'", format_unformat_error, i);
9002           return -99;
9003         }
9004     }
9005
9006   if (sw_if_index_set == 0)
9007     {
9008       errmsg ("missing interface name or sw_if_index");
9009       return -99;
9010     }
9011
9012   if (sub_id_set == 0)
9013     {
9014       errmsg ("missing sub_id");
9015       return -99;
9016     }
9017   M (CREATE_SUBIF, mp);
9018
9019   mp->sw_if_index = ntohl (sw_if_index);
9020   mp->sub_id = ntohl (sub_id);
9021
9022 #define _(a,b) mp->sub_if_flags |= (1 << a);
9023   foreach_create_subif_flag;
9024 #undef _
9025
9026   mp->outer_vlan_id = ntohs (outer_vlan_id);
9027   mp->inner_vlan_id = ntohs (inner_vlan_id);
9028
9029   S (mp);
9030   W (ret);
9031   return ret;
9032 }
9033
9034 static int
9035 api_ip_table_replace_begin (vat_main_t * vam)
9036 {
9037   unformat_input_t *i = vam->input;
9038   vl_api_ip_table_replace_begin_t *mp;
9039   u32 table_id = 0;
9040   u8 is_ipv6 = 0;
9041
9042   int ret;
9043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9044     {
9045       if (unformat (i, "table %d", &table_id))
9046         ;
9047       else if (unformat (i, "ipv6"))
9048         is_ipv6 = 1;
9049       else
9050         {
9051           clib_warning ("parse error '%U'", format_unformat_error, i);
9052           return -99;
9053         }
9054     }
9055
9056   M (IP_TABLE_REPLACE_BEGIN, mp);
9057
9058   mp->table.table_id = ntohl (table_id);
9059   mp->table.is_ip6 = is_ipv6;
9060
9061   S (mp);
9062   W (ret);
9063   return ret;
9064 }
9065
9066 static int
9067 api_ip_table_flush (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_ip_table_flush_t *mp;
9071   u32 table_id = 0;
9072   u8 is_ipv6 = 0;
9073
9074   int ret;
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "table %d", &table_id))
9078         ;
9079       else if (unformat (i, "ipv6"))
9080         is_ipv6 = 1;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   M (IP_TABLE_FLUSH, mp);
9089
9090   mp->table.table_id = ntohl (table_id);
9091   mp->table.is_ip6 = is_ipv6;
9092
9093   S (mp);
9094   W (ret);
9095   return ret;
9096 }
9097
9098 static int
9099 api_ip_table_replace_end (vat_main_t * vam)
9100 {
9101   unformat_input_t *i = vam->input;
9102   vl_api_ip_table_replace_end_t *mp;
9103   u32 table_id = 0;
9104   u8 is_ipv6 = 0;
9105
9106   int ret;
9107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9108     {
9109       if (unformat (i, "table %d", &table_id))
9110         ;
9111       else if (unformat (i, "ipv6"))
9112         is_ipv6 = 1;
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   M (IP_TABLE_REPLACE_END, mp);
9121
9122   mp->table.table_id = ntohl (table_id);
9123   mp->table.is_ip6 = is_ipv6;
9124
9125   S (mp);
9126   W (ret);
9127   return ret;
9128 }
9129
9130 static int
9131 api_set_ip_flow_hash (vat_main_t * vam)
9132 {
9133   unformat_input_t *i = vam->input;
9134   vl_api_set_ip_flow_hash_t *mp;
9135   u32 vrf_id = 0;
9136   u8 is_ipv6 = 0;
9137   u8 vrf_id_set = 0;
9138   u8 src = 0;
9139   u8 dst = 0;
9140   u8 sport = 0;
9141   u8 dport = 0;
9142   u8 proto = 0;
9143   u8 reverse = 0;
9144   int ret;
9145
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "vrf %d", &vrf_id))
9149         vrf_id_set = 1;
9150       else if (unformat (i, "ipv6"))
9151         is_ipv6 = 1;
9152       else if (unformat (i, "src"))
9153         src = 1;
9154       else if (unformat (i, "dst"))
9155         dst = 1;
9156       else if (unformat (i, "sport"))
9157         sport = 1;
9158       else if (unformat (i, "dport"))
9159         dport = 1;
9160       else if (unformat (i, "proto"))
9161         proto = 1;
9162       else if (unformat (i, "reverse"))
9163         reverse = 1;
9164
9165       else
9166         {
9167           clib_warning ("parse error '%U'", format_unformat_error, i);
9168           return -99;
9169         }
9170     }
9171
9172   if (vrf_id_set == 0)
9173     {
9174       errmsg ("missing vrf id");
9175       return -99;
9176     }
9177
9178   M (SET_IP_FLOW_HASH, mp);
9179   mp->src = src;
9180   mp->dst = dst;
9181   mp->sport = sport;
9182   mp->dport = dport;
9183   mp->proto = proto;
9184   mp->reverse = reverse;
9185   mp->vrf_id = ntohl (vrf_id);
9186   mp->is_ipv6 = is_ipv6;
9187
9188   S (mp);
9189   W (ret);
9190   return ret;
9191 }
9192
9193 static int
9194 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9195 {
9196   unformat_input_t *i = vam->input;
9197   vl_api_sw_interface_ip6_enable_disable_t *mp;
9198   u32 sw_if_index;
9199   u8 sw_if_index_set = 0;
9200   u8 enable = 0;
9201   int ret;
9202
9203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9204     {
9205       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9206         sw_if_index_set = 1;
9207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9208         sw_if_index_set = 1;
9209       else if (unformat (i, "enable"))
9210         enable = 1;
9211       else if (unformat (i, "disable"))
9212         enable = 0;
9213       else
9214         {
9215           clib_warning ("parse error '%U'", format_unformat_error, i);
9216           return -99;
9217         }
9218     }
9219
9220   if (sw_if_index_set == 0)
9221     {
9222       errmsg ("missing interface name or sw_if_index");
9223       return -99;
9224     }
9225
9226   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9227
9228   mp->sw_if_index = ntohl (sw_if_index);
9229   mp->enable = enable;
9230
9231   S (mp);
9232   W (ret);
9233   return ret;
9234 }
9235
9236
9237 static int
9238 api_l2_patch_add_del (vat_main_t * vam)
9239 {
9240   unformat_input_t *i = vam->input;
9241   vl_api_l2_patch_add_del_t *mp;
9242   u32 rx_sw_if_index;
9243   u8 rx_sw_if_index_set = 0;
9244   u32 tx_sw_if_index;
9245   u8 tx_sw_if_index_set = 0;
9246   u8 is_add = 1;
9247   int ret;
9248
9249   /* Parse args required to build the message */
9250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9251     {
9252       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9253         rx_sw_if_index_set = 1;
9254       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9255         tx_sw_if_index_set = 1;
9256       else if (unformat (i, "rx"))
9257         {
9258           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9259             {
9260               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9261                             &rx_sw_if_index))
9262                 rx_sw_if_index_set = 1;
9263             }
9264           else
9265             break;
9266         }
9267       else if (unformat (i, "tx"))
9268         {
9269           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270             {
9271               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9272                             &tx_sw_if_index))
9273                 tx_sw_if_index_set = 1;
9274             }
9275           else
9276             break;
9277         }
9278       else if (unformat (i, "del"))
9279         is_add = 0;
9280       else
9281         break;
9282     }
9283
9284   if (rx_sw_if_index_set == 0)
9285     {
9286       errmsg ("missing rx interface name or rx_sw_if_index");
9287       return -99;
9288     }
9289
9290   if (tx_sw_if_index_set == 0)
9291     {
9292       errmsg ("missing tx interface name or tx_sw_if_index");
9293       return -99;
9294     }
9295
9296   M (L2_PATCH_ADD_DEL, mp);
9297
9298   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9299   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9300   mp->is_add = is_add;
9301
9302   S (mp);
9303   W (ret);
9304   return ret;
9305 }
9306
9307 u8 is_del;
9308 u8 localsid_addr[16];
9309 u8 end_psp;
9310 u8 behavior;
9311 u32 sw_if_index;
9312 u32 vlan_index;
9313 u32 fib_table;
9314 u8 nh_addr[16];
9315
9316 static int
9317 api_sr_localsid_add_del (vat_main_t * vam)
9318 {
9319   unformat_input_t *i = vam->input;
9320   vl_api_sr_localsid_add_del_t *mp;
9321
9322   u8 is_del;
9323   ip6_address_t localsid;
9324   u8 end_psp = 0;
9325   u8 behavior = ~0;
9326   u32 sw_if_index;
9327   u32 fib_table = ~(u32) 0;
9328   ip6_address_t nh_addr6;
9329   ip4_address_t nh_addr4;
9330   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9331   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9332
9333   bool nexthop_set = 0;
9334
9335   int ret;
9336
9337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9338     {
9339       if (unformat (i, "del"))
9340         is_del = 1;
9341       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9342       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9343         nexthop_set = 1;
9344       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9345         nexthop_set = 1;
9346       else if (unformat (i, "behavior %u", &behavior));
9347       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9348       else if (unformat (i, "fib-table %u", &fib_table));
9349       else if (unformat (i, "end.psp %u", &behavior));
9350       else
9351         break;
9352     }
9353
9354   M (SR_LOCALSID_ADD_DEL, mp);
9355
9356   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9357
9358   if (nexthop_set)
9359     {
9360       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9361       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9362     }
9363   mp->behavior = behavior;
9364   mp->sw_if_index = ntohl (sw_if_index);
9365   mp->fib_table = ntohl (fib_table);
9366   mp->end_psp = end_psp;
9367   mp->is_del = is_del;
9368
9369   S (mp);
9370   W (ret);
9371   return ret;
9372 }
9373
9374 static int
9375 api_ioam_enable (vat_main_t * vam)
9376 {
9377   unformat_input_t *input = vam->input;
9378   vl_api_ioam_enable_t *mp;
9379   u32 id = 0;
9380   int has_trace_option = 0;
9381   int has_pot_option = 0;
9382   int has_seqno_option = 0;
9383   int has_analyse_option = 0;
9384   int ret;
9385
9386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (input, "trace"))
9389         has_trace_option = 1;
9390       else if (unformat (input, "pot"))
9391         has_pot_option = 1;
9392       else if (unformat (input, "seqno"))
9393         has_seqno_option = 1;
9394       else if (unformat (input, "analyse"))
9395         has_analyse_option = 1;
9396       else
9397         break;
9398     }
9399   M (IOAM_ENABLE, mp);
9400   mp->id = htons (id);
9401   mp->seqno = has_seqno_option;
9402   mp->analyse = has_analyse_option;
9403   mp->pot_enable = has_pot_option;
9404   mp->trace_enable = has_trace_option;
9405
9406   S (mp);
9407   W (ret);
9408   return ret;
9409 }
9410
9411
9412 static int
9413 api_ioam_disable (vat_main_t * vam)
9414 {
9415   vl_api_ioam_disable_t *mp;
9416   int ret;
9417
9418   M (IOAM_DISABLE, mp);
9419   S (mp);
9420   W (ret);
9421   return ret;
9422 }
9423
9424 #define foreach_tcp_proto_field                 \
9425 _(src_port)                                     \
9426 _(dst_port)
9427
9428 #define foreach_udp_proto_field                 \
9429 _(src_port)                                     \
9430 _(dst_port)
9431
9432 #define foreach_ip4_proto_field                 \
9433 _(src_address)                                  \
9434 _(dst_address)                                  \
9435 _(tos)                                          \
9436 _(length)                                       \
9437 _(fragment_id)                                  \
9438 _(ttl)                                          \
9439 _(protocol)                                     \
9440 _(checksum)
9441
9442 typedef struct
9443 {
9444   u16 src_port, dst_port;
9445 } tcpudp_header_t;
9446
9447 #if VPP_API_TEST_BUILTIN == 0
9448 uword
9449 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9450 {
9451   u8 **maskp = va_arg (*args, u8 **);
9452   u8 *mask = 0;
9453   u8 found_something = 0;
9454   tcp_header_t *tcp;
9455
9456 #define _(a) u8 a=0;
9457   foreach_tcp_proto_field;
9458 #undef _
9459
9460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (0);
9463 #define _(a) else if (unformat (input, #a)) a=1;
9464       foreach_tcp_proto_field
9465 #undef _
9466         else
9467         break;
9468     }
9469
9470 #define _(a) found_something += a;
9471   foreach_tcp_proto_field;
9472 #undef _
9473
9474   if (found_something == 0)
9475     return 0;
9476
9477   vec_validate (mask, sizeof (*tcp) - 1);
9478
9479   tcp = (tcp_header_t *) mask;
9480
9481 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9482   foreach_tcp_proto_field;
9483 #undef _
9484
9485   *maskp = mask;
9486   return 1;
9487 }
9488
9489 uword
9490 unformat_udp_mask (unformat_input_t * input, va_list * args)
9491 {
9492   u8 **maskp = va_arg (*args, u8 **);
9493   u8 *mask = 0;
9494   u8 found_something = 0;
9495   udp_header_t *udp;
9496
9497 #define _(a) u8 a=0;
9498   foreach_udp_proto_field;
9499 #undef _
9500
9501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9502     {
9503       if (0);
9504 #define _(a) else if (unformat (input, #a)) a=1;
9505       foreach_udp_proto_field
9506 #undef _
9507         else
9508         break;
9509     }
9510
9511 #define _(a) found_something += a;
9512   foreach_udp_proto_field;
9513 #undef _
9514
9515   if (found_something == 0)
9516     return 0;
9517
9518   vec_validate (mask, sizeof (*udp) - 1);
9519
9520   udp = (udp_header_t *) mask;
9521
9522 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9523   foreach_udp_proto_field;
9524 #undef _
9525
9526   *maskp = mask;
9527   return 1;
9528 }
9529
9530 uword
9531 unformat_l4_mask (unformat_input_t * input, va_list * args)
9532 {
9533   u8 **maskp = va_arg (*args, u8 **);
9534   u16 src_port = 0, dst_port = 0;
9535   tcpudp_header_t *tcpudp;
9536
9537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9538     {
9539       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9540         return 1;
9541       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9542         return 1;
9543       else if (unformat (input, "src_port"))
9544         src_port = 0xFFFF;
9545       else if (unformat (input, "dst_port"))
9546         dst_port = 0xFFFF;
9547       else
9548         return 0;
9549     }
9550
9551   if (!src_port && !dst_port)
9552     return 0;
9553
9554   u8 *mask = 0;
9555   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9556
9557   tcpudp = (tcpudp_header_t *) mask;
9558   tcpudp->src_port = src_port;
9559   tcpudp->dst_port = dst_port;
9560
9561   *maskp = mask;
9562
9563   return 1;
9564 }
9565
9566 uword
9567 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9568 {
9569   u8 **maskp = va_arg (*args, u8 **);
9570   u8 *mask = 0;
9571   u8 found_something = 0;
9572   ip4_header_t *ip;
9573
9574 #define _(a) u8 a=0;
9575   foreach_ip4_proto_field;
9576 #undef _
9577   u8 version = 0;
9578   u8 hdr_length = 0;
9579
9580
9581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9582     {
9583       if (unformat (input, "version"))
9584         version = 1;
9585       else if (unformat (input, "hdr_length"))
9586         hdr_length = 1;
9587       else if (unformat (input, "src"))
9588         src_address = 1;
9589       else if (unformat (input, "dst"))
9590         dst_address = 1;
9591       else if (unformat (input, "proto"))
9592         protocol = 1;
9593
9594 #define _(a) else if (unformat (input, #a)) a=1;
9595       foreach_ip4_proto_field
9596 #undef _
9597         else
9598         break;
9599     }
9600
9601 #define _(a) found_something += a;
9602   foreach_ip4_proto_field;
9603 #undef _
9604
9605   if (found_something == 0)
9606     return 0;
9607
9608   vec_validate (mask, sizeof (*ip) - 1);
9609
9610   ip = (ip4_header_t *) mask;
9611
9612 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9613   foreach_ip4_proto_field;
9614 #undef _
9615
9616   ip->ip_version_and_header_length = 0;
9617
9618   if (version)
9619     ip->ip_version_and_header_length |= 0xF0;
9620
9621   if (hdr_length)
9622     ip->ip_version_and_header_length |= 0x0F;
9623
9624   *maskp = mask;
9625   return 1;
9626 }
9627
9628 #define foreach_ip6_proto_field                 \
9629 _(src_address)                                  \
9630 _(dst_address)                                  \
9631 _(payload_length)                               \
9632 _(hop_limit)                                    \
9633 _(protocol)
9634
9635 uword
9636 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9637 {
9638   u8 **maskp = va_arg (*args, u8 **);
9639   u8 *mask = 0;
9640   u8 found_something = 0;
9641   ip6_header_t *ip;
9642   u32 ip_version_traffic_class_and_flow_label;
9643
9644 #define _(a) u8 a=0;
9645   foreach_ip6_proto_field;
9646 #undef _
9647   u8 version = 0;
9648   u8 traffic_class = 0;
9649   u8 flow_label = 0;
9650
9651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (input, "version"))
9654         version = 1;
9655       else if (unformat (input, "traffic-class"))
9656         traffic_class = 1;
9657       else if (unformat (input, "flow-label"))
9658         flow_label = 1;
9659       else if (unformat (input, "src"))
9660         src_address = 1;
9661       else if (unformat (input, "dst"))
9662         dst_address = 1;
9663       else if (unformat (input, "proto"))
9664         protocol = 1;
9665
9666 #define _(a) else if (unformat (input, #a)) a=1;
9667       foreach_ip6_proto_field
9668 #undef _
9669         else
9670         break;
9671     }
9672
9673 #define _(a) found_something += a;
9674   foreach_ip6_proto_field;
9675 #undef _
9676
9677   if (found_something == 0)
9678     return 0;
9679
9680   vec_validate (mask, sizeof (*ip) - 1);
9681
9682   ip = (ip6_header_t *) mask;
9683
9684 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9685   foreach_ip6_proto_field;
9686 #undef _
9687
9688   ip_version_traffic_class_and_flow_label = 0;
9689
9690   if (version)
9691     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9692
9693   if (traffic_class)
9694     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9695
9696   if (flow_label)
9697     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9698
9699   ip->ip_version_traffic_class_and_flow_label =
9700     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9701
9702   *maskp = mask;
9703   return 1;
9704 }
9705
9706 uword
9707 unformat_l3_mask (unformat_input_t * input, va_list * args)
9708 {
9709   u8 **maskp = va_arg (*args, u8 **);
9710
9711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9712     {
9713       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9714         return 1;
9715       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9716         return 1;
9717       else
9718         break;
9719     }
9720   return 0;
9721 }
9722
9723 uword
9724 unformat_l2_mask (unformat_input_t * input, va_list * args)
9725 {
9726   u8 **maskp = va_arg (*args, u8 **);
9727   u8 *mask = 0;
9728   u8 src = 0;
9729   u8 dst = 0;
9730   u8 proto = 0;
9731   u8 tag1 = 0;
9732   u8 tag2 = 0;
9733   u8 ignore_tag1 = 0;
9734   u8 ignore_tag2 = 0;
9735   u8 cos1 = 0;
9736   u8 cos2 = 0;
9737   u8 dot1q = 0;
9738   u8 dot1ad = 0;
9739   int len = 14;
9740
9741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9742     {
9743       if (unformat (input, "src"))
9744         src = 1;
9745       else if (unformat (input, "dst"))
9746         dst = 1;
9747       else if (unformat (input, "proto"))
9748         proto = 1;
9749       else if (unformat (input, "tag1"))
9750         tag1 = 1;
9751       else if (unformat (input, "tag2"))
9752         tag2 = 1;
9753       else if (unformat (input, "ignore-tag1"))
9754         ignore_tag1 = 1;
9755       else if (unformat (input, "ignore-tag2"))
9756         ignore_tag2 = 1;
9757       else if (unformat (input, "cos1"))
9758         cos1 = 1;
9759       else if (unformat (input, "cos2"))
9760         cos2 = 1;
9761       else if (unformat (input, "dot1q"))
9762         dot1q = 1;
9763       else if (unformat (input, "dot1ad"))
9764         dot1ad = 1;
9765       else
9766         break;
9767     }
9768   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9769        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9770     return 0;
9771
9772   if (tag1 || ignore_tag1 || cos1 || dot1q)
9773     len = 18;
9774   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9775     len = 22;
9776
9777   vec_validate (mask, len - 1);
9778
9779   if (dst)
9780     clib_memset (mask, 0xff, 6);
9781
9782   if (src)
9783     clib_memset (mask + 6, 0xff, 6);
9784
9785   if (tag2 || dot1ad)
9786     {
9787       /* inner vlan tag */
9788       if (tag2)
9789         {
9790           mask[19] = 0xff;
9791           mask[18] = 0x0f;
9792         }
9793       if (cos2)
9794         mask[18] |= 0xe0;
9795       if (proto)
9796         mask[21] = mask[20] = 0xff;
9797       if (tag1)
9798         {
9799           mask[15] = 0xff;
9800           mask[14] = 0x0f;
9801         }
9802       if (cos1)
9803         mask[14] |= 0xe0;
9804       *maskp = mask;
9805       return 1;
9806     }
9807   if (tag1 | dot1q)
9808     {
9809       if (tag1)
9810         {
9811           mask[15] = 0xff;
9812           mask[14] = 0x0f;
9813         }
9814       if (cos1)
9815         mask[14] |= 0xe0;
9816       if (proto)
9817         mask[16] = mask[17] = 0xff;
9818
9819       *maskp = mask;
9820       return 1;
9821     }
9822   if (cos2)
9823     mask[18] |= 0xe0;
9824   if (cos1)
9825     mask[14] |= 0xe0;
9826   if (proto)
9827     mask[12] = mask[13] = 0xff;
9828
9829   *maskp = mask;
9830   return 1;
9831 }
9832
9833 uword
9834 unformat_classify_mask (unformat_input_t * input, va_list * args)
9835 {
9836   u8 **maskp = va_arg (*args, u8 **);
9837   u32 *skipp = va_arg (*args, u32 *);
9838   u32 *matchp = va_arg (*args, u32 *);
9839   u32 match;
9840   u8 *mask = 0;
9841   u8 *l2 = 0;
9842   u8 *l3 = 0;
9843   u8 *l4 = 0;
9844   int i;
9845
9846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9847     {
9848       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9849         ;
9850       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9851         ;
9852       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9853         ;
9854       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9855         ;
9856       else
9857         break;
9858     }
9859
9860   if (l4 && !l3)
9861     {
9862       vec_free (mask);
9863       vec_free (l2);
9864       vec_free (l4);
9865       return 0;
9866     }
9867
9868   if (mask || l2 || l3 || l4)
9869     {
9870       if (l2 || l3 || l4)
9871         {
9872           /* "With a free Ethernet header in every package" */
9873           if (l2 == 0)
9874             vec_validate (l2, 13);
9875           mask = l2;
9876           if (vec_len (l3))
9877             {
9878               vec_append (mask, l3);
9879               vec_free (l3);
9880             }
9881           if (vec_len (l4))
9882             {
9883               vec_append (mask, l4);
9884               vec_free (l4);
9885             }
9886         }
9887
9888       /* Scan forward looking for the first significant mask octet */
9889       for (i = 0; i < vec_len (mask); i++)
9890         if (mask[i])
9891           break;
9892
9893       /* compute (skip, match) params */
9894       *skipp = i / sizeof (u32x4);
9895       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9896
9897       /* Pad mask to an even multiple of the vector size */
9898       while (vec_len (mask) % sizeof (u32x4))
9899         vec_add1 (mask, 0);
9900
9901       match = vec_len (mask) / sizeof (u32x4);
9902
9903       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9904         {
9905           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9906           if (*tmp || *(tmp + 1))
9907             break;
9908           match--;
9909         }
9910       if (match == 0)
9911         clib_warning ("BUG: match 0");
9912
9913       _vec_len (mask) = match * sizeof (u32x4);
9914
9915       *matchp = match;
9916       *maskp = mask;
9917
9918       return 1;
9919     }
9920
9921   return 0;
9922 }
9923 #endif /* VPP_API_TEST_BUILTIN */
9924
9925 #define foreach_l2_next                         \
9926 _(drop, DROP)                                   \
9927 _(ethernet, ETHERNET_INPUT)                     \
9928 _(ip4, IP4_INPUT)                               \
9929 _(ip6, IP6_INPUT)
9930
9931 uword
9932 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9933 {
9934   u32 *miss_next_indexp = va_arg (*args, u32 *);
9935   u32 next_index = 0;
9936   u32 tmp;
9937
9938 #define _(n,N) \
9939   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9940   foreach_l2_next;
9941 #undef _
9942
9943   if (unformat (input, "%d", &tmp))
9944     {
9945       next_index = tmp;
9946       goto out;
9947     }
9948
9949   return 0;
9950
9951 out:
9952   *miss_next_indexp = next_index;
9953   return 1;
9954 }
9955
9956 #define foreach_ip_next                         \
9957 _(drop, DROP)                                   \
9958 _(local, LOCAL)                                 \
9959 _(rewrite, REWRITE)
9960
9961 uword
9962 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9963 {
9964   u32 *miss_next_indexp = va_arg (*args, u32 *);
9965   u32 next_index = 0;
9966   u32 tmp;
9967
9968 #define _(n,N) \
9969   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9970   foreach_ip_next;
9971 #undef _
9972
9973   if (unformat (input, "%d", &tmp))
9974     {
9975       next_index = tmp;
9976       goto out;
9977     }
9978
9979   return 0;
9980
9981 out:
9982   *miss_next_indexp = next_index;
9983   return 1;
9984 }
9985
9986 #define foreach_acl_next                        \
9987 _(deny, DENY)
9988
9989 uword
9990 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9991 {
9992   u32 *miss_next_indexp = va_arg (*args, u32 *);
9993   u32 next_index = 0;
9994   u32 tmp;
9995
9996 #define _(n,N) \
9997   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9998   foreach_acl_next;
9999 #undef _
10000
10001   if (unformat (input, "permit"))
10002     {
10003       next_index = ~0;
10004       goto out;
10005     }
10006   else if (unformat (input, "%d", &tmp))
10007     {
10008       next_index = tmp;
10009       goto out;
10010     }
10011
10012   return 0;
10013
10014 out:
10015   *miss_next_indexp = next_index;
10016   return 1;
10017 }
10018
10019 uword
10020 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10021 {
10022   u32 *r = va_arg (*args, u32 *);
10023
10024   if (unformat (input, "conform-color"))
10025     *r = POLICE_CONFORM;
10026   else if (unformat (input, "exceed-color"))
10027     *r = POLICE_EXCEED;
10028   else
10029     return 0;
10030
10031   return 1;
10032 }
10033
10034 static int
10035 api_classify_add_del_table (vat_main_t * vam)
10036 {
10037   unformat_input_t *i = vam->input;
10038   vl_api_classify_add_del_table_t *mp;
10039
10040   u32 nbuckets = 2;
10041   u32 skip = ~0;
10042   u32 match = ~0;
10043   int is_add = 1;
10044   int del_chain = 0;
10045   u32 table_index = ~0;
10046   u32 next_table_index = ~0;
10047   u32 miss_next_index = ~0;
10048   u32 memory_size = 32 << 20;
10049   u8 *mask = 0;
10050   u32 current_data_flag = 0;
10051   int current_data_offset = 0;
10052   int ret;
10053
10054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10055     {
10056       if (unformat (i, "del"))
10057         is_add = 0;
10058       else if (unformat (i, "del-chain"))
10059         {
10060           is_add = 0;
10061           del_chain = 1;
10062         }
10063       else if (unformat (i, "buckets %d", &nbuckets))
10064         ;
10065       else if (unformat (i, "memory_size %d", &memory_size))
10066         ;
10067       else if (unformat (i, "skip %d", &skip))
10068         ;
10069       else if (unformat (i, "match %d", &match))
10070         ;
10071       else if (unformat (i, "table %d", &table_index))
10072         ;
10073       else if (unformat (i, "mask %U", unformat_classify_mask,
10074                          &mask, &skip, &match))
10075         ;
10076       else if (unformat (i, "next-table %d", &next_table_index))
10077         ;
10078       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10079                          &miss_next_index))
10080         ;
10081       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10082                          &miss_next_index))
10083         ;
10084       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10085                          &miss_next_index))
10086         ;
10087       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10088         ;
10089       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10090         ;
10091       else
10092         break;
10093     }
10094
10095   if (is_add && mask == 0)
10096     {
10097       errmsg ("Mask required");
10098       return -99;
10099     }
10100
10101   if (is_add && skip == ~0)
10102     {
10103       errmsg ("skip count required");
10104       return -99;
10105     }
10106
10107   if (is_add && match == ~0)
10108     {
10109       errmsg ("match count required");
10110       return -99;
10111     }
10112
10113   if (!is_add && table_index == ~0)
10114     {
10115       errmsg ("table index required for delete");
10116       return -99;
10117     }
10118
10119   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10120
10121   mp->is_add = is_add;
10122   mp->del_chain = del_chain;
10123   mp->table_index = ntohl (table_index);
10124   mp->nbuckets = ntohl (nbuckets);
10125   mp->memory_size = ntohl (memory_size);
10126   mp->skip_n_vectors = ntohl (skip);
10127   mp->match_n_vectors = ntohl (match);
10128   mp->next_table_index = ntohl (next_table_index);
10129   mp->miss_next_index = ntohl (miss_next_index);
10130   mp->current_data_flag = ntohl (current_data_flag);
10131   mp->current_data_offset = ntohl (current_data_offset);
10132   mp->mask_len = ntohl (vec_len (mask));
10133   clib_memcpy (mp->mask, mask, vec_len (mask));
10134
10135   vec_free (mask);
10136
10137   S (mp);
10138   W (ret);
10139   return ret;
10140 }
10141
10142 #if VPP_API_TEST_BUILTIN == 0
10143 uword
10144 unformat_l4_match (unformat_input_t * input, va_list * args)
10145 {
10146   u8 **matchp = va_arg (*args, u8 **);
10147
10148   u8 *proto_header = 0;
10149   int src_port = 0;
10150   int dst_port = 0;
10151
10152   tcpudp_header_t h;
10153
10154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10155     {
10156       if (unformat (input, "src_port %d", &src_port))
10157         ;
10158       else if (unformat (input, "dst_port %d", &dst_port))
10159         ;
10160       else
10161         return 0;
10162     }
10163
10164   h.src_port = clib_host_to_net_u16 (src_port);
10165   h.dst_port = clib_host_to_net_u16 (dst_port);
10166   vec_validate (proto_header, sizeof (h) - 1);
10167   memcpy (proto_header, &h, sizeof (h));
10168
10169   *matchp = proto_header;
10170
10171   return 1;
10172 }
10173
10174 uword
10175 unformat_ip4_match (unformat_input_t * input, va_list * args)
10176 {
10177   u8 **matchp = va_arg (*args, u8 **);
10178   u8 *match = 0;
10179   ip4_header_t *ip;
10180   int version = 0;
10181   u32 version_val;
10182   int hdr_length = 0;
10183   u32 hdr_length_val;
10184   int src = 0, dst = 0;
10185   ip4_address_t src_val, dst_val;
10186   int proto = 0;
10187   u32 proto_val;
10188   int tos = 0;
10189   u32 tos_val;
10190   int length = 0;
10191   u32 length_val;
10192   int fragment_id = 0;
10193   u32 fragment_id_val;
10194   int ttl = 0;
10195   int ttl_val;
10196   int checksum = 0;
10197   u32 checksum_val;
10198
10199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10200     {
10201       if (unformat (input, "version %d", &version_val))
10202         version = 1;
10203       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10204         hdr_length = 1;
10205       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10206         src = 1;
10207       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10208         dst = 1;
10209       else if (unformat (input, "proto %d", &proto_val))
10210         proto = 1;
10211       else if (unformat (input, "tos %d", &tos_val))
10212         tos = 1;
10213       else if (unformat (input, "length %d", &length_val))
10214         length = 1;
10215       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10216         fragment_id = 1;
10217       else if (unformat (input, "ttl %d", &ttl_val))
10218         ttl = 1;
10219       else if (unformat (input, "checksum %d", &checksum_val))
10220         checksum = 1;
10221       else
10222         break;
10223     }
10224
10225   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10226       + ttl + checksum == 0)
10227     return 0;
10228
10229   /*
10230    * Aligned because we use the real comparison functions
10231    */
10232   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10233
10234   ip = (ip4_header_t *) match;
10235
10236   /* These are realistically matched in practice */
10237   if (src)
10238     ip->src_address.as_u32 = src_val.as_u32;
10239
10240   if (dst)
10241     ip->dst_address.as_u32 = dst_val.as_u32;
10242
10243   if (proto)
10244     ip->protocol = proto_val;
10245
10246
10247   /* These are not, but they're included for completeness */
10248   if (version)
10249     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10250
10251   if (hdr_length)
10252     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10253
10254   if (tos)
10255     ip->tos = tos_val;
10256
10257   if (length)
10258     ip->length = clib_host_to_net_u16 (length_val);
10259
10260   if (ttl)
10261     ip->ttl = ttl_val;
10262
10263   if (checksum)
10264     ip->checksum = clib_host_to_net_u16 (checksum_val);
10265
10266   *matchp = match;
10267   return 1;
10268 }
10269
10270 uword
10271 unformat_ip6_match (unformat_input_t * input, va_list * args)
10272 {
10273   u8 **matchp = va_arg (*args, u8 **);
10274   u8 *match = 0;
10275   ip6_header_t *ip;
10276   int version = 0;
10277   u32 version_val;
10278   u8 traffic_class = 0;
10279   u32 traffic_class_val = 0;
10280   u8 flow_label = 0;
10281   u8 flow_label_val;
10282   int src = 0, dst = 0;
10283   ip6_address_t src_val, dst_val;
10284   int proto = 0;
10285   u32 proto_val;
10286   int payload_length = 0;
10287   u32 payload_length_val;
10288   int hop_limit = 0;
10289   int hop_limit_val;
10290   u32 ip_version_traffic_class_and_flow_label;
10291
10292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10293     {
10294       if (unformat (input, "version %d", &version_val))
10295         version = 1;
10296       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10297         traffic_class = 1;
10298       else if (unformat (input, "flow_label %d", &flow_label_val))
10299         flow_label = 1;
10300       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10301         src = 1;
10302       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10303         dst = 1;
10304       else if (unformat (input, "proto %d", &proto_val))
10305         proto = 1;
10306       else if (unformat (input, "payload_length %d", &payload_length_val))
10307         payload_length = 1;
10308       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10309         hop_limit = 1;
10310       else
10311         break;
10312     }
10313
10314   if (version + traffic_class + flow_label + src + dst + proto +
10315       payload_length + hop_limit == 0)
10316     return 0;
10317
10318   /*
10319    * Aligned because we use the real comparison functions
10320    */
10321   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10322
10323   ip = (ip6_header_t *) match;
10324
10325   if (src)
10326     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10327
10328   if (dst)
10329     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10330
10331   if (proto)
10332     ip->protocol = proto_val;
10333
10334   ip_version_traffic_class_and_flow_label = 0;
10335
10336   if (version)
10337     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10338
10339   if (traffic_class)
10340     ip_version_traffic_class_and_flow_label |=
10341       (traffic_class_val & 0xFF) << 20;
10342
10343   if (flow_label)
10344     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10345
10346   ip->ip_version_traffic_class_and_flow_label =
10347     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10348
10349   if (payload_length)
10350     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10351
10352   if (hop_limit)
10353     ip->hop_limit = hop_limit_val;
10354
10355   *matchp = match;
10356   return 1;
10357 }
10358
10359 uword
10360 unformat_l3_match (unformat_input_t * input, va_list * args)
10361 {
10362   u8 **matchp = va_arg (*args, u8 **);
10363
10364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10365     {
10366       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10367         return 1;
10368       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10369         return 1;
10370       else
10371         break;
10372     }
10373   return 0;
10374 }
10375
10376 uword
10377 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10378 {
10379   u8 *tagp = va_arg (*args, u8 *);
10380   u32 tag;
10381
10382   if (unformat (input, "%d", &tag))
10383     {
10384       tagp[0] = (tag >> 8) & 0x0F;
10385       tagp[1] = tag & 0xFF;
10386       return 1;
10387     }
10388
10389   return 0;
10390 }
10391
10392 uword
10393 unformat_l2_match (unformat_input_t * input, va_list * args)
10394 {
10395   u8 **matchp = va_arg (*args, u8 **);
10396   u8 *match = 0;
10397   u8 src = 0;
10398   u8 src_val[6];
10399   u8 dst = 0;
10400   u8 dst_val[6];
10401   u8 proto = 0;
10402   u16 proto_val;
10403   u8 tag1 = 0;
10404   u8 tag1_val[2];
10405   u8 tag2 = 0;
10406   u8 tag2_val[2];
10407   int len = 14;
10408   u8 ignore_tag1 = 0;
10409   u8 ignore_tag2 = 0;
10410   u8 cos1 = 0;
10411   u8 cos2 = 0;
10412   u32 cos1_val = 0;
10413   u32 cos2_val = 0;
10414
10415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10416     {
10417       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10418         src = 1;
10419       else
10420         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10421         dst = 1;
10422       else if (unformat (input, "proto %U",
10423                          unformat_ethernet_type_host_byte_order, &proto_val))
10424         proto = 1;
10425       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10426         tag1 = 1;
10427       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10428         tag2 = 1;
10429       else if (unformat (input, "ignore-tag1"))
10430         ignore_tag1 = 1;
10431       else if (unformat (input, "ignore-tag2"))
10432         ignore_tag2 = 1;
10433       else if (unformat (input, "cos1 %d", &cos1_val))
10434         cos1 = 1;
10435       else if (unformat (input, "cos2 %d", &cos2_val))
10436         cos2 = 1;
10437       else
10438         break;
10439     }
10440   if ((src + dst + proto + tag1 + tag2 +
10441        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10442     return 0;
10443
10444   if (tag1 || ignore_tag1 || cos1)
10445     len = 18;
10446   if (tag2 || ignore_tag2 || cos2)
10447     len = 22;
10448
10449   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10450
10451   if (dst)
10452     clib_memcpy (match, dst_val, 6);
10453
10454   if (src)
10455     clib_memcpy (match + 6, src_val, 6);
10456
10457   if (tag2)
10458     {
10459       /* inner vlan tag */
10460       match[19] = tag2_val[1];
10461       match[18] = tag2_val[0];
10462       if (cos2)
10463         match[18] |= (cos2_val & 0x7) << 5;
10464       if (proto)
10465         {
10466           match[21] = proto_val & 0xff;
10467           match[20] = proto_val >> 8;
10468         }
10469       if (tag1)
10470         {
10471           match[15] = tag1_val[1];
10472           match[14] = tag1_val[0];
10473         }
10474       if (cos1)
10475         match[14] |= (cos1_val & 0x7) << 5;
10476       *matchp = match;
10477       return 1;
10478     }
10479   if (tag1)
10480     {
10481       match[15] = tag1_val[1];
10482       match[14] = tag1_val[0];
10483       if (proto)
10484         {
10485           match[17] = proto_val & 0xff;
10486           match[16] = proto_val >> 8;
10487         }
10488       if (cos1)
10489         match[14] |= (cos1_val & 0x7) << 5;
10490
10491       *matchp = match;
10492       return 1;
10493     }
10494   if (cos2)
10495     match[18] |= (cos2_val & 0x7) << 5;
10496   if (cos1)
10497     match[14] |= (cos1_val & 0x7) << 5;
10498   if (proto)
10499     {
10500       match[13] = proto_val & 0xff;
10501       match[12] = proto_val >> 8;
10502     }
10503
10504   *matchp = match;
10505   return 1;
10506 }
10507
10508 uword
10509 unformat_qos_source (unformat_input_t * input, va_list * args)
10510 {
10511   int *qs = va_arg (*args, int *);
10512
10513   if (unformat (input, "ip"))
10514     *qs = QOS_SOURCE_IP;
10515   else if (unformat (input, "mpls"))
10516     *qs = QOS_SOURCE_MPLS;
10517   else if (unformat (input, "ext"))
10518     *qs = QOS_SOURCE_EXT;
10519   else if (unformat (input, "vlan"))
10520     *qs = QOS_SOURCE_VLAN;
10521   else
10522     return 0;
10523
10524   return 1;
10525 }
10526 #endif
10527
10528 uword
10529 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10530 {
10531   u8 **matchp = va_arg (*args, u8 **);
10532   u32 skip_n_vectors = va_arg (*args, u32);
10533   u32 match_n_vectors = va_arg (*args, u32);
10534
10535   u8 *match = 0;
10536   u8 *l2 = 0;
10537   u8 *l3 = 0;
10538   u8 *l4 = 0;
10539
10540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (input, "hex %U", unformat_hex_string, &match))
10543         ;
10544       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10545         ;
10546       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10547         ;
10548       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10549         ;
10550       else
10551         break;
10552     }
10553
10554   if (l4 && !l3)
10555     {
10556       vec_free (match);
10557       vec_free (l2);
10558       vec_free (l4);
10559       return 0;
10560     }
10561
10562   if (match || l2 || l3 || l4)
10563     {
10564       if (l2 || l3 || l4)
10565         {
10566           /* "Win a free Ethernet header in every packet" */
10567           if (l2 == 0)
10568             vec_validate_aligned (l2, 13, sizeof (u32x4));
10569           match = l2;
10570           if (vec_len (l3))
10571             {
10572               vec_append_aligned (match, l3, sizeof (u32x4));
10573               vec_free (l3);
10574             }
10575           if (vec_len (l4))
10576             {
10577               vec_append_aligned (match, l4, sizeof (u32x4));
10578               vec_free (l4);
10579             }
10580         }
10581
10582       /* Make sure the vector is big enough even if key is all 0's */
10583       vec_validate_aligned
10584         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10585          sizeof (u32x4));
10586
10587       /* Set size, include skipped vectors */
10588       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10589
10590       *matchp = match;
10591
10592       return 1;
10593     }
10594
10595   return 0;
10596 }
10597
10598 static int
10599 api_classify_add_del_session (vat_main_t * vam)
10600 {
10601   unformat_input_t *i = vam->input;
10602   vl_api_classify_add_del_session_t *mp;
10603   int is_add = 1;
10604   u32 table_index = ~0;
10605   u32 hit_next_index = ~0;
10606   u32 opaque_index = ~0;
10607   u8 *match = 0;
10608   i32 advance = 0;
10609   u32 skip_n_vectors = 0;
10610   u32 match_n_vectors = 0;
10611   u32 action = 0;
10612   u32 metadata = 0;
10613   int ret;
10614
10615   /*
10616    * Warning: you have to supply skip_n and match_n
10617    * because the API client cant simply look at the classify
10618    * table object.
10619    */
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "del"))
10624         is_add = 0;
10625       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10626                          &hit_next_index))
10627         ;
10628       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10629                          &hit_next_index))
10630         ;
10631       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10632                          &hit_next_index))
10633         ;
10634       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10635         ;
10636       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10637         ;
10638       else if (unformat (i, "opaque-index %d", &opaque_index))
10639         ;
10640       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10641         ;
10642       else if (unformat (i, "match_n %d", &match_n_vectors))
10643         ;
10644       else if (unformat (i, "match %U", api_unformat_classify_match,
10645                          &match, skip_n_vectors, match_n_vectors))
10646         ;
10647       else if (unformat (i, "advance %d", &advance))
10648         ;
10649       else if (unformat (i, "table-index %d", &table_index))
10650         ;
10651       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10652         action = 1;
10653       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10654         action = 2;
10655       else if (unformat (i, "action %d", &action))
10656         ;
10657       else if (unformat (i, "metadata %d", &metadata))
10658         ;
10659       else
10660         break;
10661     }
10662
10663   if (table_index == ~0)
10664     {
10665       errmsg ("Table index required");
10666       return -99;
10667     }
10668
10669   if (is_add && match == 0)
10670     {
10671       errmsg ("Match value required");
10672       return -99;
10673     }
10674
10675   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10676
10677   mp->is_add = is_add;
10678   mp->table_index = ntohl (table_index);
10679   mp->hit_next_index = ntohl (hit_next_index);
10680   mp->opaque_index = ntohl (opaque_index);
10681   mp->advance = ntohl (advance);
10682   mp->action = action;
10683   mp->metadata = ntohl (metadata);
10684   mp->match_len = ntohl (vec_len (match));
10685   clib_memcpy (mp->match, match, vec_len (match));
10686   vec_free (match);
10687
10688   S (mp);
10689   W (ret);
10690   return ret;
10691 }
10692
10693 static int
10694 api_classify_set_interface_ip_table (vat_main_t * vam)
10695 {
10696   unformat_input_t *i = vam->input;
10697   vl_api_classify_set_interface_ip_table_t *mp;
10698   u32 sw_if_index;
10699   int sw_if_index_set;
10700   u32 table_index = ~0;
10701   u8 is_ipv6 = 0;
10702   int ret;
10703
10704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "table %d", &table_index))
10711         ;
10712       else
10713         {
10714           clib_warning ("parse error '%U'", format_unformat_error, i);
10715           return -99;
10716         }
10717     }
10718
10719   if (sw_if_index_set == 0)
10720     {
10721       errmsg ("missing interface name or sw_if_index");
10722       return -99;
10723     }
10724
10725
10726   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10727
10728   mp->sw_if_index = ntohl (sw_if_index);
10729   mp->table_index = ntohl (table_index);
10730   mp->is_ipv6 = is_ipv6;
10731
10732   S (mp);
10733   W (ret);
10734   return ret;
10735 }
10736
10737 static int
10738 api_classify_set_interface_l2_tables (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_classify_set_interface_l2_tables_t *mp;
10742   u32 sw_if_index;
10743   int sw_if_index_set;
10744   u32 ip4_table_index = ~0;
10745   u32 ip6_table_index = ~0;
10746   u32 other_table_index = ~0;
10747   u32 is_input = 1;
10748   int ret;
10749
10750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10751     {
10752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10755         sw_if_index_set = 1;
10756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10757         ;
10758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10759         ;
10760       else if (unformat (i, "other-table %d", &other_table_index))
10761         ;
10762       else if (unformat (i, "is-input %d", &is_input))
10763         ;
10764       else
10765         {
10766           clib_warning ("parse error '%U'", format_unformat_error, i);
10767           return -99;
10768         }
10769     }
10770
10771   if (sw_if_index_set == 0)
10772     {
10773       errmsg ("missing interface name or sw_if_index");
10774       return -99;
10775     }
10776
10777
10778   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10779
10780   mp->sw_if_index = ntohl (sw_if_index);
10781   mp->ip4_table_index = ntohl (ip4_table_index);
10782   mp->ip6_table_index = ntohl (ip6_table_index);
10783   mp->other_table_index = ntohl (other_table_index);
10784   mp->is_input = (u8) is_input;
10785
10786   S (mp);
10787   W (ret);
10788   return ret;
10789 }
10790
10791 static int
10792 api_set_ipfix_exporter (vat_main_t * vam)
10793 {
10794   unformat_input_t *i = vam->input;
10795   vl_api_set_ipfix_exporter_t *mp;
10796   ip4_address_t collector_address;
10797   u8 collector_address_set = 0;
10798   u32 collector_port = ~0;
10799   ip4_address_t src_address;
10800   u8 src_address_set = 0;
10801   u32 vrf_id = ~0;
10802   u32 path_mtu = ~0;
10803   u32 template_interval = ~0;
10804   u8 udp_checksum = 0;
10805   int ret;
10806
10807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10808     {
10809       if (unformat (i, "collector_address %U", unformat_ip4_address,
10810                     &collector_address))
10811         collector_address_set = 1;
10812       else if (unformat (i, "collector_port %d", &collector_port))
10813         ;
10814       else if (unformat (i, "src_address %U", unformat_ip4_address,
10815                          &src_address))
10816         src_address_set = 1;
10817       else if (unformat (i, "vrf_id %d", &vrf_id))
10818         ;
10819       else if (unformat (i, "path_mtu %d", &path_mtu))
10820         ;
10821       else if (unformat (i, "template_interval %d", &template_interval))
10822         ;
10823       else if (unformat (i, "udp_checksum"))
10824         udp_checksum = 1;
10825       else
10826         break;
10827     }
10828
10829   if (collector_address_set == 0)
10830     {
10831       errmsg ("collector_address required");
10832       return -99;
10833     }
10834
10835   if (src_address_set == 0)
10836     {
10837       errmsg ("src_address required");
10838       return -99;
10839     }
10840
10841   M (SET_IPFIX_EXPORTER, mp);
10842
10843   memcpy (mp->collector_address.un.ip4, collector_address.data,
10844           sizeof (collector_address.data));
10845   mp->collector_port = htons ((u16) collector_port);
10846   memcpy (mp->src_address.un.ip4, src_address.data,
10847           sizeof (src_address.data));
10848   mp->vrf_id = htonl (vrf_id);
10849   mp->path_mtu = htonl (path_mtu);
10850   mp->template_interval = htonl (template_interval);
10851   mp->udp_checksum = udp_checksum;
10852
10853   S (mp);
10854   W (ret);
10855   return ret;
10856 }
10857
10858 static int
10859 api_set_ipfix_classify_stream (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_set_ipfix_classify_stream_t *mp;
10863   u32 domain_id = 0;
10864   u32 src_port = UDP_DST_PORT_ipfix;
10865   int ret;
10866
10867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (i, "domain %d", &domain_id))
10870         ;
10871       else if (unformat (i, "src_port %d", &src_port))
10872         ;
10873       else
10874         {
10875           errmsg ("unknown input `%U'", format_unformat_error, i);
10876           return -99;
10877         }
10878     }
10879
10880   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10881
10882   mp->domain_id = htonl (domain_id);
10883   mp->src_port = htons ((u16) src_port);
10884
10885   S (mp);
10886   W (ret);
10887   return ret;
10888 }
10889
10890 static int
10891 api_ipfix_classify_table_add_del (vat_main_t * vam)
10892 {
10893   unformat_input_t *i = vam->input;
10894   vl_api_ipfix_classify_table_add_del_t *mp;
10895   int is_add = -1;
10896   u32 classify_table_index = ~0;
10897   u8 ip_version = 0;
10898   u8 transport_protocol = 255;
10899   int ret;
10900
10901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902     {
10903       if (unformat (i, "add"))
10904         is_add = 1;
10905       else if (unformat (i, "del"))
10906         is_add = 0;
10907       else if (unformat (i, "table %d", &classify_table_index))
10908         ;
10909       else if (unformat (i, "ip4"))
10910         ip_version = 4;
10911       else if (unformat (i, "ip6"))
10912         ip_version = 6;
10913       else if (unformat (i, "tcp"))
10914         transport_protocol = 6;
10915       else if (unformat (i, "udp"))
10916         transport_protocol = 17;
10917       else
10918         {
10919           errmsg ("unknown input `%U'", format_unformat_error, i);
10920           return -99;
10921         }
10922     }
10923
10924   if (is_add == -1)
10925     {
10926       errmsg ("expecting: add|del");
10927       return -99;
10928     }
10929   if (classify_table_index == ~0)
10930     {
10931       errmsg ("classifier table not specified");
10932       return -99;
10933     }
10934   if (ip_version == 0)
10935     {
10936       errmsg ("IP version not specified");
10937       return -99;
10938     }
10939
10940   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10941
10942   mp->is_add = is_add;
10943   mp->table_id = htonl (classify_table_index);
10944   mp->ip_version = ip_version;
10945   mp->transport_protocol = transport_protocol;
10946
10947   S (mp);
10948   W (ret);
10949   return ret;
10950 }
10951
10952 static int
10953 api_get_node_index (vat_main_t * vam)
10954 {
10955   unformat_input_t *i = vam->input;
10956   vl_api_get_node_index_t *mp;
10957   u8 *name = 0;
10958   int ret;
10959
10960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (i, "node %s", &name))
10963         ;
10964       else
10965         break;
10966     }
10967   if (name == 0)
10968     {
10969       errmsg ("node name required");
10970       return -99;
10971     }
10972   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10973     {
10974       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10975       return -99;
10976     }
10977
10978   M (GET_NODE_INDEX, mp);
10979   clib_memcpy (mp->node_name, name, vec_len (name));
10980   vec_free (name);
10981
10982   S (mp);
10983   W (ret);
10984   return ret;
10985 }
10986
10987 static int
10988 api_get_next_index (vat_main_t * vam)
10989 {
10990   unformat_input_t *i = vam->input;
10991   vl_api_get_next_index_t *mp;
10992   u8 *node_name = 0, *next_node_name = 0;
10993   int ret;
10994
10995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10996     {
10997       if (unformat (i, "node-name %s", &node_name))
10998         ;
10999       else if (unformat (i, "next-node-name %s", &next_node_name))
11000         break;
11001     }
11002
11003   if (node_name == 0)
11004     {
11005       errmsg ("node name required");
11006       return -99;
11007     }
11008   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11009     {
11010       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11011       return -99;
11012     }
11013
11014   if (next_node_name == 0)
11015     {
11016       errmsg ("next node name required");
11017       return -99;
11018     }
11019   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11020     {
11021       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11022       return -99;
11023     }
11024
11025   M (GET_NEXT_INDEX, mp);
11026   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11027   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11028   vec_free (node_name);
11029   vec_free (next_node_name);
11030
11031   S (mp);
11032   W (ret);
11033   return ret;
11034 }
11035
11036 static int
11037 api_add_node_next (vat_main_t * vam)
11038 {
11039   unformat_input_t *i = vam->input;
11040   vl_api_add_node_next_t *mp;
11041   u8 *name = 0;
11042   u8 *next = 0;
11043   int ret;
11044
11045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11046     {
11047       if (unformat (i, "node %s", &name))
11048         ;
11049       else if (unformat (i, "next %s", &next))
11050         ;
11051       else
11052         break;
11053     }
11054   if (name == 0)
11055     {
11056       errmsg ("node name required");
11057       return -99;
11058     }
11059   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11060     {
11061       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11062       return -99;
11063     }
11064   if (next == 0)
11065     {
11066       errmsg ("next node required");
11067       return -99;
11068     }
11069   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11070     {
11071       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11072       return -99;
11073     }
11074
11075   M (ADD_NODE_NEXT, mp);
11076   clib_memcpy (mp->node_name, name, vec_len (name));
11077   clib_memcpy (mp->next_name, next, vec_len (next));
11078   vec_free (name);
11079   vec_free (next);
11080
11081   S (mp);
11082   W (ret);
11083   return ret;
11084 }
11085
11086 static int
11087 api_l2tpv3_create_tunnel (vat_main_t * vam)
11088 {
11089   unformat_input_t *i = vam->input;
11090   ip6_address_t client_address, our_address;
11091   int client_address_set = 0;
11092   int our_address_set = 0;
11093   u32 local_session_id = 0;
11094   u32 remote_session_id = 0;
11095   u64 local_cookie = 0;
11096   u64 remote_cookie = 0;
11097   u8 l2_sublayer_present = 0;
11098   vl_api_l2tpv3_create_tunnel_t *mp;
11099   int ret;
11100
11101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (i, "client_address %U", unformat_ip6_address,
11104                     &client_address))
11105         client_address_set = 1;
11106       else if (unformat (i, "our_address %U", unformat_ip6_address,
11107                          &our_address))
11108         our_address_set = 1;
11109       else if (unformat (i, "local_session_id %d", &local_session_id))
11110         ;
11111       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11112         ;
11113       else if (unformat (i, "local_cookie %lld", &local_cookie))
11114         ;
11115       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11116         ;
11117       else if (unformat (i, "l2-sublayer-present"))
11118         l2_sublayer_present = 1;
11119       else
11120         break;
11121     }
11122
11123   if (client_address_set == 0)
11124     {
11125       errmsg ("client_address required");
11126       return -99;
11127     }
11128
11129   if (our_address_set == 0)
11130     {
11131       errmsg ("our_address required");
11132       return -99;
11133     }
11134
11135   M (L2TPV3_CREATE_TUNNEL, mp);
11136
11137   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11138                sizeof (ip6_address_t));
11139
11140   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11141                sizeof (ip6_address_t));
11142
11143   mp->local_session_id = ntohl (local_session_id);
11144   mp->remote_session_id = ntohl (remote_session_id);
11145   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11146   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11147   mp->l2_sublayer_present = l2_sublayer_present;
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   u32 sw_if_index;
11159   u8 sw_if_index_set = 0;
11160   u64 new_local_cookie = 0;
11161   u64 new_remote_cookie = 0;
11162   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11163   int ret;
11164
11165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11166     {
11167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11170         sw_if_index_set = 1;
11171       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11172         ;
11173       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11174         ;
11175       else
11176         break;
11177     }
11178
11179   if (sw_if_index_set == 0)
11180     {
11181       errmsg ("missing interface name or sw_if_index");
11182       return -99;
11183     }
11184
11185   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11186
11187   mp->sw_if_index = ntohl (sw_if_index);
11188   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11189   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11190
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 static int
11197 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11198 {
11199   unformat_input_t *i = vam->input;
11200   vl_api_l2tpv3_interface_enable_disable_t *mp;
11201   u32 sw_if_index;
11202   u8 sw_if_index_set = 0;
11203   u8 enable_disable = 1;
11204   int ret;
11205
11206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11209         sw_if_index_set = 1;
11210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11211         sw_if_index_set = 1;
11212       else if (unformat (i, "enable"))
11213         enable_disable = 1;
11214       else if (unformat (i, "disable"))
11215         enable_disable = 0;
11216       else
11217         break;
11218     }
11219
11220   if (sw_if_index_set == 0)
11221     {
11222       errmsg ("missing interface name or sw_if_index");
11223       return -99;
11224     }
11225
11226   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11227
11228   mp->sw_if_index = ntohl (sw_if_index);
11229   mp->enable_disable = enable_disable;
11230
11231   S (mp);
11232   W (ret);
11233   return ret;
11234 }
11235
11236 static int
11237 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11238 {
11239   unformat_input_t *i = vam->input;
11240   vl_api_l2tpv3_set_lookup_key_t *mp;
11241   u8 key = ~0;
11242   int ret;
11243
11244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11245     {
11246       if (unformat (i, "lookup_v6_src"))
11247         key = L2T_LOOKUP_SRC_ADDRESS;
11248       else if (unformat (i, "lookup_v6_dst"))
11249         key = L2T_LOOKUP_DST_ADDRESS;
11250       else if (unformat (i, "lookup_session_id"))
11251         key = L2T_LOOKUP_SESSION_ID;
11252       else
11253         break;
11254     }
11255
11256   if (key == (u8) ~ 0)
11257     {
11258       errmsg ("l2tp session lookup key unset");
11259       return -99;
11260     }
11261
11262   M (L2TPV3_SET_LOOKUP_KEY, mp);
11263
11264   mp->key = key;
11265
11266   S (mp);
11267   W (ret);
11268   return ret;
11269 }
11270
11271 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11272   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11273 {
11274   vat_main_t *vam = &vat_main;
11275
11276   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11277          format_ip6_address, mp->our_address,
11278          format_ip6_address, mp->client_address,
11279          clib_net_to_host_u32 (mp->sw_if_index));
11280
11281   print (vam->ofp,
11282          "   local cookies %016llx %016llx remote cookie %016llx",
11283          clib_net_to_host_u64 (mp->local_cookie[0]),
11284          clib_net_to_host_u64 (mp->local_cookie[1]),
11285          clib_net_to_host_u64 (mp->remote_cookie));
11286
11287   print (vam->ofp, "   local session-id %d remote session-id %d",
11288          clib_net_to_host_u32 (mp->local_session_id),
11289          clib_net_to_host_u32 (mp->remote_session_id));
11290
11291   print (vam->ofp, "   l2 specific sublayer %s\n",
11292          mp->l2_sublayer_present ? "preset" : "absent");
11293
11294 }
11295
11296 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11297   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11298 {
11299   vat_main_t *vam = &vat_main;
11300   vat_json_node_t *node = NULL;
11301   struct in6_addr addr;
11302
11303   if (VAT_JSON_ARRAY != vam->json_tree.type)
11304     {
11305       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11306       vat_json_init_array (&vam->json_tree);
11307     }
11308   node = vat_json_array_add (&vam->json_tree);
11309
11310   vat_json_init_object (node);
11311
11312   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11313   vat_json_object_add_ip6 (node, "our_address", addr);
11314   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11315   vat_json_object_add_ip6 (node, "client_address", addr);
11316
11317   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11318   vat_json_init_array (lc);
11319   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11320   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11321   vat_json_object_add_uint (node, "remote_cookie",
11322                             clib_net_to_host_u64 (mp->remote_cookie));
11323
11324   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11325   vat_json_object_add_uint (node, "local_session_id",
11326                             clib_net_to_host_u32 (mp->local_session_id));
11327   vat_json_object_add_uint (node, "remote_session_id",
11328                             clib_net_to_host_u32 (mp->remote_session_id));
11329   vat_json_object_add_string_copy (node, "l2_sublayer",
11330                                    mp->l2_sublayer_present ? (u8 *) "present"
11331                                    : (u8 *) "absent");
11332 }
11333
11334 static int
11335 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11336 {
11337   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11338   vl_api_control_ping_t *mp_ping;
11339   int ret;
11340
11341   /* Get list of l2tpv3-tunnel interfaces */
11342   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11343   S (mp);
11344
11345   /* Use a control ping for synchronization */
11346   MPING (CONTROL_PING, mp_ping);
11347   S (mp_ping);
11348
11349   W (ret);
11350   return ret;
11351 }
11352
11353
11354 static void vl_api_sw_interface_tap_v2_details_t_handler
11355   (vl_api_sw_interface_tap_v2_details_t * mp)
11356 {
11357   vat_main_t *vam = &vat_main;
11358
11359   u8 *ip4 =
11360     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11361             mp->host_ip4_prefix.len);
11362   u8 *ip6 =
11363     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11364             mp->host_ip6_prefix.len);
11365
11366   print (vam->ofp,
11367          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11368          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11369          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11370          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11371          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11372
11373   vec_free (ip4);
11374   vec_free (ip6);
11375 }
11376
11377 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11378   (vl_api_sw_interface_tap_v2_details_t * mp)
11379 {
11380   vat_main_t *vam = &vat_main;
11381   vat_json_node_t *node = NULL;
11382
11383   if (VAT_JSON_ARRAY != vam->json_tree.type)
11384     {
11385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11386       vat_json_init_array (&vam->json_tree);
11387     }
11388   node = vat_json_array_add (&vam->json_tree);
11389
11390   vat_json_init_object (node);
11391   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11393   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11394   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11395   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11396   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11397   vat_json_object_add_string_copy (node, "host_mac_addr",
11398                                    format (0, "%U", format_ethernet_address,
11399                                            &mp->host_mac_addr));
11400   vat_json_object_add_string_copy (node, "host_namespace",
11401                                    mp->host_namespace);
11402   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11403   vat_json_object_add_string_copy (node, "host_ip4_addr",
11404                                    format (0, "%U/%d", format_ip4_address,
11405                                            mp->host_ip4_prefix.address,
11406                                            mp->host_ip4_prefix.len));
11407   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11408                                    format (0, "%U/%d", format_ip6_address,
11409                                            mp->host_ip6_prefix.address,
11410                                            mp->host_ip6_prefix.len));
11411
11412 }
11413
11414 static int
11415 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11416 {
11417   vl_api_sw_interface_tap_v2_dump_t *mp;
11418   vl_api_control_ping_t *mp_ping;
11419   int ret;
11420
11421   print (vam->ofp,
11422          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11423          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11424          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11425          "host_ip6_addr");
11426
11427   /* Get list of tap interfaces */
11428   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11429   S (mp);
11430
11431   /* Use a control ping for synchronization */
11432   MPING (CONTROL_PING, mp_ping);
11433   S (mp_ping);
11434
11435   W (ret);
11436   return ret;
11437 }
11438
11439 static void vl_api_sw_interface_virtio_pci_details_t_handler
11440   (vl_api_sw_interface_virtio_pci_details_t * mp)
11441 {
11442   vat_main_t *vam = &vat_main;
11443
11444   typedef union
11445   {
11446     struct
11447     {
11448       u16 domain;
11449       u8 bus;
11450       u8 slot:5;
11451       u8 function:3;
11452     };
11453     u32 as_u32;
11454   } pci_addr_t;
11455   pci_addr_t addr;
11456
11457   addr.domain = ntohs (mp->pci_addr.domain);
11458   addr.bus = mp->pci_addr.bus;
11459   addr.slot = mp->pci_addr.slot;
11460   addr.function = mp->pci_addr.function;
11461
11462   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11463                          addr.slot, addr.function);
11464
11465   print (vam->ofp,
11466          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11467          pci_addr, ntohl (mp->sw_if_index),
11468          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11469          format_ethernet_address, mp->mac_addr,
11470          clib_net_to_host_u64 (mp->features));
11471   vec_free (pci_addr);
11472 }
11473
11474 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11475   (vl_api_sw_interface_virtio_pci_details_t * mp)
11476 {
11477   vat_main_t *vam = &vat_main;
11478   vat_json_node_t *node = NULL;
11479   vlib_pci_addr_t pci_addr;
11480
11481   if (VAT_JSON_ARRAY != vam->json_tree.type)
11482     {
11483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11484       vat_json_init_array (&vam->json_tree);
11485     }
11486   node = vat_json_array_add (&vam->json_tree);
11487
11488   pci_addr.domain = ntohs (mp->pci_addr.domain);
11489   pci_addr.bus = mp->pci_addr.bus;
11490   pci_addr.slot = mp->pci_addr.slot;
11491   pci_addr.function = mp->pci_addr.function;
11492
11493   vat_json_init_object (node);
11494   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11495   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11496   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11497   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11498   vat_json_object_add_uint (node, "features",
11499                             clib_net_to_host_u64 (mp->features));
11500   vat_json_object_add_string_copy (node, "mac_addr",
11501                                    format (0, "%U", format_ethernet_address,
11502                                            &mp->mac_addr));
11503 }
11504
11505 static int
11506 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11507 {
11508   vl_api_sw_interface_virtio_pci_dump_t *mp;
11509   vl_api_control_ping_t *mp_ping;
11510   int ret;
11511
11512   print (vam->ofp,
11513          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11514          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11515          "mac_addr", "features");
11516
11517   /* Get list of tap interfaces */
11518   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11519   S (mp);
11520
11521   /* Use a control ping for synchronization */
11522   MPING (CONTROL_PING, mp_ping);
11523   S (mp_ping);
11524
11525   W (ret);
11526   return ret;
11527 }
11528
11529 static int
11530 api_vxlan_offload_rx (vat_main_t * vam)
11531 {
11532   unformat_input_t *line_input = vam->input;
11533   vl_api_vxlan_offload_rx_t *mp;
11534   u32 hw_if_index = ~0, rx_if_index = ~0;
11535   u8 is_add = 1;
11536   int ret;
11537
11538   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11539     {
11540       if (unformat (line_input, "del"))
11541         is_add = 0;
11542       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11543                          &hw_if_index))
11544         ;
11545       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11546         ;
11547       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11548                          &rx_if_index))
11549         ;
11550       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11551         ;
11552       else
11553         {
11554           errmsg ("parse error '%U'", format_unformat_error, line_input);
11555           return -99;
11556         }
11557     }
11558
11559   if (hw_if_index == ~0)
11560     {
11561       errmsg ("no hw interface");
11562       return -99;
11563     }
11564
11565   if (rx_if_index == ~0)
11566     {
11567       errmsg ("no rx tunnel");
11568       return -99;
11569     }
11570
11571   M (VXLAN_OFFLOAD_RX, mp);
11572
11573   mp->hw_if_index = ntohl (hw_if_index);
11574   mp->sw_if_index = ntohl (rx_if_index);
11575   mp->enable = is_add;
11576
11577   S (mp);
11578   W (ret);
11579   return ret;
11580 }
11581
11582 static uword unformat_vxlan_decap_next
11583   (unformat_input_t * input, va_list * args)
11584 {
11585   u32 *result = va_arg (*args, u32 *);
11586   u32 tmp;
11587
11588   if (unformat (input, "l2"))
11589     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11590   else if (unformat (input, "%d", &tmp))
11591     *result = tmp;
11592   else
11593     return 0;
11594   return 1;
11595 }
11596
11597 static int
11598 api_vxlan_add_del_tunnel (vat_main_t * vam)
11599 {
11600   unformat_input_t *line_input = vam->input;
11601   vl_api_vxlan_add_del_tunnel_t *mp;
11602   ip46_address_t src, dst;
11603   u8 is_add = 1;
11604   u8 ipv4_set = 0, ipv6_set = 0;
11605   u8 src_set = 0;
11606   u8 dst_set = 0;
11607   u8 grp_set = 0;
11608   u32 instance = ~0;
11609   u32 mcast_sw_if_index = ~0;
11610   u32 encap_vrf_id = 0;
11611   u32 decap_next_index = ~0;
11612   u32 vni = 0;
11613   int ret;
11614
11615   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11616   clib_memset (&src, 0, sizeof src);
11617   clib_memset (&dst, 0, sizeof dst);
11618
11619   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11620     {
11621       if (unformat (line_input, "del"))
11622         is_add = 0;
11623       else if (unformat (line_input, "instance %d", &instance))
11624         ;
11625       else
11626         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11627         {
11628           ipv4_set = 1;
11629           src_set = 1;
11630         }
11631       else
11632         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11633         {
11634           ipv4_set = 1;
11635           dst_set = 1;
11636         }
11637       else
11638         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11639         {
11640           ipv6_set = 1;
11641           src_set = 1;
11642         }
11643       else
11644         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11645         {
11646           ipv6_set = 1;
11647           dst_set = 1;
11648         }
11649       else if (unformat (line_input, "group %U %U",
11650                          unformat_ip4_address, &dst.ip4,
11651                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11652         {
11653           grp_set = dst_set = 1;
11654           ipv4_set = 1;
11655         }
11656       else if (unformat (line_input, "group %U",
11657                          unformat_ip4_address, &dst.ip4))
11658         {
11659           grp_set = dst_set = 1;
11660           ipv4_set = 1;
11661         }
11662       else if (unformat (line_input, "group %U %U",
11663                          unformat_ip6_address, &dst.ip6,
11664                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11665         {
11666           grp_set = dst_set = 1;
11667           ipv6_set = 1;
11668         }
11669       else if (unformat (line_input, "group %U",
11670                          unformat_ip6_address, &dst.ip6))
11671         {
11672           grp_set = dst_set = 1;
11673           ipv6_set = 1;
11674         }
11675       else
11676         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11677         ;
11678       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11679         ;
11680       else if (unformat (line_input, "decap-next %U",
11681                          unformat_vxlan_decap_next, &decap_next_index))
11682         ;
11683       else if (unformat (line_input, "vni %d", &vni))
11684         ;
11685       else
11686         {
11687           errmsg ("parse error '%U'", format_unformat_error, line_input);
11688           return -99;
11689         }
11690     }
11691
11692   if (src_set == 0)
11693     {
11694       errmsg ("tunnel src address not specified");
11695       return -99;
11696     }
11697   if (dst_set == 0)
11698     {
11699       errmsg ("tunnel dst address not specified");
11700       return -99;
11701     }
11702
11703   if (grp_set && !ip46_address_is_multicast (&dst))
11704     {
11705       errmsg ("tunnel group address not multicast");
11706       return -99;
11707     }
11708   if (grp_set && mcast_sw_if_index == ~0)
11709     {
11710       errmsg ("tunnel nonexistent multicast device");
11711       return -99;
11712     }
11713   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11714     {
11715       errmsg ("tunnel dst address must be unicast");
11716       return -99;
11717     }
11718
11719
11720   if (ipv4_set && ipv6_set)
11721     {
11722       errmsg ("both IPv4 and IPv6 addresses specified");
11723       return -99;
11724     }
11725
11726   if ((vni == 0) || (vni >> 24))
11727     {
11728       errmsg ("vni not specified or out of range");
11729       return -99;
11730     }
11731
11732   M (VXLAN_ADD_DEL_TUNNEL, mp);
11733
11734   if (ipv6_set)
11735     {
11736       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11737       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11738     }
11739   else
11740     {
11741       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11742       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11743     }
11744   mp->src_address.af = ipv6_set;
11745   mp->dst_address.af = ipv6_set;
11746
11747   mp->instance = htonl (instance);
11748   mp->encap_vrf_id = ntohl (encap_vrf_id);
11749   mp->decap_next_index = ntohl (decap_next_index);
11750   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11751   mp->vni = ntohl (vni);
11752   mp->is_add = is_add;
11753
11754   S (mp);
11755   W (ret);
11756   return ret;
11757 }
11758
11759 static void vl_api_vxlan_tunnel_details_t_handler
11760   (vl_api_vxlan_tunnel_details_t * mp)
11761 {
11762   vat_main_t *vam = &vat_main;
11763   ip46_address_t src =
11764     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11765   ip46_address_t dst =
11766     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11767
11768   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11769          ntohl (mp->sw_if_index),
11770          ntohl (mp->instance),
11771          format_ip46_address, &src, IP46_TYPE_ANY,
11772          format_ip46_address, &dst, IP46_TYPE_ANY,
11773          ntohl (mp->encap_vrf_id),
11774          ntohl (mp->decap_next_index), ntohl (mp->vni),
11775          ntohl (mp->mcast_sw_if_index));
11776 }
11777
11778 static void vl_api_vxlan_tunnel_details_t_handler_json
11779   (vl_api_vxlan_tunnel_details_t * mp)
11780 {
11781   vat_main_t *vam = &vat_main;
11782   vat_json_node_t *node = NULL;
11783
11784   if (VAT_JSON_ARRAY != vam->json_tree.type)
11785     {
11786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11787       vat_json_init_array (&vam->json_tree);
11788     }
11789   node = vat_json_array_add (&vam->json_tree);
11790
11791   vat_json_init_object (node);
11792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11793
11794   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11795
11796   if (mp->src_address.af)
11797     {
11798       struct in6_addr ip6;
11799
11800       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11801       vat_json_object_add_ip6 (node, "src_address", ip6);
11802       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11803       vat_json_object_add_ip6 (node, "dst_address", ip6);
11804     }
11805   else
11806     {
11807       struct in_addr ip4;
11808
11809       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11810       vat_json_object_add_ip4 (node, "src_address", ip4);
11811       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11812       vat_json_object_add_ip4 (node, "dst_address", ip4);
11813     }
11814   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11815   vat_json_object_add_uint (node, "decap_next_index",
11816                             ntohl (mp->decap_next_index));
11817   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11818   vat_json_object_add_uint (node, "mcast_sw_if_index",
11819                             ntohl (mp->mcast_sw_if_index));
11820 }
11821
11822 static int
11823 api_vxlan_tunnel_dump (vat_main_t * vam)
11824 {
11825   unformat_input_t *i = vam->input;
11826   vl_api_vxlan_tunnel_dump_t *mp;
11827   vl_api_control_ping_t *mp_ping;
11828   u32 sw_if_index;
11829   u8 sw_if_index_set = 0;
11830   int ret;
11831
11832   /* Parse args required to build the message */
11833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11834     {
11835       if (unformat (i, "sw_if_index %d", &sw_if_index))
11836         sw_if_index_set = 1;
11837       else
11838         break;
11839     }
11840
11841   if (sw_if_index_set == 0)
11842     {
11843       sw_if_index = ~0;
11844     }
11845
11846   if (!vam->json_output)
11847     {
11848       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11849              "sw_if_index", "instance", "src_address", "dst_address",
11850              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11851     }
11852
11853   /* Get list of vxlan-tunnel interfaces */
11854   M (VXLAN_TUNNEL_DUMP, mp);
11855
11856   mp->sw_if_index = htonl (sw_if_index);
11857
11858   S (mp);
11859
11860   /* Use a control ping for synchronization */
11861   MPING (CONTROL_PING, mp_ping);
11862   S (mp_ping);
11863
11864   W (ret);
11865   return ret;
11866 }
11867
11868 static uword unformat_geneve_decap_next
11869   (unformat_input_t * input, va_list * args)
11870 {
11871   u32 *result = va_arg (*args, u32 *);
11872   u32 tmp;
11873
11874   if (unformat (input, "l2"))
11875     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11876   else if (unformat (input, "%d", &tmp))
11877     *result = tmp;
11878   else
11879     return 0;
11880   return 1;
11881 }
11882
11883 static int
11884 api_geneve_add_del_tunnel (vat_main_t * vam)
11885 {
11886   unformat_input_t *line_input = vam->input;
11887   vl_api_geneve_add_del_tunnel_t *mp;
11888   ip46_address_t src, dst;
11889   u8 is_add = 1;
11890   u8 ipv4_set = 0, ipv6_set = 0;
11891   u8 src_set = 0;
11892   u8 dst_set = 0;
11893   u8 grp_set = 0;
11894   u32 mcast_sw_if_index = ~0;
11895   u32 encap_vrf_id = 0;
11896   u32 decap_next_index = ~0;
11897   u32 vni = 0;
11898   int ret;
11899
11900   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11901   clib_memset (&src, 0, sizeof src);
11902   clib_memset (&dst, 0, sizeof dst);
11903
11904   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11905     {
11906       if (unformat (line_input, "del"))
11907         is_add = 0;
11908       else
11909         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11910         {
11911           ipv4_set = 1;
11912           src_set = 1;
11913         }
11914       else
11915         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11916         {
11917           ipv4_set = 1;
11918           dst_set = 1;
11919         }
11920       else
11921         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11922         {
11923           ipv6_set = 1;
11924           src_set = 1;
11925         }
11926       else
11927         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11928         {
11929           ipv6_set = 1;
11930           dst_set = 1;
11931         }
11932       else if (unformat (line_input, "group %U %U",
11933                          unformat_ip4_address, &dst.ip4,
11934                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11935         {
11936           grp_set = dst_set = 1;
11937           ipv4_set = 1;
11938         }
11939       else if (unformat (line_input, "group %U",
11940                          unformat_ip4_address, &dst.ip4))
11941         {
11942           grp_set = dst_set = 1;
11943           ipv4_set = 1;
11944         }
11945       else if (unformat (line_input, "group %U %U",
11946                          unformat_ip6_address, &dst.ip6,
11947                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11948         {
11949           grp_set = dst_set = 1;
11950           ipv6_set = 1;
11951         }
11952       else if (unformat (line_input, "group %U",
11953                          unformat_ip6_address, &dst.ip6))
11954         {
11955           grp_set = dst_set = 1;
11956           ipv6_set = 1;
11957         }
11958       else
11959         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11960         ;
11961       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11962         ;
11963       else if (unformat (line_input, "decap-next %U",
11964                          unformat_geneve_decap_next, &decap_next_index))
11965         ;
11966       else if (unformat (line_input, "vni %d", &vni))
11967         ;
11968       else
11969         {
11970           errmsg ("parse error '%U'", format_unformat_error, line_input);
11971           return -99;
11972         }
11973     }
11974
11975   if (src_set == 0)
11976     {
11977       errmsg ("tunnel src address not specified");
11978       return -99;
11979     }
11980   if (dst_set == 0)
11981     {
11982       errmsg ("tunnel dst address not specified");
11983       return -99;
11984     }
11985
11986   if (grp_set && !ip46_address_is_multicast (&dst))
11987     {
11988       errmsg ("tunnel group address not multicast");
11989       return -99;
11990     }
11991   if (grp_set && mcast_sw_if_index == ~0)
11992     {
11993       errmsg ("tunnel nonexistent multicast device");
11994       return -99;
11995     }
11996   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11997     {
11998       errmsg ("tunnel dst address must be unicast");
11999       return -99;
12000     }
12001
12002
12003   if (ipv4_set && ipv6_set)
12004     {
12005       errmsg ("both IPv4 and IPv6 addresses specified");
12006       return -99;
12007     }
12008
12009   if ((vni == 0) || (vni >> 24))
12010     {
12011       errmsg ("vni not specified or out of range");
12012       return -99;
12013     }
12014
12015   M (GENEVE_ADD_DEL_TUNNEL, mp);
12016
12017   if (ipv6_set)
12018     {
12019       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12020       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12021     }
12022   else
12023     {
12024       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12025       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12026     }
12027   mp->encap_vrf_id = ntohl (encap_vrf_id);
12028   mp->decap_next_index = ntohl (decap_next_index);
12029   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12030   mp->vni = ntohl (vni);
12031   mp->is_add = is_add;
12032
12033   S (mp);
12034   W (ret);
12035   return ret;
12036 }
12037
12038 static void vl_api_geneve_tunnel_details_t_handler
12039   (vl_api_geneve_tunnel_details_t * mp)
12040 {
12041   vat_main_t *vam = &vat_main;
12042   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12043   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12044
12045   if (mp->src_address.af == ADDRESS_IP6)
12046     {
12047       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12048       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12049     }
12050   else
12051     {
12052       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12053       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12054     }
12055
12056   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12057          ntohl (mp->sw_if_index),
12058          format_ip46_address, &src, IP46_TYPE_ANY,
12059          format_ip46_address, &dst, IP46_TYPE_ANY,
12060          ntohl (mp->encap_vrf_id),
12061          ntohl (mp->decap_next_index), ntohl (mp->vni),
12062          ntohl (mp->mcast_sw_if_index));
12063 }
12064
12065 static void vl_api_geneve_tunnel_details_t_handler_json
12066   (vl_api_geneve_tunnel_details_t * mp)
12067 {
12068   vat_main_t *vam = &vat_main;
12069   vat_json_node_t *node = NULL;
12070   bool is_ipv6;
12071
12072   if (VAT_JSON_ARRAY != vam->json_tree.type)
12073     {
12074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12075       vat_json_init_array (&vam->json_tree);
12076     }
12077   node = vat_json_array_add (&vam->json_tree);
12078
12079   vat_json_init_object (node);
12080   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12081   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12082   if (is_ipv6)
12083     {
12084       struct in6_addr ip6;
12085
12086       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12087       vat_json_object_add_ip6 (node, "src_address", ip6);
12088       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12089       vat_json_object_add_ip6 (node, "dst_address", ip6);
12090     }
12091   else
12092     {
12093       struct in_addr ip4;
12094
12095       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12096       vat_json_object_add_ip4 (node, "src_address", ip4);
12097       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12098       vat_json_object_add_ip4 (node, "dst_address", ip4);
12099     }
12100   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12101   vat_json_object_add_uint (node, "decap_next_index",
12102                             ntohl (mp->decap_next_index));
12103   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12104   vat_json_object_add_uint (node, "mcast_sw_if_index",
12105                             ntohl (mp->mcast_sw_if_index));
12106 }
12107
12108 static int
12109 api_geneve_tunnel_dump (vat_main_t * vam)
12110 {
12111   unformat_input_t *i = vam->input;
12112   vl_api_geneve_tunnel_dump_t *mp;
12113   vl_api_control_ping_t *mp_ping;
12114   u32 sw_if_index;
12115   u8 sw_if_index_set = 0;
12116   int ret;
12117
12118   /* Parse args required to build the message */
12119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12120     {
12121       if (unformat (i, "sw_if_index %d", &sw_if_index))
12122         sw_if_index_set = 1;
12123       else
12124         break;
12125     }
12126
12127   if (sw_if_index_set == 0)
12128     {
12129       sw_if_index = ~0;
12130     }
12131
12132   if (!vam->json_output)
12133     {
12134       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12135              "sw_if_index", "local_address", "remote_address",
12136              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12137     }
12138
12139   /* Get list of geneve-tunnel interfaces */
12140   M (GENEVE_TUNNEL_DUMP, mp);
12141
12142   mp->sw_if_index = htonl (sw_if_index);
12143
12144   S (mp);
12145
12146   /* Use a control ping for synchronization */
12147   M (CONTROL_PING, mp_ping);
12148   S (mp_ping);
12149
12150   W (ret);
12151   return ret;
12152 }
12153
12154 static int
12155 api_gre_tunnel_add_del (vat_main_t * vam)
12156 {
12157   unformat_input_t *line_input = vam->input;
12158   vl_api_address_t src = { }, dst =
12159   {
12160   };
12161   vl_api_gre_tunnel_add_del_t *mp;
12162   vl_api_gre_tunnel_type_t t_type;
12163   u8 is_add = 1;
12164   u8 src_set = 0;
12165   u8 dst_set = 0;
12166   u32 outer_table_id = 0;
12167   u32 session_id = 0;
12168   u32 instance = ~0;
12169   int ret;
12170
12171   t_type = GRE_API_TUNNEL_TYPE_L3;
12172
12173   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12174     {
12175       if (unformat (line_input, "del"))
12176         is_add = 0;
12177       else if (unformat (line_input, "instance %d", &instance))
12178         ;
12179       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12180         {
12181           src_set = 1;
12182         }
12183       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12184         {
12185           dst_set = 1;
12186         }
12187       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12188         ;
12189       else if (unformat (line_input, "teb"))
12190         t_type = GRE_API_TUNNEL_TYPE_TEB;
12191       else if (unformat (line_input, "erspan %d", &session_id))
12192         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12193       else
12194         {
12195           errmsg ("parse error '%U'", format_unformat_error, line_input);
12196           return -99;
12197         }
12198     }
12199
12200   if (src_set == 0)
12201     {
12202       errmsg ("tunnel src address not specified");
12203       return -99;
12204     }
12205   if (dst_set == 0)
12206     {
12207       errmsg ("tunnel dst address not specified");
12208       return -99;
12209     }
12210
12211   M (GRE_TUNNEL_ADD_DEL, mp);
12212
12213   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12214   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12215
12216   mp->tunnel.instance = htonl (instance);
12217   mp->tunnel.outer_table_id = htonl (outer_table_id);
12218   mp->is_add = is_add;
12219   mp->tunnel.session_id = htons ((u16) session_id);
12220   mp->tunnel.type = htonl (t_type);
12221
12222   S (mp);
12223   W (ret);
12224   return ret;
12225 }
12226
12227 static void vl_api_gre_tunnel_details_t_handler
12228   (vl_api_gre_tunnel_details_t * mp)
12229 {
12230   vat_main_t *vam = &vat_main;
12231
12232   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12233          ntohl (mp->tunnel.sw_if_index),
12234          ntohl (mp->tunnel.instance),
12235          format_vl_api_address, &mp->tunnel.src,
12236          format_vl_api_address, &mp->tunnel.dst,
12237          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12238          ntohl (mp->tunnel.session_id));
12239 }
12240
12241 static void vl_api_gre_tunnel_details_t_handler_json
12242   (vl_api_gre_tunnel_details_t * mp)
12243 {
12244   vat_main_t *vam = &vat_main;
12245   vat_json_node_t *node = NULL;
12246
12247   if (VAT_JSON_ARRAY != vam->json_tree.type)
12248     {
12249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12250       vat_json_init_array (&vam->json_tree);
12251     }
12252   node = vat_json_array_add (&vam->json_tree);
12253
12254   vat_json_init_object (node);
12255   vat_json_object_add_uint (node, "sw_if_index",
12256                             ntohl (mp->tunnel.sw_if_index));
12257   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12258
12259   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12260   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12261   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12262   vat_json_object_add_uint (node, "outer_table_id",
12263                             ntohl (mp->tunnel.outer_table_id));
12264   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12265 }
12266
12267 static int
12268 api_gre_tunnel_dump (vat_main_t * vam)
12269 {
12270   unformat_input_t *i = vam->input;
12271   vl_api_gre_tunnel_dump_t *mp;
12272   vl_api_control_ping_t *mp_ping;
12273   u32 sw_if_index;
12274   u8 sw_if_index_set = 0;
12275   int ret;
12276
12277   /* Parse args required to build the message */
12278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12279     {
12280       if (unformat (i, "sw_if_index %d", &sw_if_index))
12281         sw_if_index_set = 1;
12282       else
12283         break;
12284     }
12285
12286   if (sw_if_index_set == 0)
12287     {
12288       sw_if_index = ~0;
12289     }
12290
12291   if (!vam->json_output)
12292     {
12293       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12294              "sw_if_index", "instance", "src_address", "dst_address",
12295              "tunnel_type", "outer_fib_id", "session_id");
12296     }
12297
12298   /* Get list of gre-tunnel interfaces */
12299   M (GRE_TUNNEL_DUMP, mp);
12300
12301   mp->sw_if_index = htonl (sw_if_index);
12302
12303   S (mp);
12304
12305   /* Use a control ping for synchronization */
12306   MPING (CONTROL_PING, mp_ping);
12307   S (mp_ping);
12308
12309   W (ret);
12310   return ret;
12311 }
12312
12313 static int
12314 api_l2_fib_clear_table (vat_main_t * vam)
12315 {
12316 //  unformat_input_t * i = vam->input;
12317   vl_api_l2_fib_clear_table_t *mp;
12318   int ret;
12319
12320   M (L2_FIB_CLEAR_TABLE, mp);
12321
12322   S (mp);
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_l2_interface_efp_filter (vat_main_t * vam)
12329 {
12330   unformat_input_t *i = vam->input;
12331   vl_api_l2_interface_efp_filter_t *mp;
12332   u32 sw_if_index;
12333   u8 enable = 1;
12334   u8 sw_if_index_set = 0;
12335   int ret;
12336
12337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12338     {
12339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12340         sw_if_index_set = 1;
12341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12342         sw_if_index_set = 1;
12343       else if (unformat (i, "enable"))
12344         enable = 1;
12345       else if (unformat (i, "disable"))
12346         enable = 0;
12347       else
12348         {
12349           clib_warning ("parse error '%U'", format_unformat_error, i);
12350           return -99;
12351         }
12352     }
12353
12354   if (sw_if_index_set == 0)
12355     {
12356       errmsg ("missing sw_if_index");
12357       return -99;
12358     }
12359
12360   M (L2_INTERFACE_EFP_FILTER, mp);
12361
12362   mp->sw_if_index = ntohl (sw_if_index);
12363   mp->enable_disable = enable;
12364
12365   S (mp);
12366   W (ret);
12367   return ret;
12368 }
12369
12370 #define foreach_vtr_op                          \
12371 _("disable",  L2_VTR_DISABLED)                  \
12372 _("push-1",  L2_VTR_PUSH_1)                     \
12373 _("push-2",  L2_VTR_PUSH_2)                     \
12374 _("pop-1",  L2_VTR_POP_1)                       \
12375 _("pop-2",  L2_VTR_POP_2)                       \
12376 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12377 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12378 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12379 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12380
12381 static int
12382 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12386   u32 sw_if_index;
12387   u8 sw_if_index_set = 0;
12388   u8 vtr_op_set = 0;
12389   u32 vtr_op = 0;
12390   u32 push_dot1q = 1;
12391   u32 tag1 = ~0;
12392   u32 tag2 = ~0;
12393   int ret;
12394
12395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12396     {
12397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12398         sw_if_index_set = 1;
12399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12400         sw_if_index_set = 1;
12401       else if (unformat (i, "vtr_op %d", &vtr_op))
12402         vtr_op_set = 1;
12403 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12404       foreach_vtr_op
12405 #undef _
12406         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12407         ;
12408       else if (unformat (i, "tag1 %d", &tag1))
12409         ;
12410       else if (unformat (i, "tag2 %d", &tag2))
12411         ;
12412       else
12413         {
12414           clib_warning ("parse error '%U'", format_unformat_error, i);
12415           return -99;
12416         }
12417     }
12418
12419   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12420     {
12421       errmsg ("missing vtr operation or sw_if_index");
12422       return -99;
12423     }
12424
12425   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12426   mp->sw_if_index = ntohl (sw_if_index);
12427   mp->vtr_op = ntohl (vtr_op);
12428   mp->push_dot1q = ntohl (push_dot1q);
12429   mp->tag1 = ntohl (tag1);
12430   mp->tag2 = ntohl (tag2);
12431
12432   S (mp);
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static int
12438 api_create_vhost_user_if (vat_main_t * vam)
12439 {
12440   unformat_input_t *i = vam->input;
12441   vl_api_create_vhost_user_if_t *mp;
12442   u8 *file_name;
12443   u8 is_server = 0;
12444   u8 file_name_set = 0;
12445   u32 custom_dev_instance = ~0;
12446   u8 hwaddr[6];
12447   u8 use_custom_mac = 0;
12448   u8 disable_mrg_rxbuf = 0;
12449   u8 disable_indirect_desc = 0;
12450   u8 *tag = 0;
12451   u8 enable_gso = 0;
12452   int ret;
12453
12454   /* Shut up coverity */
12455   clib_memset (hwaddr, 0, sizeof (hwaddr));
12456
12457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12458     {
12459       if (unformat (i, "socket %s", &file_name))
12460         {
12461           file_name_set = 1;
12462         }
12463       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12464         ;
12465       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12466         use_custom_mac = 1;
12467       else if (unformat (i, "server"))
12468         is_server = 1;
12469       else if (unformat (i, "disable_mrg_rxbuf"))
12470         disable_mrg_rxbuf = 1;
12471       else if (unformat (i, "disable_indirect_desc"))
12472         disable_indirect_desc = 1;
12473       else if (unformat (i, "gso"))
12474         enable_gso = 1;
12475       else if (unformat (i, "tag %s", &tag))
12476         ;
12477       else
12478         break;
12479     }
12480
12481   if (file_name_set == 0)
12482     {
12483       errmsg ("missing socket file name");
12484       return -99;
12485     }
12486
12487   if (vec_len (file_name) > 255)
12488     {
12489       errmsg ("socket file name too long");
12490       return -99;
12491     }
12492   vec_add1 (file_name, 0);
12493
12494   M (CREATE_VHOST_USER_IF, mp);
12495
12496   mp->is_server = is_server;
12497   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12498   mp->disable_indirect_desc = disable_indirect_desc;
12499   mp->enable_gso = enable_gso;
12500   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12501   vec_free (file_name);
12502   if (custom_dev_instance != ~0)
12503     {
12504       mp->renumber = 1;
12505       mp->custom_dev_instance = ntohl (custom_dev_instance);
12506     }
12507
12508   mp->use_custom_mac = use_custom_mac;
12509   clib_memcpy (mp->mac_address, hwaddr, 6);
12510   if (tag)
12511     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12512   vec_free (tag);
12513
12514   S (mp);
12515   W (ret);
12516   return ret;
12517 }
12518
12519 static int
12520 api_modify_vhost_user_if (vat_main_t * vam)
12521 {
12522   unformat_input_t *i = vam->input;
12523   vl_api_modify_vhost_user_if_t *mp;
12524   u8 *file_name;
12525   u8 is_server = 0;
12526   u8 file_name_set = 0;
12527   u32 custom_dev_instance = ~0;
12528   u8 sw_if_index_set = 0;
12529   u32 sw_if_index = (u32) ~ 0;
12530   u8 enable_gso = 0;
12531   int ret;
12532
12533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12534     {
12535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12536         sw_if_index_set = 1;
12537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12538         sw_if_index_set = 1;
12539       else if (unformat (i, "socket %s", &file_name))
12540         {
12541           file_name_set = 1;
12542         }
12543       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12544         ;
12545       else if (unformat (i, "server"))
12546         is_server = 1;
12547       else if (unformat (i, "gso"))
12548         enable_gso = 1;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       errmsg ("missing sw_if_index or interface name");
12556       return -99;
12557     }
12558
12559   if (file_name_set == 0)
12560     {
12561       errmsg ("missing socket file name");
12562       return -99;
12563     }
12564
12565   if (vec_len (file_name) > 255)
12566     {
12567       errmsg ("socket file name too long");
12568       return -99;
12569     }
12570   vec_add1 (file_name, 0);
12571
12572   M (MODIFY_VHOST_USER_IF, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575   mp->is_server = is_server;
12576   mp->enable_gso = enable_gso;
12577   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12578   vec_free (file_name);
12579   if (custom_dev_instance != ~0)
12580     {
12581       mp->renumber = 1;
12582       mp->custom_dev_instance = ntohl (custom_dev_instance);
12583     }
12584
12585   S (mp);
12586   W (ret);
12587   return ret;
12588 }
12589
12590 static int
12591 api_delete_vhost_user_if (vat_main_t * vam)
12592 {
12593   unformat_input_t *i = vam->input;
12594   vl_api_delete_vhost_user_if_t *mp;
12595   u32 sw_if_index = ~0;
12596   u8 sw_if_index_set = 0;
12597   int ret;
12598
12599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12600     {
12601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12602         sw_if_index_set = 1;
12603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12604         sw_if_index_set = 1;
12605       else
12606         break;
12607     }
12608
12609   if (sw_if_index_set == 0)
12610     {
12611       errmsg ("missing sw_if_index or interface name");
12612       return -99;
12613     }
12614
12615
12616   M (DELETE_VHOST_USER_IF, mp);
12617
12618   mp->sw_if_index = ntohl (sw_if_index);
12619
12620   S (mp);
12621   W (ret);
12622   return ret;
12623 }
12624
12625 static void vl_api_sw_interface_vhost_user_details_t_handler
12626   (vl_api_sw_interface_vhost_user_details_t * mp)
12627 {
12628   vat_main_t *vam = &vat_main;
12629   u64 features;
12630
12631   features =
12632     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12633                                                     clib_net_to_host_u32
12634                                                     (mp->features_last_32) <<
12635                                                     32);
12636
12637   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12638          (char *) mp->interface_name,
12639          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12640          features, mp->is_server,
12641          ntohl (mp->num_regions), (char *) mp->sock_filename);
12642   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12643 }
12644
12645 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12646   (vl_api_sw_interface_vhost_user_details_t * mp)
12647 {
12648   vat_main_t *vam = &vat_main;
12649   vat_json_node_t *node = NULL;
12650
12651   if (VAT_JSON_ARRAY != vam->json_tree.type)
12652     {
12653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12654       vat_json_init_array (&vam->json_tree);
12655     }
12656   node = vat_json_array_add (&vam->json_tree);
12657
12658   vat_json_init_object (node);
12659   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12660   vat_json_object_add_string_copy (node, "interface_name",
12661                                    mp->interface_name);
12662   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12663                             ntohl (mp->virtio_net_hdr_sz));
12664   vat_json_object_add_uint (node, "features_first_32",
12665                             clib_net_to_host_u32 (mp->features_first_32));
12666   vat_json_object_add_uint (node, "features_last_32",
12667                             clib_net_to_host_u32 (mp->features_last_32));
12668   vat_json_object_add_uint (node, "is_server", mp->is_server);
12669   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12670   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12671   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12672 }
12673
12674 static int
12675 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12676 {
12677   vl_api_sw_interface_vhost_user_dump_t *mp;
12678   vl_api_control_ping_t *mp_ping;
12679   int ret;
12680   print (vam->ofp,
12681          "Interface name            idx hdr_sz features server regions filename");
12682
12683   /* Get list of vhost-user interfaces */
12684   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12685   mp->sw_if_index = ntohl (~0);
12686   S (mp);
12687
12688   /* Use a control ping for synchronization */
12689   MPING (CONTROL_PING, mp_ping);
12690   S (mp_ping);
12691
12692   W (ret);
12693   return ret;
12694 }
12695
12696 static int
12697 api_show_version (vat_main_t * vam)
12698 {
12699   vl_api_show_version_t *mp;
12700   int ret;
12701
12702   M (SHOW_VERSION, mp);
12703
12704   S (mp);
12705   W (ret);
12706   return ret;
12707 }
12708
12709
12710 static int
12711 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12712 {
12713   unformat_input_t *line_input = vam->input;
12714   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12715   ip46_address_t local, remote;
12716   u8 is_add = 1;
12717   u8 local_set = 0;
12718   u8 remote_set = 0;
12719   u8 grp_set = 0;
12720   u32 mcast_sw_if_index = ~0;
12721   u32 encap_vrf_id = 0;
12722   u32 decap_vrf_id = 0;
12723   u8 protocol = ~0;
12724   u32 vni;
12725   u8 vni_set = 0;
12726   int ret;
12727
12728   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12729     {
12730       if (unformat (line_input, "del"))
12731         is_add = 0;
12732       else if (unformat (line_input, "local %U",
12733                          unformat_ip46_address, &local))
12734         {
12735           local_set = 1;
12736         }
12737       else if (unformat (line_input, "remote %U",
12738                          unformat_ip46_address, &remote))
12739         {
12740           remote_set = 1;
12741         }
12742       else if (unformat (line_input, "group %U %U",
12743                          unformat_ip46_address, &remote,
12744                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12745         {
12746           grp_set = remote_set = 1;
12747         }
12748       else if (unformat (line_input, "group %U",
12749                          unformat_ip46_address, &remote))
12750         {
12751           grp_set = remote_set = 1;
12752         }
12753       else
12754         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12755         ;
12756       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12757         ;
12758       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12759         ;
12760       else if (unformat (line_input, "vni %d", &vni))
12761         vni_set = 1;
12762       else if (unformat (line_input, "next-ip4"))
12763         protocol = 1;
12764       else if (unformat (line_input, "next-ip6"))
12765         protocol = 2;
12766       else if (unformat (line_input, "next-ethernet"))
12767         protocol = 3;
12768       else if (unformat (line_input, "next-nsh"))
12769         protocol = 4;
12770       else
12771         {
12772           errmsg ("parse error '%U'", format_unformat_error, line_input);
12773           return -99;
12774         }
12775     }
12776
12777   if (local_set == 0)
12778     {
12779       errmsg ("tunnel local address not specified");
12780       return -99;
12781     }
12782   if (remote_set == 0)
12783     {
12784       errmsg ("tunnel remote address not specified");
12785       return -99;
12786     }
12787   if (grp_set && mcast_sw_if_index == ~0)
12788     {
12789       errmsg ("tunnel nonexistent multicast device");
12790       return -99;
12791     }
12792   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12793     {
12794       errmsg ("both IPv4 and IPv6 addresses specified");
12795       return -99;
12796     }
12797
12798   if (vni_set == 0)
12799     {
12800       errmsg ("vni not specified");
12801       return -99;
12802     }
12803
12804   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12805
12806   ip_address_encode (&local,
12807                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12808                      IP46_TYPE_IP6, &mp->local);
12809   ip_address_encode (&remote,
12810                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12811                      IP46_TYPE_IP6, &mp->remote);
12812
12813   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12814   mp->encap_vrf_id = ntohl (encap_vrf_id);
12815   mp->decap_vrf_id = ntohl (decap_vrf_id);
12816   mp->protocol = protocol;
12817   mp->vni = ntohl (vni);
12818   mp->is_add = is_add;
12819
12820   S (mp);
12821   W (ret);
12822   return ret;
12823 }
12824
12825 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12826   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12827 {
12828   vat_main_t *vam = &vat_main;
12829   ip46_address_t local, remote;
12830
12831   ip_address_decode (&mp->local, &local);
12832   ip_address_decode (&mp->remote, &remote);
12833
12834   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12835          ntohl (mp->sw_if_index),
12836          format_ip46_address, &local, IP46_TYPE_ANY,
12837          format_ip46_address, &remote, IP46_TYPE_ANY,
12838          ntohl (mp->vni), mp->protocol,
12839          ntohl (mp->mcast_sw_if_index),
12840          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12841 }
12842
12843
12844 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12845   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12846 {
12847   vat_main_t *vam = &vat_main;
12848   vat_json_node_t *node = NULL;
12849   struct in_addr ip4;
12850   struct in6_addr ip6;
12851   ip46_address_t local, remote;
12852
12853   ip_address_decode (&mp->local, &local);
12854   ip_address_decode (&mp->remote, &remote);
12855
12856   if (VAT_JSON_ARRAY != vam->json_tree.type)
12857     {
12858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12859       vat_json_init_array (&vam->json_tree);
12860     }
12861   node = vat_json_array_add (&vam->json_tree);
12862
12863   vat_json_init_object (node);
12864   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12865   if (ip46_address_is_ip4 (&local))
12866     {
12867       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12868       vat_json_object_add_ip4 (node, "local", ip4);
12869       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12870       vat_json_object_add_ip4 (node, "remote", ip4);
12871     }
12872   else
12873     {
12874       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12875       vat_json_object_add_ip6 (node, "local", ip6);
12876       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12877       vat_json_object_add_ip6 (node, "remote", ip6);
12878     }
12879   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12880   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12881   vat_json_object_add_uint (node, "mcast_sw_if_index",
12882                             ntohl (mp->mcast_sw_if_index));
12883   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12884   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12885   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12886 }
12887
12888 static int
12889 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12890 {
12891   unformat_input_t *i = vam->input;
12892   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12893   vl_api_control_ping_t *mp_ping;
12894   u32 sw_if_index;
12895   u8 sw_if_index_set = 0;
12896   int ret;
12897
12898   /* Parse args required to build the message */
12899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12900     {
12901       if (unformat (i, "sw_if_index %d", &sw_if_index))
12902         sw_if_index_set = 1;
12903       else
12904         break;
12905     }
12906
12907   if (sw_if_index_set == 0)
12908     {
12909       sw_if_index = ~0;
12910     }
12911
12912   if (!vam->json_output)
12913     {
12914       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12915              "sw_if_index", "local", "remote", "vni",
12916              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12917     }
12918
12919   /* Get list of vxlan-tunnel interfaces */
12920   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12921
12922   mp->sw_if_index = htonl (sw_if_index);
12923
12924   S (mp);
12925
12926   /* Use a control ping for synchronization */
12927   MPING (CONTROL_PING, mp_ping);
12928   S (mp_ping);
12929
12930   W (ret);
12931   return ret;
12932 }
12933
12934 static void vl_api_l2_fib_table_details_t_handler
12935   (vl_api_l2_fib_table_details_t * mp)
12936 {
12937   vat_main_t *vam = &vat_main;
12938
12939   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12940          "       %d       %d     %d",
12941          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12942          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12943          mp->bvi_mac);
12944 }
12945
12946 static void vl_api_l2_fib_table_details_t_handler_json
12947   (vl_api_l2_fib_table_details_t * mp)
12948 {
12949   vat_main_t *vam = &vat_main;
12950   vat_json_node_t *node = NULL;
12951
12952   if (VAT_JSON_ARRAY != vam->json_tree.type)
12953     {
12954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12955       vat_json_init_array (&vam->json_tree);
12956     }
12957   node = vat_json_array_add (&vam->json_tree);
12958
12959   vat_json_init_object (node);
12960   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12961   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12962   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12963   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12964   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12965   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12966 }
12967
12968 static int
12969 api_l2_fib_table_dump (vat_main_t * vam)
12970 {
12971   unformat_input_t *i = vam->input;
12972   vl_api_l2_fib_table_dump_t *mp;
12973   vl_api_control_ping_t *mp_ping;
12974   u32 bd_id;
12975   u8 bd_id_set = 0;
12976   int ret;
12977
12978   /* Parse args required to build the message */
12979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12980     {
12981       if (unformat (i, "bd_id %d", &bd_id))
12982         bd_id_set = 1;
12983       else
12984         break;
12985     }
12986
12987   if (bd_id_set == 0)
12988     {
12989       errmsg ("missing bridge domain");
12990       return -99;
12991     }
12992
12993   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12994
12995   /* Get list of l2 fib entries */
12996   M (L2_FIB_TABLE_DUMP, mp);
12997
12998   mp->bd_id = ntohl (bd_id);
12999   S (mp);
13000
13001   /* Use a control ping for synchronization */
13002   MPING (CONTROL_PING, mp_ping);
13003   S (mp_ping);
13004
13005   W (ret);
13006   return ret;
13007 }
13008
13009
13010 static int
13011 api_interface_name_renumber (vat_main_t * vam)
13012 {
13013   unformat_input_t *line_input = vam->input;
13014   vl_api_interface_name_renumber_t *mp;
13015   u32 sw_if_index = ~0;
13016   u32 new_show_dev_instance = ~0;
13017   int ret;
13018
13019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13020     {
13021       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13022                     &sw_if_index))
13023         ;
13024       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13025         ;
13026       else if (unformat (line_input, "new_show_dev_instance %d",
13027                          &new_show_dev_instance))
13028         ;
13029       else
13030         break;
13031     }
13032
13033   if (sw_if_index == ~0)
13034     {
13035       errmsg ("missing interface name or sw_if_index");
13036       return -99;
13037     }
13038
13039   if (new_show_dev_instance == ~0)
13040     {
13041       errmsg ("missing new_show_dev_instance");
13042       return -99;
13043     }
13044
13045   M (INTERFACE_NAME_RENUMBER, mp);
13046
13047   mp->sw_if_index = ntohl (sw_if_index);
13048   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13049
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_want_l2_macs_events (vat_main_t * vam)
13057 {
13058   unformat_input_t *line_input = vam->input;
13059   vl_api_want_l2_macs_events_t *mp;
13060   u8 enable_disable = 1;
13061   u32 scan_delay = 0;
13062   u32 max_macs_in_event = 0;
13063   u32 learn_limit = 0;
13064   int ret;
13065
13066   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13067     {
13068       if (unformat (line_input, "learn-limit %d", &learn_limit))
13069         ;
13070       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13071         ;
13072       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13073         ;
13074       else if (unformat (line_input, "disable"))
13075         enable_disable = 0;
13076       else
13077         break;
13078     }
13079
13080   M (WANT_L2_MACS_EVENTS, mp);
13081   mp->enable_disable = enable_disable;
13082   mp->pid = htonl (getpid ());
13083   mp->learn_limit = htonl (learn_limit);
13084   mp->scan_delay = (u8) scan_delay;
13085   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13086   S (mp);
13087   W (ret);
13088   return ret;
13089 }
13090
13091 static int
13092 api_input_acl_set_interface (vat_main_t * vam)
13093 {
13094   unformat_input_t *i = vam->input;
13095   vl_api_input_acl_set_interface_t *mp;
13096   u32 sw_if_index;
13097   int sw_if_index_set;
13098   u32 ip4_table_index = ~0;
13099   u32 ip6_table_index = ~0;
13100   u32 l2_table_index = ~0;
13101   u8 is_add = 1;
13102   int ret;
13103
13104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13105     {
13106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13107         sw_if_index_set = 1;
13108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13109         sw_if_index_set = 1;
13110       else if (unformat (i, "del"))
13111         is_add = 0;
13112       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13113         ;
13114       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13115         ;
13116       else if (unformat (i, "l2-table %d", &l2_table_index))
13117         ;
13118       else
13119         {
13120           clib_warning ("parse error '%U'", format_unformat_error, i);
13121           return -99;
13122         }
13123     }
13124
13125   if (sw_if_index_set == 0)
13126     {
13127       errmsg ("missing interface name or sw_if_index");
13128       return -99;
13129     }
13130
13131   M (INPUT_ACL_SET_INTERFACE, mp);
13132
13133   mp->sw_if_index = ntohl (sw_if_index);
13134   mp->ip4_table_index = ntohl (ip4_table_index);
13135   mp->ip6_table_index = ntohl (ip6_table_index);
13136   mp->l2_table_index = ntohl (l2_table_index);
13137   mp->is_add = is_add;
13138
13139   S (mp);
13140   W (ret);
13141   return ret;
13142 }
13143
13144 static int
13145 api_output_acl_set_interface (vat_main_t * vam)
13146 {
13147   unformat_input_t *i = vam->input;
13148   vl_api_output_acl_set_interface_t *mp;
13149   u32 sw_if_index;
13150   int sw_if_index_set;
13151   u32 ip4_table_index = ~0;
13152   u32 ip6_table_index = ~0;
13153   u32 l2_table_index = ~0;
13154   u8 is_add = 1;
13155   int ret;
13156
13157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13158     {
13159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13160         sw_if_index_set = 1;
13161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13162         sw_if_index_set = 1;
13163       else if (unformat (i, "del"))
13164         is_add = 0;
13165       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13166         ;
13167       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13168         ;
13169       else if (unformat (i, "l2-table %d", &l2_table_index))
13170         ;
13171       else
13172         {
13173           clib_warning ("parse error '%U'", format_unformat_error, i);
13174           return -99;
13175         }
13176     }
13177
13178   if (sw_if_index_set == 0)
13179     {
13180       errmsg ("missing interface name or sw_if_index");
13181       return -99;
13182     }
13183
13184   M (OUTPUT_ACL_SET_INTERFACE, mp);
13185
13186   mp->sw_if_index = ntohl (sw_if_index);
13187   mp->ip4_table_index = ntohl (ip4_table_index);
13188   mp->ip6_table_index = ntohl (ip6_table_index);
13189   mp->l2_table_index = ntohl (l2_table_index);
13190   mp->is_add = is_add;
13191
13192   S (mp);
13193   W (ret);
13194   return ret;
13195 }
13196
13197 static int
13198 api_ip_address_dump (vat_main_t * vam)
13199 {
13200   unformat_input_t *i = vam->input;
13201   vl_api_ip_address_dump_t *mp;
13202   vl_api_control_ping_t *mp_ping;
13203   u32 sw_if_index = ~0;
13204   u8 sw_if_index_set = 0;
13205   u8 ipv4_set = 0;
13206   u8 ipv6_set = 0;
13207   int ret;
13208
13209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13210     {
13211       if (unformat (i, "sw_if_index %d", &sw_if_index))
13212         sw_if_index_set = 1;
13213       else
13214         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13215         sw_if_index_set = 1;
13216       else if (unformat (i, "ipv4"))
13217         ipv4_set = 1;
13218       else if (unformat (i, "ipv6"))
13219         ipv6_set = 1;
13220       else
13221         break;
13222     }
13223
13224   if (ipv4_set && ipv6_set)
13225     {
13226       errmsg ("ipv4 and ipv6 flags cannot be both set");
13227       return -99;
13228     }
13229
13230   if ((!ipv4_set) && (!ipv6_set))
13231     {
13232       errmsg ("no ipv4 nor ipv6 flag set");
13233       return -99;
13234     }
13235
13236   if (sw_if_index_set == 0)
13237     {
13238       errmsg ("missing interface name or sw_if_index");
13239       return -99;
13240     }
13241
13242   vam->current_sw_if_index = sw_if_index;
13243   vam->is_ipv6 = ipv6_set;
13244
13245   M (IP_ADDRESS_DUMP, mp);
13246   mp->sw_if_index = ntohl (sw_if_index);
13247   mp->is_ipv6 = ipv6_set;
13248   S (mp);
13249
13250   /* Use a control ping for synchronization */
13251   MPING (CONTROL_PING, mp_ping);
13252   S (mp_ping);
13253
13254   W (ret);
13255   return ret;
13256 }
13257
13258 static int
13259 api_ip_dump (vat_main_t * vam)
13260 {
13261   vl_api_ip_dump_t *mp;
13262   vl_api_control_ping_t *mp_ping;
13263   unformat_input_t *in = vam->input;
13264   int ipv4_set = 0;
13265   int ipv6_set = 0;
13266   int is_ipv6;
13267   int i;
13268   int ret;
13269
13270   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13271     {
13272       if (unformat (in, "ipv4"))
13273         ipv4_set = 1;
13274       else if (unformat (in, "ipv6"))
13275         ipv6_set = 1;
13276       else
13277         break;
13278     }
13279
13280   if (ipv4_set && ipv6_set)
13281     {
13282       errmsg ("ipv4 and ipv6 flags cannot be both set");
13283       return -99;
13284     }
13285
13286   if ((!ipv4_set) && (!ipv6_set))
13287     {
13288       errmsg ("no ipv4 nor ipv6 flag set");
13289       return -99;
13290     }
13291
13292   is_ipv6 = ipv6_set;
13293   vam->is_ipv6 = is_ipv6;
13294
13295   /* free old data */
13296   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13297     {
13298       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13299     }
13300   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13301
13302   M (IP_DUMP, mp);
13303   mp->is_ipv6 = ipv6_set;
13304   S (mp);
13305
13306   /* Use a control ping for synchronization */
13307   MPING (CONTROL_PING, mp_ping);
13308   S (mp_ping);
13309
13310   W (ret);
13311   return ret;
13312 }
13313
13314 static int
13315 api_ipsec_spd_add_del (vat_main_t * vam)
13316 {
13317   unformat_input_t *i = vam->input;
13318   vl_api_ipsec_spd_add_del_t *mp;
13319   u32 spd_id = ~0;
13320   u8 is_add = 1;
13321   int ret;
13322
13323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13324     {
13325       if (unformat (i, "spd_id %d", &spd_id))
13326         ;
13327       else if (unformat (i, "del"))
13328         is_add = 0;
13329       else
13330         {
13331           clib_warning ("parse error '%U'", format_unformat_error, i);
13332           return -99;
13333         }
13334     }
13335   if (spd_id == ~0)
13336     {
13337       errmsg ("spd_id must be set");
13338       return -99;
13339     }
13340
13341   M (IPSEC_SPD_ADD_DEL, mp);
13342
13343   mp->spd_id = ntohl (spd_id);
13344   mp->is_add = is_add;
13345
13346   S (mp);
13347   W (ret);
13348   return ret;
13349 }
13350
13351 static int
13352 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13353 {
13354   unformat_input_t *i = vam->input;
13355   vl_api_ipsec_interface_add_del_spd_t *mp;
13356   u32 sw_if_index;
13357   u8 sw_if_index_set = 0;
13358   u32 spd_id = (u32) ~ 0;
13359   u8 is_add = 1;
13360   int ret;
13361
13362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13363     {
13364       if (unformat (i, "del"))
13365         is_add = 0;
13366       else if (unformat (i, "spd_id %d", &spd_id))
13367         ;
13368       else
13369         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13370         sw_if_index_set = 1;
13371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13372         sw_if_index_set = 1;
13373       else
13374         {
13375           clib_warning ("parse error '%U'", format_unformat_error, i);
13376           return -99;
13377         }
13378
13379     }
13380
13381   if (spd_id == (u32) ~ 0)
13382     {
13383       errmsg ("spd_id must be set");
13384       return -99;
13385     }
13386
13387   if (sw_if_index_set == 0)
13388     {
13389       errmsg ("missing interface name or sw_if_index");
13390       return -99;
13391     }
13392
13393   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13394
13395   mp->spd_id = ntohl (spd_id);
13396   mp->sw_if_index = ntohl (sw_if_index);
13397   mp->is_add = is_add;
13398
13399   S (mp);
13400   W (ret);
13401   return ret;
13402 }
13403
13404 static int
13405 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13406 {
13407   unformat_input_t *i = vam->input;
13408   vl_api_ipsec_spd_entry_add_del_t *mp;
13409   u8 is_add = 1, is_outbound = 0;
13410   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13411   i32 priority = 0;
13412   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13413   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13414   vl_api_address_t laddr_start = { }, laddr_stop =
13415   {
13416   }, raddr_start =
13417   {
13418   }, raddr_stop =
13419   {
13420   };
13421   int ret;
13422
13423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13424     {
13425       if (unformat (i, "del"))
13426         is_add = 0;
13427       if (unformat (i, "outbound"))
13428         is_outbound = 1;
13429       if (unformat (i, "inbound"))
13430         is_outbound = 0;
13431       else if (unformat (i, "spd_id %d", &spd_id))
13432         ;
13433       else if (unformat (i, "sa_id %d", &sa_id))
13434         ;
13435       else if (unformat (i, "priority %d", &priority))
13436         ;
13437       else if (unformat (i, "protocol %d", &protocol))
13438         ;
13439       else if (unformat (i, "lport_start %d", &lport_start))
13440         ;
13441       else if (unformat (i, "lport_stop %d", &lport_stop))
13442         ;
13443       else if (unformat (i, "rport_start %d", &rport_start))
13444         ;
13445       else if (unformat (i, "rport_stop %d", &rport_stop))
13446         ;
13447       else if (unformat (i, "laddr_start %U",
13448                          unformat_vl_api_address, &laddr_start))
13449         ;
13450       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13451                          &laddr_stop))
13452         ;
13453       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13454                          &raddr_start))
13455         ;
13456       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13457                          &raddr_stop))
13458         ;
13459       else
13460         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13461         {
13462           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13463             {
13464               clib_warning ("unsupported action: 'resolve'");
13465               return -99;
13466             }
13467         }
13468       else
13469         {
13470           clib_warning ("parse error '%U'", format_unformat_error, i);
13471           return -99;
13472         }
13473
13474     }
13475
13476   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13477
13478   mp->is_add = is_add;
13479
13480   mp->entry.spd_id = ntohl (spd_id);
13481   mp->entry.priority = ntohl (priority);
13482   mp->entry.is_outbound = is_outbound;
13483
13484   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13485                sizeof (vl_api_address_t));
13486   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13487                sizeof (vl_api_address_t));
13488   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13489                sizeof (vl_api_address_t));
13490   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13491                sizeof (vl_api_address_t));
13492
13493   mp->entry.protocol = (u8) protocol;
13494   mp->entry.local_port_start = ntohs ((u16) lport_start);
13495   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13496   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13497   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13498   mp->entry.policy = (u8) policy;
13499   mp->entry.sa_id = ntohl (sa_id);
13500
13501   S (mp);
13502   W (ret);
13503   return ret;
13504 }
13505
13506 static int
13507 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13508 {
13509   unformat_input_t *i = vam->input;
13510   vl_api_ipsec_sad_entry_add_del_t *mp;
13511   u32 sad_id = 0, spi = 0;
13512   u8 *ck = 0, *ik = 0;
13513   u8 is_add = 1;
13514
13515   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13516   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13517   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13518   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13519   vl_api_address_t tun_src, tun_dst;
13520   int ret;
13521
13522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13523     {
13524       if (unformat (i, "del"))
13525         is_add = 0;
13526       else if (unformat (i, "sad_id %d", &sad_id))
13527         ;
13528       else if (unformat (i, "spi %d", &spi))
13529         ;
13530       else if (unformat (i, "esp"))
13531         protocol = IPSEC_API_PROTO_ESP;
13532       else
13533         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13534         {
13535           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13536           if (ADDRESS_IP6 == tun_src.af)
13537             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13538         }
13539       else
13540         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13541         {
13542           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13543           if (ADDRESS_IP6 == tun_src.af)
13544             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13545         }
13546       else
13547         if (unformat (i, "crypto_alg %U",
13548                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13549         ;
13550       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13551         ;
13552       else if (unformat (i, "integ_alg %U",
13553                          unformat_ipsec_api_integ_alg, &integ_alg))
13554         ;
13555       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13556         ;
13557       else
13558         {
13559           clib_warning ("parse error '%U'", format_unformat_error, i);
13560           return -99;
13561         }
13562
13563     }
13564
13565   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13566
13567   mp->is_add = is_add;
13568   mp->entry.sad_id = ntohl (sad_id);
13569   mp->entry.protocol = protocol;
13570   mp->entry.spi = ntohl (spi);
13571   mp->entry.flags = flags;
13572
13573   mp->entry.crypto_algorithm = crypto_alg;
13574   mp->entry.integrity_algorithm = integ_alg;
13575   mp->entry.crypto_key.length = vec_len (ck);
13576   mp->entry.integrity_key.length = vec_len (ik);
13577
13578   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13579     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13580
13581   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13582     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13583
13584   if (ck)
13585     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13586   if (ik)
13587     clib_memcpy (mp->entry.integrity_key.data, ik,
13588                  mp->entry.integrity_key.length);
13589
13590   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13591     {
13592       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13593                    sizeof (mp->entry.tunnel_src));
13594       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13595                    sizeof (mp->entry.tunnel_dst));
13596     }
13597
13598   S (mp);
13599   W (ret);
13600   return ret;
13601 }
13602
13603 static int
13604 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13605 {
13606   unformat_input_t *i = vam->input;
13607   vl_api_ipsec_tunnel_if_add_del_t *mp;
13608   u32 local_spi = 0, remote_spi = 0;
13609   u32 crypto_alg = 0, integ_alg = 0;
13610   u8 *lck = NULL, *rck = NULL;
13611   u8 *lik = NULL, *rik = NULL;
13612   vl_api_address_t local_ip = { 0 };
13613   vl_api_address_t remote_ip = { 0 };
13614   f64 before = 0;
13615   u8 is_add = 1;
13616   u8 esn = 0;
13617   u8 anti_replay = 0;
13618   u8 renumber = 0;
13619   u32 instance = ~0;
13620   u32 count = 1, jj;
13621   int ret = -1;
13622
13623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13624     {
13625       if (unformat (i, "del"))
13626         is_add = 0;
13627       else if (unformat (i, "esn"))
13628         esn = 1;
13629       else if (unformat (i, "anti-replay"))
13630         anti_replay = 1;
13631       else if (unformat (i, "count %d", &count))
13632         ;
13633       else if (unformat (i, "local_spi %d", &local_spi))
13634         ;
13635       else if (unformat (i, "remote_spi %d", &remote_spi))
13636         ;
13637       else
13638         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13639         ;
13640       else
13641         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13642         ;
13643       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13644         ;
13645       else
13646         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13647         ;
13648       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13649         ;
13650       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13651         ;
13652       else
13653         if (unformat
13654             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13655         {
13656           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13657             {
13658               errmsg ("unsupported crypto-alg: '%U'\n",
13659                       format_ipsec_crypto_alg, crypto_alg);
13660               return -99;
13661             }
13662         }
13663       else
13664         if (unformat
13665             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13666         {
13667           if (integ_alg >= IPSEC_INTEG_N_ALG)
13668             {
13669               errmsg ("unsupported integ-alg: '%U'\n",
13670                       format_ipsec_integ_alg, integ_alg);
13671               return -99;
13672             }
13673         }
13674       else if (unformat (i, "instance %u", &instance))
13675         renumber = 1;
13676       else
13677         {
13678           errmsg ("parse error '%U'\n", format_unformat_error, i);
13679           return -99;
13680         }
13681     }
13682
13683   if (count > 1)
13684     {
13685       /* Turn on async mode */
13686       vam->async_mode = 1;
13687       vam->async_errors = 0;
13688       before = vat_time_now (vam);
13689     }
13690
13691   for (jj = 0; jj < count; jj++)
13692     {
13693       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13694
13695       mp->is_add = is_add;
13696       mp->esn = esn;
13697       mp->anti_replay = anti_replay;
13698
13699       if (jj > 0)
13700         increment_address (&remote_ip);
13701
13702       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13703       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13704
13705       mp->local_spi = htonl (local_spi + jj);
13706       mp->remote_spi = htonl (remote_spi + jj);
13707       mp->crypto_alg = (u8) crypto_alg;
13708
13709       mp->local_crypto_key_len = 0;
13710       if (lck)
13711         {
13712           mp->local_crypto_key_len = vec_len (lck);
13713           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13714             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13715           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13716         }
13717
13718       mp->remote_crypto_key_len = 0;
13719       if (rck)
13720         {
13721           mp->remote_crypto_key_len = vec_len (rck);
13722           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13723             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13724           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13725         }
13726
13727       mp->integ_alg = (u8) integ_alg;
13728
13729       mp->local_integ_key_len = 0;
13730       if (lik)
13731         {
13732           mp->local_integ_key_len = vec_len (lik);
13733           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13734             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13735           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13736         }
13737
13738       mp->remote_integ_key_len = 0;
13739       if (rik)
13740         {
13741           mp->remote_integ_key_len = vec_len (rik);
13742           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13743             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13744           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13745         }
13746
13747       if (renumber)
13748         {
13749           mp->renumber = renumber;
13750           mp->show_instance = ntohl (instance);
13751         }
13752       S (mp);
13753     }
13754
13755   /* When testing multiple add/del ops, use a control-ping to sync */
13756   if (count > 1)
13757     {
13758       vl_api_control_ping_t *mp_ping;
13759       f64 after;
13760       f64 timeout;
13761
13762       /* Shut off async mode */
13763       vam->async_mode = 0;
13764
13765       MPING (CONTROL_PING, mp_ping);
13766       S (mp_ping);
13767
13768       timeout = vat_time_now (vam) + 1.0;
13769       while (vat_time_now (vam) < timeout)
13770         if (vam->result_ready == 1)
13771           goto out;
13772       vam->retval = -99;
13773
13774     out:
13775       if (vam->retval == -99)
13776         errmsg ("timeout");
13777
13778       if (vam->async_errors > 0)
13779         {
13780           errmsg ("%d asynchronous errors", vam->async_errors);
13781           vam->retval = -98;
13782         }
13783       vam->async_errors = 0;
13784       after = vat_time_now (vam);
13785
13786       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13787       if (jj > 0)
13788         count = jj;
13789
13790       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13791              count, after - before, count / (after - before));
13792     }
13793   else
13794     {
13795       /* Wait for a reply... */
13796       W (ret);
13797       return ret;
13798     }
13799
13800   return ret;
13801 }
13802
13803 static void
13804 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13805 {
13806   vat_main_t *vam = &vat_main;
13807
13808   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13809          "crypto_key %U integ_alg %u integ_key %U flags %x "
13810          "tunnel_src_addr %U tunnel_dst_addr %U "
13811          "salt %u seq_outbound %lu last_seq_inbound %lu "
13812          "replay_window %lu\n",
13813          ntohl (mp->entry.sad_id),
13814          ntohl (mp->sw_if_index),
13815          ntohl (mp->entry.spi),
13816          ntohl (mp->entry.protocol),
13817          ntohl (mp->entry.crypto_algorithm),
13818          format_hex_bytes, mp->entry.crypto_key.data,
13819          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13820          format_hex_bytes, mp->entry.integrity_key.data,
13821          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13822          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13823          &mp->entry.tunnel_dst, ntohl (mp->salt),
13824          clib_net_to_host_u64 (mp->seq_outbound),
13825          clib_net_to_host_u64 (mp->last_seq_inbound),
13826          clib_net_to_host_u64 (mp->replay_window));
13827 }
13828
13829 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13830 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13831
13832 static void vl_api_ipsec_sa_details_t_handler_json
13833   (vl_api_ipsec_sa_details_t * mp)
13834 {
13835   vat_main_t *vam = &vat_main;
13836   vat_json_node_t *node = NULL;
13837   vl_api_ipsec_sad_flags_t flags;
13838
13839   if (VAT_JSON_ARRAY != vam->json_tree.type)
13840     {
13841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13842       vat_json_init_array (&vam->json_tree);
13843     }
13844   node = vat_json_array_add (&vam->json_tree);
13845
13846   vat_json_init_object (node);
13847   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13848   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13849   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13850   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13851   vat_json_object_add_uint (node, "crypto_alg",
13852                             ntohl (mp->entry.crypto_algorithm));
13853   vat_json_object_add_uint (node, "integ_alg",
13854                             ntohl (mp->entry.integrity_algorithm));
13855   flags = ntohl (mp->entry.flags);
13856   vat_json_object_add_uint (node, "use_esn",
13857                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13858   vat_json_object_add_uint (node, "use_anti_replay",
13859                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13860   vat_json_object_add_uint (node, "is_tunnel",
13861                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13862   vat_json_object_add_uint (node, "is_tunnel_ip6",
13863                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13864   vat_json_object_add_uint (node, "udp_encap",
13865                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13866   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13867                              mp->entry.crypto_key.length);
13868   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13869                              mp->entry.integrity_key.length);
13870   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13871   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13872   vat_json_object_add_uint (node, "replay_window",
13873                             clib_net_to_host_u64 (mp->replay_window));
13874 }
13875
13876 static int
13877 api_ipsec_sa_dump (vat_main_t * vam)
13878 {
13879   unformat_input_t *i = vam->input;
13880   vl_api_ipsec_sa_dump_t *mp;
13881   vl_api_control_ping_t *mp_ping;
13882   u32 sa_id = ~0;
13883   int ret;
13884
13885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (i, "sa_id %d", &sa_id))
13888         ;
13889       else
13890         {
13891           clib_warning ("parse error '%U'", format_unformat_error, i);
13892           return -99;
13893         }
13894     }
13895
13896   M (IPSEC_SA_DUMP, mp);
13897
13898   mp->sa_id = ntohl (sa_id);
13899
13900   S (mp);
13901
13902   /* Use a control ping for synchronization */
13903   M (CONTROL_PING, mp_ping);
13904   S (mp_ping);
13905
13906   W (ret);
13907   return ret;
13908 }
13909
13910 static int
13911 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13912 {
13913   unformat_input_t *i = vam->input;
13914   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13915   u32 sw_if_index = ~0;
13916   u32 sa_id = ~0;
13917   u8 is_outbound = (u8) ~ 0;
13918   int ret;
13919
13920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13921     {
13922       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13923         ;
13924       else if (unformat (i, "sa_id %d", &sa_id))
13925         ;
13926       else if (unformat (i, "outbound"))
13927         is_outbound = 1;
13928       else if (unformat (i, "inbound"))
13929         is_outbound = 0;
13930       else
13931         {
13932           clib_warning ("parse error '%U'", format_unformat_error, i);
13933           return -99;
13934         }
13935     }
13936
13937   if (sw_if_index == ~0)
13938     {
13939       errmsg ("interface must be specified");
13940       return -99;
13941     }
13942
13943   if (sa_id == ~0)
13944     {
13945       errmsg ("SA ID must be specified");
13946       return -99;
13947     }
13948
13949   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13950
13951   mp->sw_if_index = htonl (sw_if_index);
13952   mp->sa_id = htonl (sa_id);
13953   mp->is_outbound = is_outbound;
13954
13955   S (mp);
13956   W (ret);
13957
13958   return ret;
13959 }
13960
13961 static int
13962 api_get_first_msg_id (vat_main_t * vam)
13963 {
13964   vl_api_get_first_msg_id_t *mp;
13965   unformat_input_t *i = vam->input;
13966   u8 *name;
13967   u8 name_set = 0;
13968   int ret;
13969
13970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (i, "client %s", &name))
13973         name_set = 1;
13974       else
13975         break;
13976     }
13977
13978   if (name_set == 0)
13979     {
13980       errmsg ("missing client name");
13981       return -99;
13982     }
13983   vec_add1 (name, 0);
13984
13985   if (vec_len (name) > 63)
13986     {
13987       errmsg ("client name too long");
13988       return -99;
13989     }
13990
13991   M (GET_FIRST_MSG_ID, mp);
13992   clib_memcpy (mp->name, name, vec_len (name));
13993   S (mp);
13994   W (ret);
13995   return ret;
13996 }
13997
13998 static int
13999 api_cop_interface_enable_disable (vat_main_t * vam)
14000 {
14001   unformat_input_t *line_input = vam->input;
14002   vl_api_cop_interface_enable_disable_t *mp;
14003   u32 sw_if_index = ~0;
14004   u8 enable_disable = 1;
14005   int ret;
14006
14007   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (line_input, "disable"))
14010         enable_disable = 0;
14011       if (unformat (line_input, "enable"))
14012         enable_disable = 1;
14013       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14014                          vam, &sw_if_index))
14015         ;
14016       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14017         ;
14018       else
14019         break;
14020     }
14021
14022   if (sw_if_index == ~0)
14023     {
14024       errmsg ("missing interface name or sw_if_index");
14025       return -99;
14026     }
14027
14028   /* Construct the API message */
14029   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14030   mp->sw_if_index = ntohl (sw_if_index);
14031   mp->enable_disable = enable_disable;
14032
14033   /* send it... */
14034   S (mp);
14035   /* Wait for the reply */
14036   W (ret);
14037   return ret;
14038 }
14039
14040 static int
14041 api_cop_whitelist_enable_disable (vat_main_t * vam)
14042 {
14043   unformat_input_t *line_input = vam->input;
14044   vl_api_cop_whitelist_enable_disable_t *mp;
14045   u32 sw_if_index = ~0;
14046   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14047   u32 fib_id = 0;
14048   int ret;
14049
14050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14051     {
14052       if (unformat (line_input, "ip4"))
14053         ip4 = 1;
14054       else if (unformat (line_input, "ip6"))
14055         ip6 = 1;
14056       else if (unformat (line_input, "default"))
14057         default_cop = 1;
14058       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14059                          vam, &sw_if_index))
14060         ;
14061       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14062         ;
14063       else if (unformat (line_input, "fib-id %d", &fib_id))
14064         ;
14065       else
14066         break;
14067     }
14068
14069   if (sw_if_index == ~0)
14070     {
14071       errmsg ("missing interface name or sw_if_index");
14072       return -99;
14073     }
14074
14075   /* Construct the API message */
14076   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14077   mp->sw_if_index = ntohl (sw_if_index);
14078   mp->fib_id = ntohl (fib_id);
14079   mp->ip4 = ip4;
14080   mp->ip6 = ip6;
14081   mp->default_cop = default_cop;
14082
14083   /* send it... */
14084   S (mp);
14085   /* Wait for the reply */
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_get_node_graph (vat_main_t * vam)
14092 {
14093   vl_api_get_node_graph_t *mp;
14094   int ret;
14095
14096   M (GET_NODE_GRAPH, mp);
14097
14098   /* send it... */
14099   S (mp);
14100   /* Wait for the reply */
14101   W (ret);
14102   return ret;
14103 }
14104
14105 /* *INDENT-OFF* */
14106 /** Used for parsing LISP eids */
14107 typedef CLIB_PACKED(struct{
14108   u8 addr[16];   /**< eid address */
14109   u32 len;       /**< prefix length if IP */
14110   u8 type;      /**< type of eid */
14111 }) lisp_eid_vat_t;
14112 /* *INDENT-ON* */
14113
14114 static uword
14115 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14116 {
14117   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14118
14119   clib_memset (a, 0, sizeof (a[0]));
14120
14121   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14122     {
14123       a->type = 0;              /* ipv4 type */
14124     }
14125   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14126     {
14127       a->type = 1;              /* ipv6 type */
14128     }
14129   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14130     {
14131       a->type = 2;              /* mac type */
14132     }
14133   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14134     {
14135       a->type = 3;              /* NSH type */
14136       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14137       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14138     }
14139   else
14140     {
14141       return 0;
14142     }
14143
14144   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14145     {
14146       return 0;
14147     }
14148
14149   return 1;
14150 }
14151
14152 static int
14153 lisp_eid_size_vat (u8 type)
14154 {
14155   switch (type)
14156     {
14157     case 0:
14158       return 4;
14159     case 1:
14160       return 16;
14161     case 2:
14162       return 6;
14163     case 3:
14164       return 5;
14165     }
14166   return 0;
14167 }
14168
14169 static void
14170 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14171 {
14172   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14173 }
14174
14175 static int
14176 api_one_add_del_locator_set (vat_main_t * vam)
14177 {
14178   unformat_input_t *input = vam->input;
14179   vl_api_one_add_del_locator_set_t *mp;
14180   u8 is_add = 1;
14181   u8 *locator_set_name = NULL;
14182   u8 locator_set_name_set = 0;
14183   vl_api_local_locator_t locator, *locators = 0;
14184   u32 sw_if_index, priority, weight;
14185   u32 data_len = 0;
14186
14187   int ret;
14188   /* Parse args required to build the message */
14189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14190     {
14191       if (unformat (input, "del"))
14192         {
14193           is_add = 0;
14194         }
14195       else if (unformat (input, "locator-set %s", &locator_set_name))
14196         {
14197           locator_set_name_set = 1;
14198         }
14199       else if (unformat (input, "sw_if_index %u p %u w %u",
14200                          &sw_if_index, &priority, &weight))
14201         {
14202           locator.sw_if_index = htonl (sw_if_index);
14203           locator.priority = priority;
14204           locator.weight = weight;
14205           vec_add1 (locators, locator);
14206         }
14207       else
14208         if (unformat
14209             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14210              &sw_if_index, &priority, &weight))
14211         {
14212           locator.sw_if_index = htonl (sw_if_index);
14213           locator.priority = priority;
14214           locator.weight = weight;
14215           vec_add1 (locators, locator);
14216         }
14217       else
14218         break;
14219     }
14220
14221   if (locator_set_name_set == 0)
14222     {
14223       errmsg ("missing locator-set name");
14224       vec_free (locators);
14225       return -99;
14226     }
14227
14228   if (vec_len (locator_set_name) > 64)
14229     {
14230       errmsg ("locator-set name too long");
14231       vec_free (locator_set_name);
14232       vec_free (locators);
14233       return -99;
14234     }
14235   vec_add1 (locator_set_name, 0);
14236
14237   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14238
14239   /* Construct the API message */
14240   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14241
14242   mp->is_add = is_add;
14243   clib_memcpy (mp->locator_set_name, locator_set_name,
14244                vec_len (locator_set_name));
14245   vec_free (locator_set_name);
14246
14247   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14248   if (locators)
14249     clib_memcpy (mp->locators, locators, data_len);
14250   vec_free (locators);
14251
14252   /* send it... */
14253   S (mp);
14254
14255   /* Wait for a reply... */
14256   W (ret);
14257   return ret;
14258 }
14259
14260 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14261
14262 static int
14263 api_one_add_del_locator (vat_main_t * vam)
14264 {
14265   unformat_input_t *input = vam->input;
14266   vl_api_one_add_del_locator_t *mp;
14267   u32 tmp_if_index = ~0;
14268   u32 sw_if_index = ~0;
14269   u8 sw_if_index_set = 0;
14270   u8 sw_if_index_if_name_set = 0;
14271   u32 priority = ~0;
14272   u8 priority_set = 0;
14273   u32 weight = ~0;
14274   u8 weight_set = 0;
14275   u8 is_add = 1;
14276   u8 *locator_set_name = NULL;
14277   u8 locator_set_name_set = 0;
14278   int ret;
14279
14280   /* Parse args required to build the message */
14281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14282     {
14283       if (unformat (input, "del"))
14284         {
14285           is_add = 0;
14286         }
14287       else if (unformat (input, "locator-set %s", &locator_set_name))
14288         {
14289           locator_set_name_set = 1;
14290         }
14291       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14292                          &tmp_if_index))
14293         {
14294           sw_if_index_if_name_set = 1;
14295           sw_if_index = tmp_if_index;
14296         }
14297       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14298         {
14299           sw_if_index_set = 1;
14300           sw_if_index = tmp_if_index;
14301         }
14302       else if (unformat (input, "p %d", &priority))
14303         {
14304           priority_set = 1;
14305         }
14306       else if (unformat (input, "w %d", &weight))
14307         {
14308           weight_set = 1;
14309         }
14310       else
14311         break;
14312     }
14313
14314   if (locator_set_name_set == 0)
14315     {
14316       errmsg ("missing locator-set name");
14317       return -99;
14318     }
14319
14320   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14321     {
14322       errmsg ("missing sw_if_index");
14323       vec_free (locator_set_name);
14324       return -99;
14325     }
14326
14327   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14328     {
14329       errmsg ("cannot use both params interface name and sw_if_index");
14330       vec_free (locator_set_name);
14331       return -99;
14332     }
14333
14334   if (priority_set == 0)
14335     {
14336       errmsg ("missing locator-set priority");
14337       vec_free (locator_set_name);
14338       return -99;
14339     }
14340
14341   if (weight_set == 0)
14342     {
14343       errmsg ("missing locator-set weight");
14344       vec_free (locator_set_name);
14345       return -99;
14346     }
14347
14348   if (vec_len (locator_set_name) > 64)
14349     {
14350       errmsg ("locator-set name too long");
14351       vec_free (locator_set_name);
14352       return -99;
14353     }
14354   vec_add1 (locator_set_name, 0);
14355
14356   /* Construct the API message */
14357   M (ONE_ADD_DEL_LOCATOR, mp);
14358
14359   mp->is_add = is_add;
14360   mp->sw_if_index = ntohl (sw_if_index);
14361   mp->priority = priority;
14362   mp->weight = weight;
14363   clib_memcpy (mp->locator_set_name, locator_set_name,
14364                vec_len (locator_set_name));
14365   vec_free (locator_set_name);
14366
14367   /* send it... */
14368   S (mp);
14369
14370   /* Wait for a reply... */
14371   W (ret);
14372   return ret;
14373 }
14374
14375 #define api_lisp_add_del_locator api_one_add_del_locator
14376
14377 uword
14378 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14379 {
14380   u32 *key_id = va_arg (*args, u32 *);
14381   u8 *s = 0;
14382
14383   if (unformat (input, "%s", &s))
14384     {
14385       if (!strcmp ((char *) s, "sha1"))
14386         key_id[0] = HMAC_SHA_1_96;
14387       else if (!strcmp ((char *) s, "sha256"))
14388         key_id[0] = HMAC_SHA_256_128;
14389       else
14390         {
14391           clib_warning ("invalid key_id: '%s'", s);
14392           key_id[0] = HMAC_NO_KEY;
14393         }
14394     }
14395   else
14396     return 0;
14397
14398   vec_free (s);
14399   return 1;
14400 }
14401
14402 static int
14403 api_one_add_del_local_eid (vat_main_t * vam)
14404 {
14405   unformat_input_t *input = vam->input;
14406   vl_api_one_add_del_local_eid_t *mp;
14407   u8 is_add = 1;
14408   u8 eid_set = 0;
14409   lisp_eid_vat_t _eid, *eid = &_eid;
14410   u8 *locator_set_name = 0;
14411   u8 locator_set_name_set = 0;
14412   u32 vni = 0;
14413   u16 key_id = 0;
14414   u8 *key = 0;
14415   int ret;
14416
14417   /* Parse args required to build the message */
14418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14419     {
14420       if (unformat (input, "del"))
14421         {
14422           is_add = 0;
14423         }
14424       else if (unformat (input, "vni %d", &vni))
14425         {
14426           ;
14427         }
14428       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14429         {
14430           eid_set = 1;
14431         }
14432       else if (unformat (input, "locator-set %s", &locator_set_name))
14433         {
14434           locator_set_name_set = 1;
14435         }
14436       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14437         ;
14438       else if (unformat (input, "secret-key %_%v%_", &key))
14439         ;
14440       else
14441         break;
14442     }
14443
14444   if (locator_set_name_set == 0)
14445     {
14446       errmsg ("missing locator-set name");
14447       return -99;
14448     }
14449
14450   if (0 == eid_set)
14451     {
14452       errmsg ("EID address not set!");
14453       vec_free (locator_set_name);
14454       return -99;
14455     }
14456
14457   if (key && (0 == key_id))
14458     {
14459       errmsg ("invalid key_id!");
14460       return -99;
14461     }
14462
14463   if (vec_len (key) > 64)
14464     {
14465       errmsg ("key too long");
14466       vec_free (key);
14467       return -99;
14468     }
14469
14470   if (vec_len (locator_set_name) > 64)
14471     {
14472       errmsg ("locator-set name too long");
14473       vec_free (locator_set_name);
14474       return -99;
14475     }
14476   vec_add1 (locator_set_name, 0);
14477
14478   /* Construct the API message */
14479   M (ONE_ADD_DEL_LOCAL_EID, mp);
14480
14481   mp->is_add = is_add;
14482   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14483   mp->eid_type = eid->type;
14484   mp->prefix_len = eid->len;
14485   mp->vni = clib_host_to_net_u32 (vni);
14486   mp->key_id = clib_host_to_net_u16 (key_id);
14487   clib_memcpy (mp->locator_set_name, locator_set_name,
14488                vec_len (locator_set_name));
14489   clib_memcpy (mp->key, key, vec_len (key));
14490
14491   vec_free (locator_set_name);
14492   vec_free (key);
14493
14494   /* send it... */
14495   S (mp);
14496
14497   /* Wait for a reply... */
14498   W (ret);
14499   return ret;
14500 }
14501
14502 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14503
14504 static int
14505 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14506 {
14507   u32 dp_table = 0, vni = 0;;
14508   unformat_input_t *input = vam->input;
14509   vl_api_gpe_add_del_fwd_entry_t *mp;
14510   u8 is_add = 1;
14511   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14512   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14513   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14514   u32 action = ~0, w;
14515   ip4_address_t rmt_rloc4, lcl_rloc4;
14516   ip6_address_t rmt_rloc6, lcl_rloc6;
14517   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14518   int ret;
14519
14520   clib_memset (&rloc, 0, sizeof (rloc));
14521
14522   /* Parse args required to build the message */
14523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14524     {
14525       if (unformat (input, "del"))
14526         is_add = 0;
14527       else if (unformat (input, "add"))
14528         is_add = 1;
14529       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14530         {
14531           rmt_eid_set = 1;
14532         }
14533       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14534         {
14535           lcl_eid_set = 1;
14536         }
14537       else if (unformat (input, "vrf %d", &dp_table))
14538         ;
14539       else if (unformat (input, "bd %d", &dp_table))
14540         ;
14541       else if (unformat (input, "vni %d", &vni))
14542         ;
14543       else if (unformat (input, "w %d", &w))
14544         {
14545           if (!curr_rloc)
14546             {
14547               errmsg ("No RLOC configured for setting priority/weight!");
14548               return -99;
14549             }
14550           curr_rloc->weight = w;
14551         }
14552       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14553                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14554         {
14555           rloc.is_ip4 = 1;
14556
14557           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14558           rloc.weight = 0;
14559           vec_add1 (lcl_locs, rloc);
14560
14561           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14562           vec_add1 (rmt_locs, rloc);
14563           /* weight saved in rmt loc */
14564           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14565         }
14566       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14567                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14568         {
14569           rloc.is_ip4 = 0;
14570           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14571           rloc.weight = 0;
14572           vec_add1 (lcl_locs, rloc);
14573
14574           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14575           vec_add1 (rmt_locs, rloc);
14576           /* weight saved in rmt loc */
14577           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14578         }
14579       else if (unformat (input, "action %d", &action))
14580         {
14581           ;
14582         }
14583       else
14584         {
14585           clib_warning ("parse error '%U'", format_unformat_error, input);
14586           return -99;
14587         }
14588     }
14589
14590   if (!rmt_eid_set)
14591     {
14592       errmsg ("remote eid addresses not set");
14593       return -99;
14594     }
14595
14596   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14597     {
14598       errmsg ("eid types don't match");
14599       return -99;
14600     }
14601
14602   if (0 == rmt_locs && (u32) ~ 0 == action)
14603     {
14604       errmsg ("action not set for negative mapping");
14605       return -99;
14606     }
14607
14608   /* Construct the API message */
14609   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14610       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14611
14612   mp->is_add = is_add;
14613   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14614   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14615   mp->eid_type = rmt_eid->type;
14616   mp->dp_table = clib_host_to_net_u32 (dp_table);
14617   mp->vni = clib_host_to_net_u32 (vni);
14618   mp->rmt_len = rmt_eid->len;
14619   mp->lcl_len = lcl_eid->len;
14620   mp->action = action;
14621
14622   if (0 != rmt_locs && 0 != lcl_locs)
14623     {
14624       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14625       clib_memcpy (mp->locs, lcl_locs,
14626                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14627
14628       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14629       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14630                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14631     }
14632   vec_free (lcl_locs);
14633   vec_free (rmt_locs);
14634
14635   /* send it... */
14636   S (mp);
14637
14638   /* Wait for a reply... */
14639   W (ret);
14640   return ret;
14641 }
14642
14643 static int
14644 api_one_add_del_map_server (vat_main_t * vam)
14645 {
14646   unformat_input_t *input = vam->input;
14647   vl_api_one_add_del_map_server_t *mp;
14648   u8 is_add = 1;
14649   u8 ipv4_set = 0;
14650   u8 ipv6_set = 0;
14651   ip4_address_t ipv4;
14652   ip6_address_t ipv6;
14653   int ret;
14654
14655   /* Parse args required to build the message */
14656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (input, "del"))
14659         {
14660           is_add = 0;
14661         }
14662       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14663         {
14664           ipv4_set = 1;
14665         }
14666       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14667         {
14668           ipv6_set = 1;
14669         }
14670       else
14671         break;
14672     }
14673
14674   if (ipv4_set && ipv6_set)
14675     {
14676       errmsg ("both eid v4 and v6 addresses set");
14677       return -99;
14678     }
14679
14680   if (!ipv4_set && !ipv6_set)
14681     {
14682       errmsg ("eid addresses not set");
14683       return -99;
14684     }
14685
14686   /* Construct the API message */
14687   M (ONE_ADD_DEL_MAP_SERVER, mp);
14688
14689   mp->is_add = is_add;
14690   if (ipv6_set)
14691     {
14692       mp->is_ipv6 = 1;
14693       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14694     }
14695   else
14696     {
14697       mp->is_ipv6 = 0;
14698       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14699     }
14700
14701   /* send it... */
14702   S (mp);
14703
14704   /* Wait for a reply... */
14705   W (ret);
14706   return ret;
14707 }
14708
14709 #define api_lisp_add_del_map_server api_one_add_del_map_server
14710
14711 static int
14712 api_one_add_del_map_resolver (vat_main_t * vam)
14713 {
14714   unformat_input_t *input = vam->input;
14715   vl_api_one_add_del_map_resolver_t *mp;
14716   u8 is_add = 1;
14717   u8 ipv4_set = 0;
14718   u8 ipv6_set = 0;
14719   ip4_address_t ipv4;
14720   ip6_address_t ipv6;
14721   int ret;
14722
14723   /* Parse args required to build the message */
14724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14725     {
14726       if (unformat (input, "del"))
14727         {
14728           is_add = 0;
14729         }
14730       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14731         {
14732           ipv4_set = 1;
14733         }
14734       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14735         {
14736           ipv6_set = 1;
14737         }
14738       else
14739         break;
14740     }
14741
14742   if (ipv4_set && ipv6_set)
14743     {
14744       errmsg ("both eid v4 and v6 addresses set");
14745       return -99;
14746     }
14747
14748   if (!ipv4_set && !ipv6_set)
14749     {
14750       errmsg ("eid addresses not set");
14751       return -99;
14752     }
14753
14754   /* Construct the API message */
14755   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14756
14757   mp->is_add = is_add;
14758   if (ipv6_set)
14759     {
14760       mp->is_ipv6 = 1;
14761       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14762     }
14763   else
14764     {
14765       mp->is_ipv6 = 0;
14766       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14767     }
14768
14769   /* send it... */
14770   S (mp);
14771
14772   /* Wait for a reply... */
14773   W (ret);
14774   return ret;
14775 }
14776
14777 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14778
14779 static int
14780 api_lisp_gpe_enable_disable (vat_main_t * vam)
14781 {
14782   unformat_input_t *input = vam->input;
14783   vl_api_gpe_enable_disable_t *mp;
14784   u8 is_set = 0;
14785   u8 is_en = 1;
14786   int ret;
14787
14788   /* Parse args required to build the message */
14789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14790     {
14791       if (unformat (input, "enable"))
14792         {
14793           is_set = 1;
14794           is_en = 1;
14795         }
14796       else if (unformat (input, "disable"))
14797         {
14798           is_set = 1;
14799           is_en = 0;
14800         }
14801       else
14802         break;
14803     }
14804
14805   if (is_set == 0)
14806     {
14807       errmsg ("Value not set");
14808       return -99;
14809     }
14810
14811   /* Construct the API message */
14812   M (GPE_ENABLE_DISABLE, mp);
14813
14814   mp->is_en = is_en;
14815
14816   /* send it... */
14817   S (mp);
14818
14819   /* Wait for a reply... */
14820   W (ret);
14821   return ret;
14822 }
14823
14824 static int
14825 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14826 {
14827   unformat_input_t *input = vam->input;
14828   vl_api_one_rloc_probe_enable_disable_t *mp;
14829   u8 is_set = 0;
14830   u8 is_en = 0;
14831   int ret;
14832
14833   /* Parse args required to build the message */
14834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14835     {
14836       if (unformat (input, "enable"))
14837         {
14838           is_set = 1;
14839           is_en = 1;
14840         }
14841       else if (unformat (input, "disable"))
14842         is_set = 1;
14843       else
14844         break;
14845     }
14846
14847   if (!is_set)
14848     {
14849       errmsg ("Value not set");
14850       return -99;
14851     }
14852
14853   /* Construct the API message */
14854   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14855
14856   mp->is_enabled = is_en;
14857
14858   /* send it... */
14859   S (mp);
14860
14861   /* Wait for a reply... */
14862   W (ret);
14863   return ret;
14864 }
14865
14866 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14867
14868 static int
14869 api_one_map_register_enable_disable (vat_main_t * vam)
14870 {
14871   unformat_input_t *input = vam->input;
14872   vl_api_one_map_register_enable_disable_t *mp;
14873   u8 is_set = 0;
14874   u8 is_en = 0;
14875   int ret;
14876
14877   /* Parse args required to build the message */
14878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14879     {
14880       if (unformat (input, "enable"))
14881         {
14882           is_set = 1;
14883           is_en = 1;
14884         }
14885       else if (unformat (input, "disable"))
14886         is_set = 1;
14887       else
14888         break;
14889     }
14890
14891   if (!is_set)
14892     {
14893       errmsg ("Value not set");
14894       return -99;
14895     }
14896
14897   /* Construct the API message */
14898   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14899
14900   mp->is_enabled = is_en;
14901
14902   /* send it... */
14903   S (mp);
14904
14905   /* Wait for a reply... */
14906   W (ret);
14907   return ret;
14908 }
14909
14910 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14911
14912 static int
14913 api_one_enable_disable (vat_main_t * vam)
14914 {
14915   unformat_input_t *input = vam->input;
14916   vl_api_one_enable_disable_t *mp;
14917   u8 is_set = 0;
14918   u8 is_en = 0;
14919   int ret;
14920
14921   /* Parse args required to build the message */
14922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (input, "enable"))
14925         {
14926           is_set = 1;
14927           is_en = 1;
14928         }
14929       else if (unformat (input, "disable"))
14930         {
14931           is_set = 1;
14932         }
14933       else
14934         break;
14935     }
14936
14937   if (!is_set)
14938     {
14939       errmsg ("Value not set");
14940       return -99;
14941     }
14942
14943   /* Construct the API message */
14944   M (ONE_ENABLE_DISABLE, mp);
14945
14946   mp->is_en = is_en;
14947
14948   /* send it... */
14949   S (mp);
14950
14951   /* Wait for a reply... */
14952   W (ret);
14953   return ret;
14954 }
14955
14956 #define api_lisp_enable_disable api_one_enable_disable
14957
14958 static int
14959 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14960 {
14961   unformat_input_t *input = vam->input;
14962   vl_api_one_enable_disable_xtr_mode_t *mp;
14963   u8 is_set = 0;
14964   u8 is_en = 0;
14965   int ret;
14966
14967   /* Parse args required to build the message */
14968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14969     {
14970       if (unformat (input, "enable"))
14971         {
14972           is_set = 1;
14973           is_en = 1;
14974         }
14975       else if (unformat (input, "disable"))
14976         {
14977           is_set = 1;
14978         }
14979       else
14980         break;
14981     }
14982
14983   if (!is_set)
14984     {
14985       errmsg ("Value not set");
14986       return -99;
14987     }
14988
14989   /* Construct the API message */
14990   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14991
14992   mp->is_en = is_en;
14993
14994   /* send it... */
14995   S (mp);
14996
14997   /* Wait for a reply... */
14998   W (ret);
14999   return ret;
15000 }
15001
15002 static int
15003 api_one_show_xtr_mode (vat_main_t * vam)
15004 {
15005   vl_api_one_show_xtr_mode_t *mp;
15006   int ret;
15007
15008   /* Construct the API message */
15009   M (ONE_SHOW_XTR_MODE, mp);
15010
15011   /* send it... */
15012   S (mp);
15013
15014   /* Wait for a reply... */
15015   W (ret);
15016   return ret;
15017 }
15018
15019 static int
15020 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15021 {
15022   unformat_input_t *input = vam->input;
15023   vl_api_one_enable_disable_pitr_mode_t *mp;
15024   u8 is_set = 0;
15025   u8 is_en = 0;
15026   int ret;
15027
15028   /* Parse args required to build the message */
15029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15030     {
15031       if (unformat (input, "enable"))
15032         {
15033           is_set = 1;
15034           is_en = 1;
15035         }
15036       else if (unformat (input, "disable"))
15037         {
15038           is_set = 1;
15039         }
15040       else
15041         break;
15042     }
15043
15044   if (!is_set)
15045     {
15046       errmsg ("Value not set");
15047       return -99;
15048     }
15049
15050   /* Construct the API message */
15051   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15052
15053   mp->is_en = is_en;
15054
15055   /* send it... */
15056   S (mp);
15057
15058   /* Wait for a reply... */
15059   W (ret);
15060   return ret;
15061 }
15062
15063 static int
15064 api_one_show_pitr_mode (vat_main_t * vam)
15065 {
15066   vl_api_one_show_pitr_mode_t *mp;
15067   int ret;
15068
15069   /* Construct the API message */
15070   M (ONE_SHOW_PITR_MODE, mp);
15071
15072   /* send it... */
15073   S (mp);
15074
15075   /* Wait for a reply... */
15076   W (ret);
15077   return ret;
15078 }
15079
15080 static int
15081 api_one_enable_disable_petr_mode (vat_main_t * vam)
15082 {
15083   unformat_input_t *input = vam->input;
15084   vl_api_one_enable_disable_petr_mode_t *mp;
15085   u8 is_set = 0;
15086   u8 is_en = 0;
15087   int ret;
15088
15089   /* Parse args required to build the message */
15090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15091     {
15092       if (unformat (input, "enable"))
15093         {
15094           is_set = 1;
15095           is_en = 1;
15096         }
15097       else if (unformat (input, "disable"))
15098         {
15099           is_set = 1;
15100         }
15101       else
15102         break;
15103     }
15104
15105   if (!is_set)
15106     {
15107       errmsg ("Value not set");
15108       return -99;
15109     }
15110
15111   /* Construct the API message */
15112   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15113
15114   mp->is_en = is_en;
15115
15116   /* send it... */
15117   S (mp);
15118
15119   /* Wait for a reply... */
15120   W (ret);
15121   return ret;
15122 }
15123
15124 static int
15125 api_one_show_petr_mode (vat_main_t * vam)
15126 {
15127   vl_api_one_show_petr_mode_t *mp;
15128   int ret;
15129
15130   /* Construct the API message */
15131   M (ONE_SHOW_PETR_MODE, mp);
15132
15133   /* send it... */
15134   S (mp);
15135
15136   /* Wait for a reply... */
15137   W (ret);
15138   return ret;
15139 }
15140
15141 static int
15142 api_show_one_map_register_state (vat_main_t * vam)
15143 {
15144   vl_api_show_one_map_register_state_t *mp;
15145   int ret;
15146
15147   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15148
15149   /* send */
15150   S (mp);
15151
15152   /* wait for reply */
15153   W (ret);
15154   return ret;
15155 }
15156
15157 #define api_show_lisp_map_register_state api_show_one_map_register_state
15158
15159 static int
15160 api_show_one_rloc_probe_state (vat_main_t * vam)
15161 {
15162   vl_api_show_one_rloc_probe_state_t *mp;
15163   int ret;
15164
15165   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15166
15167   /* send */
15168   S (mp);
15169
15170   /* wait for reply */
15171   W (ret);
15172   return ret;
15173 }
15174
15175 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15176
15177 static int
15178 api_one_add_del_ndp_entry (vat_main_t * vam)
15179 {
15180   vl_api_one_add_del_ndp_entry_t *mp;
15181   unformat_input_t *input = vam->input;
15182   u8 is_add = 1;
15183   u8 mac_set = 0;
15184   u8 bd_set = 0;
15185   u8 ip_set = 0;
15186   u8 mac[6] = { 0, };
15187   u8 ip6[16] = { 0, };
15188   u32 bd = ~0;
15189   int ret;
15190
15191   /* Parse args required to build the message */
15192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15193     {
15194       if (unformat (input, "del"))
15195         is_add = 0;
15196       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15197         mac_set = 1;
15198       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15199         ip_set = 1;
15200       else if (unformat (input, "bd %d", &bd))
15201         bd_set = 1;
15202       else
15203         {
15204           errmsg ("parse error '%U'", format_unformat_error, input);
15205           return -99;
15206         }
15207     }
15208
15209   if (!bd_set || !ip_set || (!mac_set && is_add))
15210     {
15211       errmsg ("Missing BD, IP or MAC!");
15212       return -99;
15213     }
15214
15215   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15216   mp->is_add = is_add;
15217   clib_memcpy (mp->mac, mac, 6);
15218   mp->bd = clib_host_to_net_u32 (bd);
15219   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15220
15221   /* send */
15222   S (mp);
15223
15224   /* wait for reply */
15225   W (ret);
15226   return ret;
15227 }
15228
15229 static int
15230 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15231 {
15232   vl_api_one_add_del_l2_arp_entry_t *mp;
15233   unformat_input_t *input = vam->input;
15234   u8 is_add = 1;
15235   u8 mac_set = 0;
15236   u8 bd_set = 0;
15237   u8 ip_set = 0;
15238   u8 mac[6] = { 0, };
15239   u32 ip4 = 0, bd = ~0;
15240   int ret;
15241
15242   /* Parse args required to build the message */
15243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15244     {
15245       if (unformat (input, "del"))
15246         is_add = 0;
15247       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15248         mac_set = 1;
15249       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15250         ip_set = 1;
15251       else if (unformat (input, "bd %d", &bd))
15252         bd_set = 1;
15253       else
15254         {
15255           errmsg ("parse error '%U'", format_unformat_error, input);
15256           return -99;
15257         }
15258     }
15259
15260   if (!bd_set || !ip_set || (!mac_set && is_add))
15261     {
15262       errmsg ("Missing BD, IP or MAC!");
15263       return -99;
15264     }
15265
15266   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15267   mp->is_add = is_add;
15268   clib_memcpy (mp->mac, mac, 6);
15269   mp->bd = clib_host_to_net_u32 (bd);
15270   mp->ip4 = ip4;
15271
15272   /* send */
15273   S (mp);
15274
15275   /* wait for reply */
15276   W (ret);
15277   return ret;
15278 }
15279
15280 static int
15281 api_one_ndp_bd_get (vat_main_t * vam)
15282 {
15283   vl_api_one_ndp_bd_get_t *mp;
15284   int ret;
15285
15286   M (ONE_NDP_BD_GET, mp);
15287
15288   /* send */
15289   S (mp);
15290
15291   /* wait for reply */
15292   W (ret);
15293   return ret;
15294 }
15295
15296 static int
15297 api_one_ndp_entries_get (vat_main_t * vam)
15298 {
15299   vl_api_one_ndp_entries_get_t *mp;
15300   unformat_input_t *input = vam->input;
15301   u8 bd_set = 0;
15302   u32 bd = ~0;
15303   int ret;
15304
15305   /* Parse args required to build the message */
15306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15307     {
15308       if (unformat (input, "bd %d", &bd))
15309         bd_set = 1;
15310       else
15311         {
15312           errmsg ("parse error '%U'", format_unformat_error, input);
15313           return -99;
15314         }
15315     }
15316
15317   if (!bd_set)
15318     {
15319       errmsg ("Expected bridge domain!");
15320       return -99;
15321     }
15322
15323   M (ONE_NDP_ENTRIES_GET, mp);
15324   mp->bd = clib_host_to_net_u32 (bd);
15325
15326   /* send */
15327   S (mp);
15328
15329   /* wait for reply */
15330   W (ret);
15331   return ret;
15332 }
15333
15334 static int
15335 api_one_l2_arp_bd_get (vat_main_t * vam)
15336 {
15337   vl_api_one_l2_arp_bd_get_t *mp;
15338   int ret;
15339
15340   M (ONE_L2_ARP_BD_GET, mp);
15341
15342   /* send */
15343   S (mp);
15344
15345   /* wait for reply */
15346   W (ret);
15347   return ret;
15348 }
15349
15350 static int
15351 api_one_l2_arp_entries_get (vat_main_t * vam)
15352 {
15353   vl_api_one_l2_arp_entries_get_t *mp;
15354   unformat_input_t *input = vam->input;
15355   u8 bd_set = 0;
15356   u32 bd = ~0;
15357   int ret;
15358
15359   /* Parse args required to build the message */
15360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15361     {
15362       if (unformat (input, "bd %d", &bd))
15363         bd_set = 1;
15364       else
15365         {
15366           errmsg ("parse error '%U'", format_unformat_error, input);
15367           return -99;
15368         }
15369     }
15370
15371   if (!bd_set)
15372     {
15373       errmsg ("Expected bridge domain!");
15374       return -99;
15375     }
15376
15377   M (ONE_L2_ARP_ENTRIES_GET, mp);
15378   mp->bd = clib_host_to_net_u32 (bd);
15379
15380   /* send */
15381   S (mp);
15382
15383   /* wait for reply */
15384   W (ret);
15385   return ret;
15386 }
15387
15388 static int
15389 api_one_stats_enable_disable (vat_main_t * vam)
15390 {
15391   vl_api_one_stats_enable_disable_t *mp;
15392   unformat_input_t *input = vam->input;
15393   u8 is_set = 0;
15394   u8 is_en = 0;
15395   int ret;
15396
15397   /* Parse args required to build the message */
15398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15399     {
15400       if (unformat (input, "enable"))
15401         {
15402           is_set = 1;
15403           is_en = 1;
15404         }
15405       else if (unformat (input, "disable"))
15406         {
15407           is_set = 1;
15408         }
15409       else
15410         break;
15411     }
15412
15413   if (!is_set)
15414     {
15415       errmsg ("Value not set");
15416       return -99;
15417     }
15418
15419   M (ONE_STATS_ENABLE_DISABLE, mp);
15420   mp->is_en = is_en;
15421
15422   /* send */
15423   S (mp);
15424
15425   /* wait for reply */
15426   W (ret);
15427   return ret;
15428 }
15429
15430 static int
15431 api_show_one_stats_enable_disable (vat_main_t * vam)
15432 {
15433   vl_api_show_one_stats_enable_disable_t *mp;
15434   int ret;
15435
15436   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15437
15438   /* send */
15439   S (mp);
15440
15441   /* wait for reply */
15442   W (ret);
15443   return ret;
15444 }
15445
15446 static int
15447 api_show_one_map_request_mode (vat_main_t * vam)
15448 {
15449   vl_api_show_one_map_request_mode_t *mp;
15450   int ret;
15451
15452   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15453
15454   /* send */
15455   S (mp);
15456
15457   /* wait for reply */
15458   W (ret);
15459   return ret;
15460 }
15461
15462 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15463
15464 static int
15465 api_one_map_request_mode (vat_main_t * vam)
15466 {
15467   unformat_input_t *input = vam->input;
15468   vl_api_one_map_request_mode_t *mp;
15469   u8 mode = 0;
15470   int ret;
15471
15472   /* Parse args required to build the message */
15473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15474     {
15475       if (unformat (input, "dst-only"))
15476         mode = 0;
15477       else if (unformat (input, "src-dst"))
15478         mode = 1;
15479       else
15480         {
15481           errmsg ("parse error '%U'", format_unformat_error, input);
15482           return -99;
15483         }
15484     }
15485
15486   M (ONE_MAP_REQUEST_MODE, mp);
15487
15488   mp->mode = mode;
15489
15490   /* send */
15491   S (mp);
15492
15493   /* wait for reply */
15494   W (ret);
15495   return ret;
15496 }
15497
15498 #define api_lisp_map_request_mode api_one_map_request_mode
15499
15500 /**
15501  * Enable/disable ONE proxy ITR.
15502  *
15503  * @param vam vpp API test context
15504  * @return return code
15505  */
15506 static int
15507 api_one_pitr_set_locator_set (vat_main_t * vam)
15508 {
15509   u8 ls_name_set = 0;
15510   unformat_input_t *input = vam->input;
15511   vl_api_one_pitr_set_locator_set_t *mp;
15512   u8 is_add = 1;
15513   u8 *ls_name = 0;
15514   int ret;
15515
15516   /* Parse args required to build the message */
15517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15518     {
15519       if (unformat (input, "del"))
15520         is_add = 0;
15521       else if (unformat (input, "locator-set %s", &ls_name))
15522         ls_name_set = 1;
15523       else
15524         {
15525           errmsg ("parse error '%U'", format_unformat_error, input);
15526           return -99;
15527         }
15528     }
15529
15530   if (!ls_name_set)
15531     {
15532       errmsg ("locator-set name not set!");
15533       return -99;
15534     }
15535
15536   M (ONE_PITR_SET_LOCATOR_SET, mp);
15537
15538   mp->is_add = is_add;
15539   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15540   vec_free (ls_name);
15541
15542   /* send */
15543   S (mp);
15544
15545   /* wait for reply */
15546   W (ret);
15547   return ret;
15548 }
15549
15550 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15551
15552 static int
15553 api_one_nsh_set_locator_set (vat_main_t * vam)
15554 {
15555   u8 ls_name_set = 0;
15556   unformat_input_t *input = vam->input;
15557   vl_api_one_nsh_set_locator_set_t *mp;
15558   u8 is_add = 1;
15559   u8 *ls_name = 0;
15560   int ret;
15561
15562   /* Parse args required to build the message */
15563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15564     {
15565       if (unformat (input, "del"))
15566         is_add = 0;
15567       else if (unformat (input, "ls %s", &ls_name))
15568         ls_name_set = 1;
15569       else
15570         {
15571           errmsg ("parse error '%U'", format_unformat_error, input);
15572           return -99;
15573         }
15574     }
15575
15576   if (!ls_name_set && is_add)
15577     {
15578       errmsg ("locator-set name not set!");
15579       return -99;
15580     }
15581
15582   M (ONE_NSH_SET_LOCATOR_SET, mp);
15583
15584   mp->is_add = is_add;
15585   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15586   vec_free (ls_name);
15587
15588   /* send */
15589   S (mp);
15590
15591   /* wait for reply */
15592   W (ret);
15593   return ret;
15594 }
15595
15596 static int
15597 api_show_one_pitr (vat_main_t * vam)
15598 {
15599   vl_api_show_one_pitr_t *mp;
15600   int ret;
15601
15602   if (!vam->json_output)
15603     {
15604       print (vam->ofp, "%=20s", "lisp status:");
15605     }
15606
15607   M (SHOW_ONE_PITR, mp);
15608   /* send it... */
15609   S (mp);
15610
15611   /* Wait for a reply... */
15612   W (ret);
15613   return ret;
15614 }
15615
15616 #define api_show_lisp_pitr api_show_one_pitr
15617
15618 static int
15619 api_one_use_petr (vat_main_t * vam)
15620 {
15621   unformat_input_t *input = vam->input;
15622   vl_api_one_use_petr_t *mp;
15623   u8 is_add = 0;
15624   ip_address_t ip;
15625   int ret;
15626
15627   clib_memset (&ip, 0, sizeof (ip));
15628
15629   /* Parse args required to build the message */
15630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15631     {
15632       if (unformat (input, "disable"))
15633         is_add = 0;
15634       else
15635         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15636         {
15637           is_add = 1;
15638           ip_addr_version (&ip) = AF_IP4;
15639         }
15640       else
15641         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15642         {
15643           is_add = 1;
15644           ip_addr_version (&ip) = AF_IP6;
15645         }
15646       else
15647         {
15648           errmsg ("parse error '%U'", format_unformat_error, input);
15649           return -99;
15650         }
15651     }
15652
15653   M (ONE_USE_PETR, mp);
15654
15655   mp->is_add = is_add;
15656   if (is_add)
15657     {
15658       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15659       if (mp->is_ip4)
15660         clib_memcpy (mp->address, &ip, 4);
15661       else
15662         clib_memcpy (mp->address, &ip, 16);
15663     }
15664
15665   /* send */
15666   S (mp);
15667
15668   /* wait for reply */
15669   W (ret);
15670   return ret;
15671 }
15672
15673 #define api_lisp_use_petr api_one_use_petr
15674
15675 static int
15676 api_show_one_nsh_mapping (vat_main_t * vam)
15677 {
15678   vl_api_show_one_use_petr_t *mp;
15679   int ret;
15680
15681   if (!vam->json_output)
15682     {
15683       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15684     }
15685
15686   M (SHOW_ONE_NSH_MAPPING, mp);
15687   /* send it... */
15688   S (mp);
15689
15690   /* Wait for a reply... */
15691   W (ret);
15692   return ret;
15693 }
15694
15695 static int
15696 api_show_one_use_petr (vat_main_t * vam)
15697 {
15698   vl_api_show_one_use_petr_t *mp;
15699   int ret;
15700
15701   if (!vam->json_output)
15702     {
15703       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15704     }
15705
15706   M (SHOW_ONE_USE_PETR, mp);
15707   /* send it... */
15708   S (mp);
15709
15710   /* Wait for a reply... */
15711   W (ret);
15712   return ret;
15713 }
15714
15715 #define api_show_lisp_use_petr api_show_one_use_petr
15716
15717 /**
15718  * Add/delete mapping between vni and vrf
15719  */
15720 static int
15721 api_one_eid_table_add_del_map (vat_main_t * vam)
15722 {
15723   unformat_input_t *input = vam->input;
15724   vl_api_one_eid_table_add_del_map_t *mp;
15725   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15726   u32 vni, vrf, bd_index;
15727   int ret;
15728
15729   /* Parse args required to build the message */
15730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (input, "del"))
15733         is_add = 0;
15734       else if (unformat (input, "vrf %d", &vrf))
15735         vrf_set = 1;
15736       else if (unformat (input, "bd_index %d", &bd_index))
15737         bd_index_set = 1;
15738       else if (unformat (input, "vni %d", &vni))
15739         vni_set = 1;
15740       else
15741         break;
15742     }
15743
15744   if (!vni_set || (!vrf_set && !bd_index_set))
15745     {
15746       errmsg ("missing arguments!");
15747       return -99;
15748     }
15749
15750   if (vrf_set && bd_index_set)
15751     {
15752       errmsg ("error: both vrf and bd entered!");
15753       return -99;
15754     }
15755
15756   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15757
15758   mp->is_add = is_add;
15759   mp->vni = htonl (vni);
15760   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15761   mp->is_l2 = bd_index_set;
15762
15763   /* send */
15764   S (mp);
15765
15766   /* wait for reply */
15767   W (ret);
15768   return ret;
15769 }
15770
15771 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15772
15773 uword
15774 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15775 {
15776   u32 *action = va_arg (*args, u32 *);
15777   u8 *s = 0;
15778
15779   if (unformat (input, "%s", &s))
15780     {
15781       if (!strcmp ((char *) s, "no-action"))
15782         action[0] = 0;
15783       else if (!strcmp ((char *) s, "natively-forward"))
15784         action[0] = 1;
15785       else if (!strcmp ((char *) s, "send-map-request"))
15786         action[0] = 2;
15787       else if (!strcmp ((char *) s, "drop"))
15788         action[0] = 3;
15789       else
15790         {
15791           clib_warning ("invalid action: '%s'", s);
15792           action[0] = 3;
15793         }
15794     }
15795   else
15796     return 0;
15797
15798   vec_free (s);
15799   return 1;
15800 }
15801
15802 /**
15803  * Add/del remote mapping to/from ONE control plane
15804  *
15805  * @param vam vpp API test context
15806  * @return return code
15807  */
15808 static int
15809 api_one_add_del_remote_mapping (vat_main_t * vam)
15810 {
15811   unformat_input_t *input = vam->input;
15812   vl_api_one_add_del_remote_mapping_t *mp;
15813   u32 vni = 0;
15814   lisp_eid_vat_t _eid, *eid = &_eid;
15815   lisp_eid_vat_t _seid, *seid = &_seid;
15816   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15817   u32 action = ~0, p, w, data_len;
15818   ip4_address_t rloc4;
15819   ip6_address_t rloc6;
15820   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15821   int ret;
15822
15823   clib_memset (&rloc, 0, sizeof (rloc));
15824
15825   /* Parse args required to build the message */
15826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15827     {
15828       if (unformat (input, "del-all"))
15829         {
15830           del_all = 1;
15831         }
15832       else if (unformat (input, "del"))
15833         {
15834           is_add = 0;
15835         }
15836       else if (unformat (input, "add"))
15837         {
15838           is_add = 1;
15839         }
15840       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15841         {
15842           eid_set = 1;
15843         }
15844       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15845         {
15846           seid_set = 1;
15847         }
15848       else if (unformat (input, "vni %d", &vni))
15849         {
15850           ;
15851         }
15852       else if (unformat (input, "p %d w %d", &p, &w))
15853         {
15854           if (!curr_rloc)
15855             {
15856               errmsg ("No RLOC configured for setting priority/weight!");
15857               return -99;
15858             }
15859           curr_rloc->priority = p;
15860           curr_rloc->weight = w;
15861         }
15862       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15863         {
15864           rloc.is_ip4 = 1;
15865           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15866           vec_add1 (rlocs, rloc);
15867           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15868         }
15869       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15870         {
15871           rloc.is_ip4 = 0;
15872           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15873           vec_add1 (rlocs, rloc);
15874           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15875         }
15876       else if (unformat (input, "action %U",
15877                          unformat_negative_mapping_action, &action))
15878         {
15879           ;
15880         }
15881       else
15882         {
15883           clib_warning ("parse error '%U'", format_unformat_error, input);
15884           return -99;
15885         }
15886     }
15887
15888   if (0 == eid_set)
15889     {
15890       errmsg ("missing params!");
15891       return -99;
15892     }
15893
15894   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15895     {
15896       errmsg ("no action set for negative map-reply!");
15897       return -99;
15898     }
15899
15900   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15901
15902   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15903   mp->is_add = is_add;
15904   mp->vni = htonl (vni);
15905   mp->action = (u8) action;
15906   mp->is_src_dst = seid_set;
15907   mp->eid_len = eid->len;
15908   mp->seid_len = seid->len;
15909   mp->del_all = del_all;
15910   mp->eid_type = eid->type;
15911   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15912   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15913
15914   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15915   clib_memcpy (mp->rlocs, rlocs, data_len);
15916   vec_free (rlocs);
15917
15918   /* send it... */
15919   S (mp);
15920
15921   /* Wait for a reply... */
15922   W (ret);
15923   return ret;
15924 }
15925
15926 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15927
15928 /**
15929  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15930  * forwarding entries in data-plane accordingly.
15931  *
15932  * @param vam vpp API test context
15933  * @return return code
15934  */
15935 static int
15936 api_one_add_del_adjacency (vat_main_t * vam)
15937 {
15938   unformat_input_t *input = vam->input;
15939   vl_api_one_add_del_adjacency_t *mp;
15940   u32 vni = 0;
15941   ip4_address_t leid4, reid4;
15942   ip6_address_t leid6, reid6;
15943   u8 reid_mac[6] = { 0 };
15944   u8 leid_mac[6] = { 0 };
15945   u8 reid_type, leid_type;
15946   u32 leid_len = 0, reid_len = 0, len;
15947   u8 is_add = 1;
15948   int ret;
15949
15950   leid_type = reid_type = (u8) ~ 0;
15951
15952   /* Parse args required to build the message */
15953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15954     {
15955       if (unformat (input, "del"))
15956         {
15957           is_add = 0;
15958         }
15959       else if (unformat (input, "add"))
15960         {
15961           is_add = 1;
15962         }
15963       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15964                          &reid4, &len))
15965         {
15966           reid_type = 0;        /* ipv4 */
15967           reid_len = len;
15968         }
15969       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15970                          &reid6, &len))
15971         {
15972           reid_type = 1;        /* ipv6 */
15973           reid_len = len;
15974         }
15975       else if (unformat (input, "reid %U", unformat_ethernet_address,
15976                          reid_mac))
15977         {
15978           reid_type = 2;        /* mac */
15979         }
15980       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15981                          &leid4, &len))
15982         {
15983           leid_type = 0;        /* ipv4 */
15984           leid_len = len;
15985         }
15986       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15987                          &leid6, &len))
15988         {
15989           leid_type = 1;        /* ipv6 */
15990           leid_len = len;
15991         }
15992       else if (unformat (input, "leid %U", unformat_ethernet_address,
15993                          leid_mac))
15994         {
15995           leid_type = 2;        /* mac */
15996         }
15997       else if (unformat (input, "vni %d", &vni))
15998         {
15999           ;
16000         }
16001       else
16002         {
16003           errmsg ("parse error '%U'", format_unformat_error, input);
16004           return -99;
16005         }
16006     }
16007
16008   if ((u8) ~ 0 == reid_type)
16009     {
16010       errmsg ("missing params!");
16011       return -99;
16012     }
16013
16014   if (leid_type != reid_type)
16015     {
16016       errmsg ("remote and local EIDs are of different types!");
16017       return -99;
16018     }
16019
16020   M (ONE_ADD_DEL_ADJACENCY, mp);
16021   mp->is_add = is_add;
16022   mp->vni = htonl (vni);
16023   mp->leid_len = leid_len;
16024   mp->reid_len = reid_len;
16025   mp->eid_type = reid_type;
16026
16027   switch (mp->eid_type)
16028     {
16029     case 0:
16030       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16031       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16032       break;
16033     case 1:
16034       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16035       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16036       break;
16037     case 2:
16038       clib_memcpy (mp->leid, leid_mac, 6);
16039       clib_memcpy (mp->reid, reid_mac, 6);
16040       break;
16041     default:
16042       errmsg ("unknown EID type %d!", mp->eid_type);
16043       return 0;
16044     }
16045
16046   /* send it... */
16047   S (mp);
16048
16049   /* Wait for a reply... */
16050   W (ret);
16051   return ret;
16052 }
16053
16054 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16055
16056 uword
16057 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16058 {
16059   u32 *mode = va_arg (*args, u32 *);
16060
16061   if (unformat (input, "lisp"))
16062     *mode = 0;
16063   else if (unformat (input, "vxlan"))
16064     *mode = 1;
16065   else
16066     return 0;
16067
16068   return 1;
16069 }
16070
16071 static int
16072 api_gpe_get_encap_mode (vat_main_t * vam)
16073 {
16074   vl_api_gpe_get_encap_mode_t *mp;
16075   int ret;
16076
16077   /* Construct the API message */
16078   M (GPE_GET_ENCAP_MODE, mp);
16079
16080   /* send it... */
16081   S (mp);
16082
16083   /* Wait for a reply... */
16084   W (ret);
16085   return ret;
16086 }
16087
16088 static int
16089 api_gpe_set_encap_mode (vat_main_t * vam)
16090 {
16091   unformat_input_t *input = vam->input;
16092   vl_api_gpe_set_encap_mode_t *mp;
16093   int ret;
16094   u32 mode = 0;
16095
16096   /* Parse args required to build the message */
16097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16100         ;
16101       else
16102         break;
16103     }
16104
16105   /* Construct the API message */
16106   M (GPE_SET_ENCAP_MODE, mp);
16107
16108   mp->mode = mode;
16109
16110   /* send it... */
16111   S (mp);
16112
16113   /* Wait for a reply... */
16114   W (ret);
16115   return ret;
16116 }
16117
16118 static int
16119 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16120 {
16121   unformat_input_t *input = vam->input;
16122   vl_api_gpe_add_del_iface_t *mp;
16123   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16124   u32 dp_table = 0, vni = 0;
16125   int ret;
16126
16127   /* Parse args required to build the message */
16128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16129     {
16130       if (unformat (input, "up"))
16131         {
16132           action_set = 1;
16133           is_add = 1;
16134         }
16135       else if (unformat (input, "down"))
16136         {
16137           action_set = 1;
16138           is_add = 0;
16139         }
16140       else if (unformat (input, "table_id %d", &dp_table))
16141         {
16142           dp_table_set = 1;
16143         }
16144       else if (unformat (input, "bd_id %d", &dp_table))
16145         {
16146           dp_table_set = 1;
16147           is_l2 = 1;
16148         }
16149       else if (unformat (input, "vni %d", &vni))
16150         {
16151           vni_set = 1;
16152         }
16153       else
16154         break;
16155     }
16156
16157   if (action_set == 0)
16158     {
16159       errmsg ("Action not set");
16160       return -99;
16161     }
16162   if (dp_table_set == 0 || vni_set == 0)
16163     {
16164       errmsg ("vni and dp_table must be set");
16165       return -99;
16166     }
16167
16168   /* Construct the API message */
16169   M (GPE_ADD_DEL_IFACE, mp);
16170
16171   mp->is_add = is_add;
16172   mp->dp_table = clib_host_to_net_u32 (dp_table);
16173   mp->is_l2 = is_l2;
16174   mp->vni = clib_host_to_net_u32 (vni);
16175
16176   /* send it... */
16177   S (mp);
16178
16179   /* Wait for a reply... */
16180   W (ret);
16181   return ret;
16182 }
16183
16184 static int
16185 api_one_map_register_fallback_threshold (vat_main_t * vam)
16186 {
16187   unformat_input_t *input = vam->input;
16188   vl_api_one_map_register_fallback_threshold_t *mp;
16189   u32 value = 0;
16190   u8 is_set = 0;
16191   int ret;
16192
16193   /* Parse args required to build the message */
16194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16195     {
16196       if (unformat (input, "%u", &value))
16197         is_set = 1;
16198       else
16199         {
16200           clib_warning ("parse error '%U'", format_unformat_error, input);
16201           return -99;
16202         }
16203     }
16204
16205   if (!is_set)
16206     {
16207       errmsg ("fallback threshold value is missing!");
16208       return -99;
16209     }
16210
16211   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16212   mp->value = clib_host_to_net_u32 (value);
16213
16214   /* send it... */
16215   S (mp);
16216
16217   /* Wait for a reply... */
16218   W (ret);
16219   return ret;
16220 }
16221
16222 static int
16223 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16224 {
16225   vl_api_show_one_map_register_fallback_threshold_t *mp;
16226   int ret;
16227
16228   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16229
16230   /* send it... */
16231   S (mp);
16232
16233   /* Wait for a reply... */
16234   W (ret);
16235   return ret;
16236 }
16237
16238 uword
16239 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16240 {
16241   u32 *proto = va_arg (*args, u32 *);
16242
16243   if (unformat (input, "udp"))
16244     *proto = 1;
16245   else if (unformat (input, "api"))
16246     *proto = 2;
16247   else
16248     return 0;
16249
16250   return 1;
16251 }
16252
16253 static int
16254 api_one_set_transport_protocol (vat_main_t * vam)
16255 {
16256   unformat_input_t *input = vam->input;
16257   vl_api_one_set_transport_protocol_t *mp;
16258   u8 is_set = 0;
16259   u32 protocol = 0;
16260   int ret;
16261
16262   /* Parse args required to build the message */
16263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16264     {
16265       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16266         is_set = 1;
16267       else
16268         {
16269           clib_warning ("parse error '%U'", format_unformat_error, input);
16270           return -99;
16271         }
16272     }
16273
16274   if (!is_set)
16275     {
16276       errmsg ("Transport protocol missing!");
16277       return -99;
16278     }
16279
16280   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16281   mp->protocol = (u8) protocol;
16282
16283   /* send it... */
16284   S (mp);
16285
16286   /* Wait for a reply... */
16287   W (ret);
16288   return ret;
16289 }
16290
16291 static int
16292 api_one_get_transport_protocol (vat_main_t * vam)
16293 {
16294   vl_api_one_get_transport_protocol_t *mp;
16295   int ret;
16296
16297   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16298
16299   /* send it... */
16300   S (mp);
16301
16302   /* Wait for a reply... */
16303   W (ret);
16304   return ret;
16305 }
16306
16307 static int
16308 api_one_map_register_set_ttl (vat_main_t * vam)
16309 {
16310   unformat_input_t *input = vam->input;
16311   vl_api_one_map_register_set_ttl_t *mp;
16312   u32 ttl = 0;
16313   u8 is_set = 0;
16314   int ret;
16315
16316   /* Parse args required to build the message */
16317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16318     {
16319       if (unformat (input, "%u", &ttl))
16320         is_set = 1;
16321       else
16322         {
16323           clib_warning ("parse error '%U'", format_unformat_error, input);
16324           return -99;
16325         }
16326     }
16327
16328   if (!is_set)
16329     {
16330       errmsg ("TTL value missing!");
16331       return -99;
16332     }
16333
16334   M (ONE_MAP_REGISTER_SET_TTL, mp);
16335   mp->ttl = clib_host_to_net_u32 (ttl);
16336
16337   /* send it... */
16338   S (mp);
16339
16340   /* Wait for a reply... */
16341   W (ret);
16342   return ret;
16343 }
16344
16345 static int
16346 api_show_one_map_register_ttl (vat_main_t * vam)
16347 {
16348   vl_api_show_one_map_register_ttl_t *mp;
16349   int ret;
16350
16351   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16352
16353   /* send it... */
16354   S (mp);
16355
16356   /* Wait for a reply... */
16357   W (ret);
16358   return ret;
16359 }
16360
16361 /**
16362  * Add/del map request itr rlocs from ONE control plane and updates
16363  *
16364  * @param vam vpp API test context
16365  * @return return code
16366  */
16367 static int
16368 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16369 {
16370   unformat_input_t *input = vam->input;
16371   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16372   u8 *locator_set_name = 0;
16373   u8 locator_set_name_set = 0;
16374   u8 is_add = 1;
16375   int ret;
16376
16377   /* Parse args required to build the message */
16378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16379     {
16380       if (unformat (input, "del"))
16381         {
16382           is_add = 0;
16383         }
16384       else if (unformat (input, "%_%v%_", &locator_set_name))
16385         {
16386           locator_set_name_set = 1;
16387         }
16388       else
16389         {
16390           clib_warning ("parse error '%U'", format_unformat_error, input);
16391           return -99;
16392         }
16393     }
16394
16395   if (is_add && !locator_set_name_set)
16396     {
16397       errmsg ("itr-rloc is not set!");
16398       return -99;
16399     }
16400
16401   if (is_add && vec_len (locator_set_name) > 64)
16402     {
16403       errmsg ("itr-rloc locator-set name too long");
16404       vec_free (locator_set_name);
16405       return -99;
16406     }
16407
16408   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16409   mp->is_add = is_add;
16410   if (is_add)
16411     {
16412       clib_memcpy (mp->locator_set_name, locator_set_name,
16413                    vec_len (locator_set_name));
16414     }
16415   else
16416     {
16417       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16418     }
16419   vec_free (locator_set_name);
16420
16421   /* send it... */
16422   S (mp);
16423
16424   /* Wait for a reply... */
16425   W (ret);
16426   return ret;
16427 }
16428
16429 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16430
16431 static int
16432 api_one_locator_dump (vat_main_t * vam)
16433 {
16434   unformat_input_t *input = vam->input;
16435   vl_api_one_locator_dump_t *mp;
16436   vl_api_control_ping_t *mp_ping;
16437   u8 is_index_set = 0, is_name_set = 0;
16438   u8 *ls_name = 0;
16439   u32 ls_index = ~0;
16440   int ret;
16441
16442   /* Parse args required to build the message */
16443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16444     {
16445       if (unformat (input, "ls_name %_%v%_", &ls_name))
16446         {
16447           is_name_set = 1;
16448         }
16449       else if (unformat (input, "ls_index %d", &ls_index))
16450         {
16451           is_index_set = 1;
16452         }
16453       else
16454         {
16455           errmsg ("parse error '%U'", format_unformat_error, input);
16456           return -99;
16457         }
16458     }
16459
16460   if (!is_index_set && !is_name_set)
16461     {
16462       errmsg ("error: expected one of index or name!");
16463       return -99;
16464     }
16465
16466   if (is_index_set && is_name_set)
16467     {
16468       errmsg ("error: only one param expected!");
16469       return -99;
16470     }
16471
16472   if (vec_len (ls_name) > 62)
16473     {
16474       errmsg ("error: locator set name too long!");
16475       return -99;
16476     }
16477
16478   if (!vam->json_output)
16479     {
16480       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16481     }
16482
16483   M (ONE_LOCATOR_DUMP, mp);
16484   mp->is_index_set = is_index_set;
16485
16486   if (is_index_set)
16487     mp->ls_index = clib_host_to_net_u32 (ls_index);
16488   else
16489     {
16490       vec_add1 (ls_name, 0);
16491       strncpy ((char *) mp->ls_name, (char *) ls_name,
16492                sizeof (mp->ls_name) - 1);
16493     }
16494
16495   /* send it... */
16496   S (mp);
16497
16498   /* Use a control ping for synchronization */
16499   MPING (CONTROL_PING, mp_ping);
16500   S (mp_ping);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 #define api_lisp_locator_dump api_one_locator_dump
16508
16509 static int
16510 api_one_locator_set_dump (vat_main_t * vam)
16511 {
16512   vl_api_one_locator_set_dump_t *mp;
16513   vl_api_control_ping_t *mp_ping;
16514   unformat_input_t *input = vam->input;
16515   u8 filter = 0;
16516   int ret;
16517
16518   /* Parse args required to build the message */
16519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16520     {
16521       if (unformat (input, "local"))
16522         {
16523           filter = 1;
16524         }
16525       else if (unformat (input, "remote"))
16526         {
16527           filter = 2;
16528         }
16529       else
16530         {
16531           errmsg ("parse error '%U'", format_unformat_error, input);
16532           return -99;
16533         }
16534     }
16535
16536   if (!vam->json_output)
16537     {
16538       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16539     }
16540
16541   M (ONE_LOCATOR_SET_DUMP, mp);
16542
16543   mp->filter = filter;
16544
16545   /* send it... */
16546   S (mp);
16547
16548   /* Use a control ping for synchronization */
16549   MPING (CONTROL_PING, mp_ping);
16550   S (mp_ping);
16551
16552   /* Wait for a reply... */
16553   W (ret);
16554   return ret;
16555 }
16556
16557 #define api_lisp_locator_set_dump api_one_locator_set_dump
16558
16559 static int
16560 api_one_eid_table_map_dump (vat_main_t * vam)
16561 {
16562   u8 is_l2 = 0;
16563   u8 mode_set = 0;
16564   unformat_input_t *input = vam->input;
16565   vl_api_one_eid_table_map_dump_t *mp;
16566   vl_api_control_ping_t *mp_ping;
16567   int ret;
16568
16569   /* Parse args required to build the message */
16570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16571     {
16572       if (unformat (input, "l2"))
16573         {
16574           is_l2 = 1;
16575           mode_set = 1;
16576         }
16577       else if (unformat (input, "l3"))
16578         {
16579           is_l2 = 0;
16580           mode_set = 1;
16581         }
16582       else
16583         {
16584           errmsg ("parse error '%U'", format_unformat_error, input);
16585           return -99;
16586         }
16587     }
16588
16589   if (!mode_set)
16590     {
16591       errmsg ("expected one of 'l2' or 'l3' parameter!");
16592       return -99;
16593     }
16594
16595   if (!vam->json_output)
16596     {
16597       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16598     }
16599
16600   M (ONE_EID_TABLE_MAP_DUMP, mp);
16601   mp->is_l2 = is_l2;
16602
16603   /* send it... */
16604   S (mp);
16605
16606   /* Use a control ping for synchronization */
16607   MPING (CONTROL_PING, mp_ping);
16608   S (mp_ping);
16609
16610   /* Wait for a reply... */
16611   W (ret);
16612   return ret;
16613 }
16614
16615 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16616
16617 static int
16618 api_one_eid_table_vni_dump (vat_main_t * vam)
16619 {
16620   vl_api_one_eid_table_vni_dump_t *mp;
16621   vl_api_control_ping_t *mp_ping;
16622   int ret;
16623
16624   if (!vam->json_output)
16625     {
16626       print (vam->ofp, "VNI");
16627     }
16628
16629   M (ONE_EID_TABLE_VNI_DUMP, mp);
16630
16631   /* send it... */
16632   S (mp);
16633
16634   /* Use a control ping for synchronization */
16635   MPING (CONTROL_PING, mp_ping);
16636   S (mp_ping);
16637
16638   /* Wait for a reply... */
16639   W (ret);
16640   return ret;
16641 }
16642
16643 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16644
16645 static int
16646 api_one_eid_table_dump (vat_main_t * vam)
16647 {
16648   unformat_input_t *i = vam->input;
16649   vl_api_one_eid_table_dump_t *mp;
16650   vl_api_control_ping_t *mp_ping;
16651   struct in_addr ip4;
16652   struct in6_addr ip6;
16653   u8 mac[6];
16654   u8 eid_type = ~0, eid_set = 0;
16655   u32 prefix_length = ~0, t, vni = 0;
16656   u8 filter = 0;
16657   int ret;
16658   lisp_nsh_api_t nsh;
16659
16660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16663         {
16664           eid_set = 1;
16665           eid_type = 0;
16666           prefix_length = t;
16667         }
16668       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16669         {
16670           eid_set = 1;
16671           eid_type = 1;
16672           prefix_length = t;
16673         }
16674       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16675         {
16676           eid_set = 1;
16677           eid_type = 2;
16678         }
16679       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16680         {
16681           eid_set = 1;
16682           eid_type = 3;
16683         }
16684       else if (unformat (i, "vni %d", &t))
16685         {
16686           vni = t;
16687         }
16688       else if (unformat (i, "local"))
16689         {
16690           filter = 1;
16691         }
16692       else if (unformat (i, "remote"))
16693         {
16694           filter = 2;
16695         }
16696       else
16697         {
16698           errmsg ("parse error '%U'", format_unformat_error, i);
16699           return -99;
16700         }
16701     }
16702
16703   if (!vam->json_output)
16704     {
16705       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16706              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16707     }
16708
16709   M (ONE_EID_TABLE_DUMP, mp);
16710
16711   mp->filter = filter;
16712   if (eid_set)
16713     {
16714       mp->eid_set = 1;
16715       mp->vni = htonl (vni);
16716       mp->eid_type = eid_type;
16717       switch (eid_type)
16718         {
16719         case 0:
16720           mp->prefix_length = prefix_length;
16721           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16722           break;
16723         case 1:
16724           mp->prefix_length = prefix_length;
16725           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16726           break;
16727         case 2:
16728           clib_memcpy (mp->eid, mac, sizeof (mac));
16729           break;
16730         case 3:
16731           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16732           break;
16733         default:
16734           errmsg ("unknown EID type %d!", eid_type);
16735           return -99;
16736         }
16737     }
16738
16739   /* send it... */
16740   S (mp);
16741
16742   /* Use a control ping for synchronization */
16743   MPING (CONTROL_PING, mp_ping);
16744   S (mp_ping);
16745
16746   /* Wait for a reply... */
16747   W (ret);
16748   return ret;
16749 }
16750
16751 #define api_lisp_eid_table_dump api_one_eid_table_dump
16752
16753 static int
16754 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16755 {
16756   unformat_input_t *i = vam->input;
16757   vl_api_gpe_fwd_entries_get_t *mp;
16758   u8 vni_set = 0;
16759   u32 vni = ~0;
16760   int ret;
16761
16762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16763     {
16764       if (unformat (i, "vni %d", &vni))
16765         {
16766           vni_set = 1;
16767         }
16768       else
16769         {
16770           errmsg ("parse error '%U'", format_unformat_error, i);
16771           return -99;
16772         }
16773     }
16774
16775   if (!vni_set)
16776     {
16777       errmsg ("vni not set!");
16778       return -99;
16779     }
16780
16781   if (!vam->json_output)
16782     {
16783       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16784              "leid", "reid");
16785     }
16786
16787   M (GPE_FWD_ENTRIES_GET, mp);
16788   mp->vni = clib_host_to_net_u32 (vni);
16789
16790   /* send it... */
16791   S (mp);
16792
16793   /* Wait for a reply... */
16794   W (ret);
16795   return ret;
16796 }
16797
16798 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16799 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16800 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16801 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16802 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16803 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16804 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16805 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16806
16807 static int
16808 api_one_adjacencies_get (vat_main_t * vam)
16809 {
16810   unformat_input_t *i = vam->input;
16811   vl_api_one_adjacencies_get_t *mp;
16812   u8 vni_set = 0;
16813   u32 vni = ~0;
16814   int ret;
16815
16816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16817     {
16818       if (unformat (i, "vni %d", &vni))
16819         {
16820           vni_set = 1;
16821         }
16822       else
16823         {
16824           errmsg ("parse error '%U'", format_unformat_error, i);
16825           return -99;
16826         }
16827     }
16828
16829   if (!vni_set)
16830     {
16831       errmsg ("vni not set!");
16832       return -99;
16833     }
16834
16835   if (!vam->json_output)
16836     {
16837       print (vam->ofp, "%s %40s", "leid", "reid");
16838     }
16839
16840   M (ONE_ADJACENCIES_GET, mp);
16841   mp->vni = clib_host_to_net_u32 (vni);
16842
16843   /* send it... */
16844   S (mp);
16845
16846   /* Wait for a reply... */
16847   W (ret);
16848   return ret;
16849 }
16850
16851 #define api_lisp_adjacencies_get api_one_adjacencies_get
16852
16853 static int
16854 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16855 {
16856   unformat_input_t *i = vam->input;
16857   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16858   int ret;
16859   u8 ip_family_set = 0, is_ip4 = 1;
16860
16861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16862     {
16863       if (unformat (i, "ip4"))
16864         {
16865           ip_family_set = 1;
16866           is_ip4 = 1;
16867         }
16868       else if (unformat (i, "ip6"))
16869         {
16870           ip_family_set = 1;
16871           is_ip4 = 0;
16872         }
16873       else
16874         {
16875           errmsg ("parse error '%U'", format_unformat_error, i);
16876           return -99;
16877         }
16878     }
16879
16880   if (!ip_family_set)
16881     {
16882       errmsg ("ip family not set!");
16883       return -99;
16884     }
16885
16886   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16887   mp->is_ip4 = is_ip4;
16888
16889   /* send it... */
16890   S (mp);
16891
16892   /* Wait for a reply... */
16893   W (ret);
16894   return ret;
16895 }
16896
16897 static int
16898 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16899 {
16900   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16901   int ret;
16902
16903   if (!vam->json_output)
16904     {
16905       print (vam->ofp, "VNIs");
16906     }
16907
16908   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16909
16910   /* send it... */
16911   S (mp);
16912
16913   /* Wait for a reply... */
16914   W (ret);
16915   return ret;
16916 }
16917
16918 static int
16919 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16920 {
16921   unformat_input_t *i = vam->input;
16922   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16923   int ret = 0;
16924   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16925   struct in_addr ip4;
16926   struct in6_addr ip6;
16927   u32 table_id = 0, nh_sw_if_index = ~0;
16928
16929   clib_memset (&ip4, 0, sizeof (ip4));
16930   clib_memset (&ip6, 0, sizeof (ip6));
16931
16932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16933     {
16934       if (unformat (i, "del"))
16935         is_add = 0;
16936       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16937                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16938         {
16939           ip_set = 1;
16940           is_ip4 = 1;
16941         }
16942       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16943                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16944         {
16945           ip_set = 1;
16946           is_ip4 = 0;
16947         }
16948       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16949         {
16950           ip_set = 1;
16951           is_ip4 = 1;
16952           nh_sw_if_index = ~0;
16953         }
16954       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16955         {
16956           ip_set = 1;
16957           is_ip4 = 0;
16958           nh_sw_if_index = ~0;
16959         }
16960       else if (unformat (i, "table %d", &table_id))
16961         ;
16962       else
16963         {
16964           errmsg ("parse error '%U'", format_unformat_error, i);
16965           return -99;
16966         }
16967     }
16968
16969   if (!ip_set)
16970     {
16971       errmsg ("nh addr not set!");
16972       return -99;
16973     }
16974
16975   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16976   mp->is_add = is_add;
16977   mp->table_id = clib_host_to_net_u32 (table_id);
16978   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16979   mp->is_ip4 = is_ip4;
16980   if (is_ip4)
16981     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16982   else
16983     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16984
16985   /* send it... */
16986   S (mp);
16987
16988   /* Wait for a reply... */
16989   W (ret);
16990   return ret;
16991 }
16992
16993 static int
16994 api_one_map_server_dump (vat_main_t * vam)
16995 {
16996   vl_api_one_map_server_dump_t *mp;
16997   vl_api_control_ping_t *mp_ping;
16998   int ret;
16999
17000   if (!vam->json_output)
17001     {
17002       print (vam->ofp, "%=20s", "Map server");
17003     }
17004
17005   M (ONE_MAP_SERVER_DUMP, mp);
17006   /* send it... */
17007   S (mp);
17008
17009   /* Use a control ping for synchronization */
17010   MPING (CONTROL_PING, mp_ping);
17011   S (mp_ping);
17012
17013   /* Wait for a reply... */
17014   W (ret);
17015   return ret;
17016 }
17017
17018 #define api_lisp_map_server_dump api_one_map_server_dump
17019
17020 static int
17021 api_one_map_resolver_dump (vat_main_t * vam)
17022 {
17023   vl_api_one_map_resolver_dump_t *mp;
17024   vl_api_control_ping_t *mp_ping;
17025   int ret;
17026
17027   if (!vam->json_output)
17028     {
17029       print (vam->ofp, "%=20s", "Map resolver");
17030     }
17031
17032   M (ONE_MAP_RESOLVER_DUMP, mp);
17033   /* send it... */
17034   S (mp);
17035
17036   /* Use a control ping for synchronization */
17037   MPING (CONTROL_PING, mp_ping);
17038   S (mp_ping);
17039
17040   /* Wait for a reply... */
17041   W (ret);
17042   return ret;
17043 }
17044
17045 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17046
17047 static int
17048 api_one_stats_flush (vat_main_t * vam)
17049 {
17050   vl_api_one_stats_flush_t *mp;
17051   int ret = 0;
17052
17053   M (ONE_STATS_FLUSH, mp);
17054   S (mp);
17055   W (ret);
17056   return ret;
17057 }
17058
17059 static int
17060 api_one_stats_dump (vat_main_t * vam)
17061 {
17062   vl_api_one_stats_dump_t *mp;
17063   vl_api_control_ping_t *mp_ping;
17064   int ret;
17065
17066   M (ONE_STATS_DUMP, mp);
17067   /* send it... */
17068   S (mp);
17069
17070   /* Use a control ping for synchronization */
17071   MPING (CONTROL_PING, mp_ping);
17072   S (mp_ping);
17073
17074   /* Wait for a reply... */
17075   W (ret);
17076   return ret;
17077 }
17078
17079 static int
17080 api_show_one_status (vat_main_t * vam)
17081 {
17082   vl_api_show_one_status_t *mp;
17083   int ret;
17084
17085   if (!vam->json_output)
17086     {
17087       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17088     }
17089
17090   M (SHOW_ONE_STATUS, mp);
17091   /* send it... */
17092   S (mp);
17093   /* Wait for a reply... */
17094   W (ret);
17095   return ret;
17096 }
17097
17098 #define api_show_lisp_status api_show_one_status
17099
17100 static int
17101 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17102 {
17103   vl_api_gpe_fwd_entry_path_dump_t *mp;
17104   vl_api_control_ping_t *mp_ping;
17105   unformat_input_t *i = vam->input;
17106   u32 fwd_entry_index = ~0;
17107   int ret;
17108
17109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17110     {
17111       if (unformat (i, "index %d", &fwd_entry_index))
17112         ;
17113       else
17114         break;
17115     }
17116
17117   if (~0 == fwd_entry_index)
17118     {
17119       errmsg ("no index specified!");
17120       return -99;
17121     }
17122
17123   if (!vam->json_output)
17124     {
17125       print (vam->ofp, "first line");
17126     }
17127
17128   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17129
17130   /* send it... */
17131   S (mp);
17132   /* Use a control ping for synchronization */
17133   MPING (CONTROL_PING, mp_ping);
17134   S (mp_ping);
17135
17136   /* Wait for a reply... */
17137   W (ret);
17138   return ret;
17139 }
17140
17141 static int
17142 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17143 {
17144   vl_api_one_get_map_request_itr_rlocs_t *mp;
17145   int ret;
17146
17147   if (!vam->json_output)
17148     {
17149       print (vam->ofp, "%=20s", "itr-rlocs:");
17150     }
17151
17152   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17153   /* send it... */
17154   S (mp);
17155   /* Wait for a reply... */
17156   W (ret);
17157   return ret;
17158 }
17159
17160 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17161
17162 static int
17163 api_af_packet_create (vat_main_t * vam)
17164 {
17165   unformat_input_t *i = vam->input;
17166   vl_api_af_packet_create_t *mp;
17167   u8 *host_if_name = 0;
17168   u8 hw_addr[6];
17169   u8 random_hw_addr = 1;
17170   int ret;
17171
17172   clib_memset (hw_addr, 0, sizeof (hw_addr));
17173
17174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17175     {
17176       if (unformat (i, "name %s", &host_if_name))
17177         vec_add1 (host_if_name, 0);
17178       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17179         random_hw_addr = 0;
17180       else
17181         break;
17182     }
17183
17184   if (!vec_len (host_if_name))
17185     {
17186       errmsg ("host-interface name must be specified");
17187       return -99;
17188     }
17189
17190   if (vec_len (host_if_name) > 64)
17191     {
17192       errmsg ("host-interface name too long");
17193       return -99;
17194     }
17195
17196   M (AF_PACKET_CREATE, mp);
17197
17198   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17199   clib_memcpy (mp->hw_addr, hw_addr, 6);
17200   mp->use_random_hw_addr = random_hw_addr;
17201   vec_free (host_if_name);
17202
17203   S (mp);
17204
17205   /* *INDENT-OFF* */
17206   W2 (ret,
17207       ({
17208         if (ret == 0)
17209           fprintf (vam->ofp ? vam->ofp : stderr,
17210                    " new sw_if_index = %d\n", vam->sw_if_index);
17211       }));
17212   /* *INDENT-ON* */
17213   return ret;
17214 }
17215
17216 static int
17217 api_af_packet_delete (vat_main_t * vam)
17218 {
17219   unformat_input_t *i = vam->input;
17220   vl_api_af_packet_delete_t *mp;
17221   u8 *host_if_name = 0;
17222   int ret;
17223
17224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17225     {
17226       if (unformat (i, "name %s", &host_if_name))
17227         vec_add1 (host_if_name, 0);
17228       else
17229         break;
17230     }
17231
17232   if (!vec_len (host_if_name))
17233     {
17234       errmsg ("host-interface name must be specified");
17235       return -99;
17236     }
17237
17238   if (vec_len (host_if_name) > 64)
17239     {
17240       errmsg ("host-interface name too long");
17241       return -99;
17242     }
17243
17244   M (AF_PACKET_DELETE, mp);
17245
17246   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17247   vec_free (host_if_name);
17248
17249   S (mp);
17250   W (ret);
17251   return ret;
17252 }
17253
17254 static void vl_api_af_packet_details_t_handler
17255   (vl_api_af_packet_details_t * mp)
17256 {
17257   vat_main_t *vam = &vat_main;
17258
17259   print (vam->ofp, "%-16s %d",
17260          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17261 }
17262
17263 static void vl_api_af_packet_details_t_handler_json
17264   (vl_api_af_packet_details_t * mp)
17265 {
17266   vat_main_t *vam = &vat_main;
17267   vat_json_node_t *node = NULL;
17268
17269   if (VAT_JSON_ARRAY != vam->json_tree.type)
17270     {
17271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17272       vat_json_init_array (&vam->json_tree);
17273     }
17274   node = vat_json_array_add (&vam->json_tree);
17275
17276   vat_json_init_object (node);
17277   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17278   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17279 }
17280
17281 static int
17282 api_af_packet_dump (vat_main_t * vam)
17283 {
17284   vl_api_af_packet_dump_t *mp;
17285   vl_api_control_ping_t *mp_ping;
17286   int ret;
17287
17288   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17289   /* Get list of tap interfaces */
17290   M (AF_PACKET_DUMP, mp);
17291   S (mp);
17292
17293   /* Use a control ping for synchronization */
17294   MPING (CONTROL_PING, mp_ping);
17295   S (mp_ping);
17296
17297   W (ret);
17298   return ret;
17299 }
17300
17301 static int
17302 api_policer_add_del (vat_main_t * vam)
17303 {
17304   unformat_input_t *i = vam->input;
17305   vl_api_policer_add_del_t *mp;
17306   u8 is_add = 1;
17307   u8 *name = 0;
17308   u32 cir = 0;
17309   u32 eir = 0;
17310   u64 cb = 0;
17311   u64 eb = 0;
17312   u8 rate_type = 0;
17313   u8 round_type = 0;
17314   u8 type = 0;
17315   u8 color_aware = 0;
17316   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17317   int ret;
17318
17319   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17320   conform_action.dscp = 0;
17321   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17322   exceed_action.dscp = 0;
17323   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17324   violate_action.dscp = 0;
17325
17326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17327     {
17328       if (unformat (i, "del"))
17329         is_add = 0;
17330       else if (unformat (i, "name %s", &name))
17331         vec_add1 (name, 0);
17332       else if (unformat (i, "cir %u", &cir))
17333         ;
17334       else if (unformat (i, "eir %u", &eir))
17335         ;
17336       else if (unformat (i, "cb %u", &cb))
17337         ;
17338       else if (unformat (i, "eb %u", &eb))
17339         ;
17340       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17341                          &rate_type))
17342         ;
17343       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17344                          &round_type))
17345         ;
17346       else if (unformat (i, "type %U", unformat_policer_type, &type))
17347         ;
17348       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17349                          &conform_action))
17350         ;
17351       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17352                          &exceed_action))
17353         ;
17354       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17355                          &violate_action))
17356         ;
17357       else if (unformat (i, "color-aware"))
17358         color_aware = 1;
17359       else
17360         break;
17361     }
17362
17363   if (!vec_len (name))
17364     {
17365       errmsg ("policer name must be specified");
17366       return -99;
17367     }
17368
17369   if (vec_len (name) > 64)
17370     {
17371       errmsg ("policer name too long");
17372       return -99;
17373     }
17374
17375   M (POLICER_ADD_DEL, mp);
17376
17377   clib_memcpy (mp->name, name, vec_len (name));
17378   vec_free (name);
17379   mp->is_add = is_add;
17380   mp->cir = ntohl (cir);
17381   mp->eir = ntohl (eir);
17382   mp->cb = clib_net_to_host_u64 (cb);
17383   mp->eb = clib_net_to_host_u64 (eb);
17384   mp->rate_type = rate_type;
17385   mp->round_type = round_type;
17386   mp->type = type;
17387   mp->conform_action.type = conform_action.action_type;
17388   mp->conform_action.dscp = conform_action.dscp;
17389   mp->exceed_action.type = exceed_action.action_type;
17390   mp->exceed_action.dscp = exceed_action.dscp;
17391   mp->violate_action.type = violate_action.action_type;
17392   mp->violate_action.dscp = violate_action.dscp;
17393   mp->color_aware = color_aware;
17394
17395   S (mp);
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static int
17401 api_policer_dump (vat_main_t * vam)
17402 {
17403   unformat_input_t *i = vam->input;
17404   vl_api_policer_dump_t *mp;
17405   vl_api_control_ping_t *mp_ping;
17406   u8 *match_name = 0;
17407   u8 match_name_valid = 0;
17408   int ret;
17409
17410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17411     {
17412       if (unformat (i, "name %s", &match_name))
17413         {
17414           vec_add1 (match_name, 0);
17415           match_name_valid = 1;
17416         }
17417       else
17418         break;
17419     }
17420
17421   M (POLICER_DUMP, mp);
17422   mp->match_name_valid = match_name_valid;
17423   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17424   vec_free (match_name);
17425   /* send it... */
17426   S (mp);
17427
17428   /* Use a control ping for synchronization */
17429   MPING (CONTROL_PING, mp_ping);
17430   S (mp_ping);
17431
17432   /* Wait for a reply... */
17433   W (ret);
17434   return ret;
17435 }
17436
17437 static int
17438 api_policer_classify_set_interface (vat_main_t * vam)
17439 {
17440   unformat_input_t *i = vam->input;
17441   vl_api_policer_classify_set_interface_t *mp;
17442   u32 sw_if_index;
17443   int sw_if_index_set;
17444   u32 ip4_table_index = ~0;
17445   u32 ip6_table_index = ~0;
17446   u32 l2_table_index = ~0;
17447   u8 is_add = 1;
17448   int ret;
17449
17450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17451     {
17452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17453         sw_if_index_set = 1;
17454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17455         sw_if_index_set = 1;
17456       else if (unformat (i, "del"))
17457         is_add = 0;
17458       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17459         ;
17460       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17461         ;
17462       else if (unformat (i, "l2-table %d", &l2_table_index))
17463         ;
17464       else
17465         {
17466           clib_warning ("parse error '%U'", format_unformat_error, i);
17467           return -99;
17468         }
17469     }
17470
17471   if (sw_if_index_set == 0)
17472     {
17473       errmsg ("missing interface name or sw_if_index");
17474       return -99;
17475     }
17476
17477   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17478
17479   mp->sw_if_index = ntohl (sw_if_index);
17480   mp->ip4_table_index = ntohl (ip4_table_index);
17481   mp->ip6_table_index = ntohl (ip6_table_index);
17482   mp->l2_table_index = ntohl (l2_table_index);
17483   mp->is_add = is_add;
17484
17485   S (mp);
17486   W (ret);
17487   return ret;
17488 }
17489
17490 static int
17491 api_policer_classify_dump (vat_main_t * vam)
17492 {
17493   unformat_input_t *i = vam->input;
17494   vl_api_policer_classify_dump_t *mp;
17495   vl_api_control_ping_t *mp_ping;
17496   u8 type = POLICER_CLASSIFY_N_TABLES;
17497   int ret;
17498
17499   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17500     ;
17501   else
17502     {
17503       errmsg ("classify table type must be specified");
17504       return -99;
17505     }
17506
17507   if (!vam->json_output)
17508     {
17509       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17510     }
17511
17512   M (POLICER_CLASSIFY_DUMP, mp);
17513   mp->type = type;
17514   /* send it... */
17515   S (mp);
17516
17517   /* Use a control ping for synchronization */
17518   MPING (CONTROL_PING, mp_ping);
17519   S (mp_ping);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static u8 *
17527 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17528 {
17529   vl_api_fib_path_nh_proto_t proto =
17530     va_arg (*args, vl_api_fib_path_nh_proto_t);
17531
17532   switch (proto)
17533     {
17534     case FIB_API_PATH_NH_PROTO_IP4:
17535       s = format (s, "ip4");
17536       break;
17537     case FIB_API_PATH_NH_PROTO_IP6:
17538       s = format (s, "ip6");
17539       break;
17540     case FIB_API_PATH_NH_PROTO_MPLS:
17541       s = format (s, "mpls");
17542       break;
17543     case FIB_API_PATH_NH_PROTO_BIER:
17544       s = format (s, "bier");
17545       break;
17546     case FIB_API_PATH_NH_PROTO_ETHERNET:
17547       s = format (s, "ethernet");
17548       break;
17549     }
17550
17551   return (s);
17552 }
17553
17554 static u8 *
17555 format_vl_api_ip_address_union (u8 * s, va_list * args)
17556 {
17557   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17558   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17559
17560   switch (af)
17561     {
17562     case ADDRESS_IP4:
17563       s = format (s, "%U", format_ip4_address, u->ip4);
17564       break;
17565     case ADDRESS_IP6:
17566       s = format (s, "%U", format_ip6_address, u->ip6);
17567       break;
17568     }
17569   return (s);
17570 }
17571
17572 static u8 *
17573 format_vl_api_fib_path_type (u8 * s, va_list * args)
17574 {
17575   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17576
17577   switch (t)
17578     {
17579     case FIB_API_PATH_TYPE_NORMAL:
17580       s = format (s, "normal");
17581       break;
17582     case FIB_API_PATH_TYPE_LOCAL:
17583       s = format (s, "local");
17584       break;
17585     case FIB_API_PATH_TYPE_DROP:
17586       s = format (s, "drop");
17587       break;
17588     case FIB_API_PATH_TYPE_UDP_ENCAP:
17589       s = format (s, "udp-encap");
17590       break;
17591     case FIB_API_PATH_TYPE_BIER_IMP:
17592       s = format (s, "bier-imp");
17593       break;
17594     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17595       s = format (s, "unreach");
17596       break;
17597     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17598       s = format (s, "prohibit");
17599       break;
17600     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17601       s = format (s, "src-lookup");
17602       break;
17603     case FIB_API_PATH_TYPE_DVR:
17604       s = format (s, "dvr");
17605       break;
17606     case FIB_API_PATH_TYPE_INTERFACE_RX:
17607       s = format (s, "interface-rx");
17608       break;
17609     case FIB_API_PATH_TYPE_CLASSIFY:
17610       s = format (s, "classify");
17611       break;
17612     }
17613
17614   return (s);
17615 }
17616
17617 static void
17618 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17619 {
17620   print (vam->ofp,
17621          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17622          ntohl (fp->weight), ntohl (fp->sw_if_index),
17623          format_vl_api_fib_path_type, fp->type,
17624          format_fib_api_path_nh_proto, fp->proto,
17625          format_vl_api_ip_address_union, &fp->nh.address);
17626 }
17627
17628 static void
17629 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17630                                  vl_api_fib_path_t * fp)
17631 {
17632   struct in_addr ip4;
17633   struct in6_addr ip6;
17634
17635   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17636   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17637   vat_json_object_add_uint (node, "type", fp->type);
17638   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17639   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17640     {
17641       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17642       vat_json_object_add_ip4 (node, "next_hop", ip4);
17643     }
17644   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17645     {
17646       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17647       vat_json_object_add_ip6 (node, "next_hop", ip6);
17648     }
17649 }
17650
17651 static void
17652 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17653 {
17654   vat_main_t *vam = &vat_main;
17655   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17656   vl_api_fib_path_t *fp;
17657   i32 i;
17658
17659   print (vam->ofp, "sw_if_index %d via:",
17660          ntohl (mp->mt_tunnel.mt_sw_if_index));
17661   fp = mp->mt_tunnel.mt_paths;
17662   for (i = 0; i < count; i++)
17663     {
17664       vl_api_fib_path_print (vam, fp);
17665       fp++;
17666     }
17667
17668   print (vam->ofp, "");
17669 }
17670
17671 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17672 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17673
17674 static void
17675 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17676 {
17677   vat_main_t *vam = &vat_main;
17678   vat_json_node_t *node = NULL;
17679   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17680   vl_api_fib_path_t *fp;
17681   i32 i;
17682
17683   if (VAT_JSON_ARRAY != vam->json_tree.type)
17684     {
17685       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17686       vat_json_init_array (&vam->json_tree);
17687     }
17688   node = vat_json_array_add (&vam->json_tree);
17689
17690   vat_json_init_object (node);
17691   vat_json_object_add_uint (node, "sw_if_index",
17692                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17693
17694   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17695
17696   fp = mp->mt_tunnel.mt_paths;
17697   for (i = 0; i < count; i++)
17698     {
17699       vl_api_mpls_fib_path_json_print (node, fp);
17700       fp++;
17701     }
17702 }
17703
17704 static int
17705 api_mpls_tunnel_dump (vat_main_t * vam)
17706 {
17707   vl_api_mpls_tunnel_dump_t *mp;
17708   vl_api_control_ping_t *mp_ping;
17709   int ret;
17710
17711   M (MPLS_TUNNEL_DUMP, mp);
17712
17713   S (mp);
17714
17715   /* Use a control ping for synchronization */
17716   MPING (CONTROL_PING, mp_ping);
17717   S (mp_ping);
17718
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17724 #define vl_api_mpls_table_details_t_print vl_noop_handler
17725
17726
17727 static void
17728 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17729 {
17730   vat_main_t *vam = &vat_main;
17731
17732   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17733 }
17734
17735 static void vl_api_mpls_table_details_t_handler_json
17736   (vl_api_mpls_table_details_t * mp)
17737 {
17738   vat_main_t *vam = &vat_main;
17739   vat_json_node_t *node = NULL;
17740
17741   if (VAT_JSON_ARRAY != vam->json_tree.type)
17742     {
17743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17744       vat_json_init_array (&vam->json_tree);
17745     }
17746   node = vat_json_array_add (&vam->json_tree);
17747
17748   vat_json_init_object (node);
17749   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17750 }
17751
17752 static int
17753 api_mpls_table_dump (vat_main_t * vam)
17754 {
17755   vl_api_mpls_table_dump_t *mp;
17756   vl_api_control_ping_t *mp_ping;
17757   int ret;
17758
17759   M (MPLS_TABLE_DUMP, mp);
17760   S (mp);
17761
17762   /* Use a control ping for synchronization */
17763   MPING (CONTROL_PING, mp_ping);
17764   S (mp_ping);
17765
17766   W (ret);
17767   return ret;
17768 }
17769
17770 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17771 #define vl_api_mpls_route_details_t_print vl_noop_handler
17772
17773 static void
17774 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17775 {
17776   vat_main_t *vam = &vat_main;
17777   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17778   vl_api_fib_path_t *fp;
17779   int i;
17780
17781   print (vam->ofp,
17782          "table-id %d, label %u, ess_bit %u",
17783          ntohl (mp->mr_route.mr_table_id),
17784          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17785   fp = mp->mr_route.mr_paths;
17786   for (i = 0; i < count; i++)
17787     {
17788       vl_api_fib_path_print (vam, fp);
17789       fp++;
17790     }
17791 }
17792
17793 static void vl_api_mpls_route_details_t_handler_json
17794   (vl_api_mpls_route_details_t * mp)
17795 {
17796   vat_main_t *vam = &vat_main;
17797   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17798   vat_json_node_t *node = NULL;
17799   vl_api_fib_path_t *fp;
17800   int i;
17801
17802   if (VAT_JSON_ARRAY != vam->json_tree.type)
17803     {
17804       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17805       vat_json_init_array (&vam->json_tree);
17806     }
17807   node = vat_json_array_add (&vam->json_tree);
17808
17809   vat_json_init_object (node);
17810   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17811   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17812   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17813   vat_json_object_add_uint (node, "path_count", count);
17814   fp = mp->mr_route.mr_paths;
17815   for (i = 0; i < count; i++)
17816     {
17817       vl_api_mpls_fib_path_json_print (node, fp);
17818       fp++;
17819     }
17820 }
17821
17822 static int
17823 api_mpls_route_dump (vat_main_t * vam)
17824 {
17825   unformat_input_t *input = vam->input;
17826   vl_api_mpls_route_dump_t *mp;
17827   vl_api_control_ping_t *mp_ping;
17828   u32 table_id;
17829   int ret;
17830
17831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17832     {
17833       if (unformat (input, "table_id %d", &table_id))
17834         ;
17835       else
17836         break;
17837     }
17838   if (table_id == ~0)
17839     {
17840       errmsg ("missing table id");
17841       return -99;
17842     }
17843
17844   M (MPLS_ROUTE_DUMP, mp);
17845
17846   mp->table.mt_table_id = ntohl (table_id);
17847   S (mp);
17848
17849   /* Use a control ping for synchronization */
17850   MPING (CONTROL_PING, mp_ping);
17851   S (mp_ping);
17852
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define vl_api_ip_table_details_t_endian vl_noop_handler
17858 #define vl_api_ip_table_details_t_print vl_noop_handler
17859
17860 static void
17861 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17862 {
17863   vat_main_t *vam = &vat_main;
17864
17865   print (vam->ofp,
17866          "%s; table-id %d, prefix %U/%d",
17867          mp->table.name, ntohl (mp->table.table_id));
17868 }
17869
17870
17871 static void vl_api_ip_table_details_t_handler_json
17872   (vl_api_ip_table_details_t * mp)
17873 {
17874   vat_main_t *vam = &vat_main;
17875   vat_json_node_t *node = NULL;
17876
17877   if (VAT_JSON_ARRAY != vam->json_tree.type)
17878     {
17879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17880       vat_json_init_array (&vam->json_tree);
17881     }
17882   node = vat_json_array_add (&vam->json_tree);
17883
17884   vat_json_init_object (node);
17885   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17886 }
17887
17888 static int
17889 api_ip_table_dump (vat_main_t * vam)
17890 {
17891   vl_api_ip_table_dump_t *mp;
17892   vl_api_control_ping_t *mp_ping;
17893   int ret;
17894
17895   M (IP_TABLE_DUMP, mp);
17896   S (mp);
17897
17898   /* Use a control ping for synchronization */
17899   MPING (CONTROL_PING, mp_ping);
17900   S (mp_ping);
17901
17902   W (ret);
17903   return ret;
17904 }
17905
17906 static int
17907 api_ip_mtable_dump (vat_main_t * vam)
17908 {
17909   vl_api_ip_mtable_dump_t *mp;
17910   vl_api_control_ping_t *mp_ping;
17911   int ret;
17912
17913   M (IP_MTABLE_DUMP, mp);
17914   S (mp);
17915
17916   /* Use a control ping for synchronization */
17917   MPING (CONTROL_PING, mp_ping);
17918   S (mp_ping);
17919
17920   W (ret);
17921   return ret;
17922 }
17923
17924 static int
17925 api_ip_mroute_dump (vat_main_t * vam)
17926 {
17927   unformat_input_t *input = vam->input;
17928   vl_api_control_ping_t *mp_ping;
17929   vl_api_ip_mroute_dump_t *mp;
17930   int ret, is_ip6;
17931   u32 table_id;
17932
17933   is_ip6 = 0;
17934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17935     {
17936       if (unformat (input, "table_id %d", &table_id))
17937         ;
17938       else if (unformat (input, "ip6"))
17939         is_ip6 = 1;
17940       else if (unformat (input, "ip4"))
17941         is_ip6 = 0;
17942       else
17943         break;
17944     }
17945   if (table_id == ~0)
17946     {
17947       errmsg ("missing table id");
17948       return -99;
17949     }
17950
17951   M (IP_MROUTE_DUMP, mp);
17952   mp->table.table_id = table_id;
17953   mp->table.is_ip6 = is_ip6;
17954   S (mp);
17955
17956   /* Use a control ping for synchronization */
17957   MPING (CONTROL_PING, mp_ping);
17958   S (mp_ping);
17959
17960   W (ret);
17961   return ret;
17962 }
17963
17964 #define vl_api_ip_route_details_t_endian vl_noop_handler
17965 #define vl_api_ip_route_details_t_print vl_noop_handler
17966
17967 static void
17968 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17969 {
17970   vat_main_t *vam = &vat_main;
17971   u8 count = mp->route.n_paths;
17972   vl_api_fib_path_t *fp;
17973   int i;
17974
17975   print (vam->ofp,
17976          "table-id %d, prefix %U/%d",
17977          ntohl (mp->route.table_id),
17978          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17979   for (i = 0; i < count; i++)
17980     {
17981       fp = &mp->route.paths[i];
17982
17983       vl_api_fib_path_print (vam, fp);
17984       fp++;
17985     }
17986 }
17987
17988 static void vl_api_ip_route_details_t_handler_json
17989   (vl_api_ip_route_details_t * mp)
17990 {
17991   vat_main_t *vam = &vat_main;
17992   u8 count = mp->route.n_paths;
17993   vat_json_node_t *node = NULL;
17994   struct in_addr ip4;
17995   struct in6_addr ip6;
17996   vl_api_fib_path_t *fp;
17997   int i;
17998
17999   if (VAT_JSON_ARRAY != vam->json_tree.type)
18000     {
18001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18002       vat_json_init_array (&vam->json_tree);
18003     }
18004   node = vat_json_array_add (&vam->json_tree);
18005
18006   vat_json_init_object (node);
18007   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18008   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18009     {
18010       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18011       vat_json_object_add_ip6 (node, "prefix", ip6);
18012     }
18013   else
18014     {
18015       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18016       vat_json_object_add_ip4 (node, "prefix", ip4);
18017     }
18018   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18019   vat_json_object_add_uint (node, "path_count", count);
18020   for (i = 0; i < count; i++)
18021     {
18022       fp = &mp->route.paths[i];
18023       vl_api_mpls_fib_path_json_print (node, fp);
18024     }
18025 }
18026
18027 static int
18028 api_ip_route_dump (vat_main_t * vam)
18029 {
18030   unformat_input_t *input = vam->input;
18031   vl_api_ip_route_dump_t *mp;
18032   vl_api_control_ping_t *mp_ping;
18033   u32 table_id;
18034   u8 is_ip6;
18035   int ret;
18036
18037   is_ip6 = 0;
18038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18039     {
18040       if (unformat (input, "table_id %d", &table_id))
18041         ;
18042       else if (unformat (input, "ip6"))
18043         is_ip6 = 1;
18044       else if (unformat (input, "ip4"))
18045         is_ip6 = 0;
18046       else
18047         break;
18048     }
18049   if (table_id == ~0)
18050     {
18051       errmsg ("missing table id");
18052       return -99;
18053     }
18054
18055   M (IP_ROUTE_DUMP, mp);
18056
18057   mp->table.table_id = table_id;
18058   mp->table.is_ip6 = is_ip6;
18059
18060   S (mp);
18061
18062   /* Use a control ping for synchronization */
18063   MPING (CONTROL_PING, mp_ping);
18064   S (mp_ping);
18065
18066   W (ret);
18067   return ret;
18068 }
18069
18070 int
18071 api_classify_table_ids (vat_main_t * vam)
18072 {
18073   vl_api_classify_table_ids_t *mp;
18074   int ret;
18075
18076   /* Construct the API message */
18077   M (CLASSIFY_TABLE_IDS, mp);
18078   mp->context = 0;
18079
18080   S (mp);
18081   W (ret);
18082   return ret;
18083 }
18084
18085 int
18086 api_classify_table_by_interface (vat_main_t * vam)
18087 {
18088   unformat_input_t *input = vam->input;
18089   vl_api_classify_table_by_interface_t *mp;
18090
18091   u32 sw_if_index = ~0;
18092   int ret;
18093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18094     {
18095       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18096         ;
18097       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18098         ;
18099       else
18100         break;
18101     }
18102   if (sw_if_index == ~0)
18103     {
18104       errmsg ("missing interface name or sw_if_index");
18105       return -99;
18106     }
18107
18108   /* Construct the API message */
18109   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18110   mp->context = 0;
18111   mp->sw_if_index = ntohl (sw_if_index);
18112
18113   S (mp);
18114   W (ret);
18115   return ret;
18116 }
18117
18118 int
18119 api_classify_table_info (vat_main_t * vam)
18120 {
18121   unformat_input_t *input = vam->input;
18122   vl_api_classify_table_info_t *mp;
18123
18124   u32 table_id = ~0;
18125   int ret;
18126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18127     {
18128       if (unformat (input, "table_id %d", &table_id))
18129         ;
18130       else
18131         break;
18132     }
18133   if (table_id == ~0)
18134     {
18135       errmsg ("missing table id");
18136       return -99;
18137     }
18138
18139   /* Construct the API message */
18140   M (CLASSIFY_TABLE_INFO, mp);
18141   mp->context = 0;
18142   mp->table_id = ntohl (table_id);
18143
18144   S (mp);
18145   W (ret);
18146   return ret;
18147 }
18148
18149 int
18150 api_classify_session_dump (vat_main_t * vam)
18151 {
18152   unformat_input_t *input = vam->input;
18153   vl_api_classify_session_dump_t *mp;
18154   vl_api_control_ping_t *mp_ping;
18155
18156   u32 table_id = ~0;
18157   int ret;
18158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18159     {
18160       if (unformat (input, "table_id %d", &table_id))
18161         ;
18162       else
18163         break;
18164     }
18165   if (table_id == ~0)
18166     {
18167       errmsg ("missing table id");
18168       return -99;
18169     }
18170
18171   /* Construct the API message */
18172   M (CLASSIFY_SESSION_DUMP, mp);
18173   mp->context = 0;
18174   mp->table_id = ntohl (table_id);
18175   S (mp);
18176
18177   /* Use a control ping for synchronization */
18178   MPING (CONTROL_PING, mp_ping);
18179   S (mp_ping);
18180
18181   W (ret);
18182   return ret;
18183 }
18184
18185 static void
18186 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18187 {
18188   vat_main_t *vam = &vat_main;
18189
18190   print (vam->ofp, "collector_address %U, collector_port %d, "
18191          "src_address %U, vrf_id %d, path_mtu %u, "
18192          "template_interval %u, udp_checksum %d",
18193          format_ip4_address, mp->collector_address,
18194          ntohs (mp->collector_port),
18195          format_ip4_address, mp->src_address,
18196          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18197          ntohl (mp->template_interval), mp->udp_checksum);
18198
18199   vam->retval = 0;
18200   vam->result_ready = 1;
18201 }
18202
18203 static void
18204   vl_api_ipfix_exporter_details_t_handler_json
18205   (vl_api_ipfix_exporter_details_t * mp)
18206 {
18207   vat_main_t *vam = &vat_main;
18208   vat_json_node_t node;
18209   struct in_addr collector_address;
18210   struct in_addr src_address;
18211
18212   vat_json_init_object (&node);
18213   clib_memcpy (&collector_address, &mp->collector_address,
18214                sizeof (collector_address));
18215   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18216   vat_json_object_add_uint (&node, "collector_port",
18217                             ntohs (mp->collector_port));
18218   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18219   vat_json_object_add_ip4 (&node, "src_address", src_address);
18220   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18221   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18222   vat_json_object_add_uint (&node, "template_interval",
18223                             ntohl (mp->template_interval));
18224   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18225
18226   vat_json_print (vam->ofp, &node);
18227   vat_json_free (&node);
18228   vam->retval = 0;
18229   vam->result_ready = 1;
18230 }
18231
18232 int
18233 api_ipfix_exporter_dump (vat_main_t * vam)
18234 {
18235   vl_api_ipfix_exporter_dump_t *mp;
18236   int ret;
18237
18238   /* Construct the API message */
18239   M (IPFIX_EXPORTER_DUMP, mp);
18240   mp->context = 0;
18241
18242   S (mp);
18243   W (ret);
18244   return ret;
18245 }
18246
18247 static int
18248 api_ipfix_classify_stream_dump (vat_main_t * vam)
18249 {
18250   vl_api_ipfix_classify_stream_dump_t *mp;
18251   int ret;
18252
18253   /* Construct the API message */
18254   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18255   mp->context = 0;
18256
18257   S (mp);
18258   W (ret);
18259   return ret;
18260   /* NOTREACHED */
18261   return 0;
18262 }
18263
18264 static void
18265   vl_api_ipfix_classify_stream_details_t_handler
18266   (vl_api_ipfix_classify_stream_details_t * mp)
18267 {
18268   vat_main_t *vam = &vat_main;
18269   print (vam->ofp, "domain_id %d, src_port %d",
18270          ntohl (mp->domain_id), ntohs (mp->src_port));
18271   vam->retval = 0;
18272   vam->result_ready = 1;
18273 }
18274
18275 static void
18276   vl_api_ipfix_classify_stream_details_t_handler_json
18277   (vl_api_ipfix_classify_stream_details_t * mp)
18278 {
18279   vat_main_t *vam = &vat_main;
18280   vat_json_node_t node;
18281
18282   vat_json_init_object (&node);
18283   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18284   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18285
18286   vat_json_print (vam->ofp, &node);
18287   vat_json_free (&node);
18288   vam->retval = 0;
18289   vam->result_ready = 1;
18290 }
18291
18292 static int
18293 api_ipfix_classify_table_dump (vat_main_t * vam)
18294 {
18295   vl_api_ipfix_classify_table_dump_t *mp;
18296   vl_api_control_ping_t *mp_ping;
18297   int ret;
18298
18299   if (!vam->json_output)
18300     {
18301       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18302              "transport_protocol");
18303     }
18304
18305   /* Construct the API message */
18306   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18307
18308   /* send it... */
18309   S (mp);
18310
18311   /* Use a control ping for synchronization */
18312   MPING (CONTROL_PING, mp_ping);
18313   S (mp_ping);
18314
18315   W (ret);
18316   return ret;
18317 }
18318
18319 static void
18320   vl_api_ipfix_classify_table_details_t_handler
18321   (vl_api_ipfix_classify_table_details_t * mp)
18322 {
18323   vat_main_t *vam = &vat_main;
18324   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18325          mp->transport_protocol);
18326 }
18327
18328 static void
18329   vl_api_ipfix_classify_table_details_t_handler_json
18330   (vl_api_ipfix_classify_table_details_t * mp)
18331 {
18332   vat_json_node_t *node = NULL;
18333   vat_main_t *vam = &vat_main;
18334
18335   if (VAT_JSON_ARRAY != vam->json_tree.type)
18336     {
18337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18338       vat_json_init_array (&vam->json_tree);
18339     }
18340
18341   node = vat_json_array_add (&vam->json_tree);
18342   vat_json_init_object (node);
18343
18344   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18345   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18346   vat_json_object_add_uint (node, "transport_protocol",
18347                             mp->transport_protocol);
18348 }
18349
18350 static int
18351 api_sw_interface_span_enable_disable (vat_main_t * vam)
18352 {
18353   unformat_input_t *i = vam->input;
18354   vl_api_sw_interface_span_enable_disable_t *mp;
18355   u32 src_sw_if_index = ~0;
18356   u32 dst_sw_if_index = ~0;
18357   u8 state = 3;
18358   int ret;
18359   u8 is_l2 = 0;
18360
18361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18362     {
18363       if (unformat
18364           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18365         ;
18366       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18367         ;
18368       else
18369         if (unformat
18370             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18371         ;
18372       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18373         ;
18374       else if (unformat (i, "disable"))
18375         state = 0;
18376       else if (unformat (i, "rx"))
18377         state = 1;
18378       else if (unformat (i, "tx"))
18379         state = 2;
18380       else if (unformat (i, "both"))
18381         state = 3;
18382       else if (unformat (i, "l2"))
18383         is_l2 = 1;
18384       else
18385         break;
18386     }
18387
18388   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18389
18390   mp->sw_if_index_from = htonl (src_sw_if_index);
18391   mp->sw_if_index_to = htonl (dst_sw_if_index);
18392   mp->state = state;
18393   mp->is_l2 = is_l2;
18394
18395   S (mp);
18396   W (ret);
18397   return ret;
18398 }
18399
18400 static void
18401 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18402                                             * mp)
18403 {
18404   vat_main_t *vam = &vat_main;
18405   u8 *sw_if_from_name = 0;
18406   u8 *sw_if_to_name = 0;
18407   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18408   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18409   char *states[] = { "none", "rx", "tx", "both" };
18410   hash_pair_t *p;
18411
18412   /* *INDENT-OFF* */
18413   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18414   ({
18415     if ((u32) p->value[0] == sw_if_index_from)
18416       {
18417         sw_if_from_name = (u8 *)(p->key);
18418         if (sw_if_to_name)
18419           break;
18420       }
18421     if ((u32) p->value[0] == sw_if_index_to)
18422       {
18423         sw_if_to_name = (u8 *)(p->key);
18424         if (sw_if_from_name)
18425           break;
18426       }
18427   }));
18428   /* *INDENT-ON* */
18429   print (vam->ofp, "%20s => %20s (%s) %s",
18430          sw_if_from_name, sw_if_to_name, states[mp->state],
18431          mp->is_l2 ? "l2" : "device");
18432 }
18433
18434 static void
18435   vl_api_sw_interface_span_details_t_handler_json
18436   (vl_api_sw_interface_span_details_t * mp)
18437 {
18438   vat_main_t *vam = &vat_main;
18439   vat_json_node_t *node = NULL;
18440   u8 *sw_if_from_name = 0;
18441   u8 *sw_if_to_name = 0;
18442   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18443   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18444   hash_pair_t *p;
18445
18446   /* *INDENT-OFF* */
18447   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18448   ({
18449     if ((u32) p->value[0] == sw_if_index_from)
18450       {
18451         sw_if_from_name = (u8 *)(p->key);
18452         if (sw_if_to_name)
18453           break;
18454       }
18455     if ((u32) p->value[0] == sw_if_index_to)
18456       {
18457         sw_if_to_name = (u8 *)(p->key);
18458         if (sw_if_from_name)
18459           break;
18460       }
18461   }));
18462   /* *INDENT-ON* */
18463
18464   if (VAT_JSON_ARRAY != vam->json_tree.type)
18465     {
18466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18467       vat_json_init_array (&vam->json_tree);
18468     }
18469   node = vat_json_array_add (&vam->json_tree);
18470
18471   vat_json_init_object (node);
18472   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18473   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18474   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18475   if (0 != sw_if_to_name)
18476     {
18477       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18478     }
18479   vat_json_object_add_uint (node, "state", mp->state);
18480   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18481 }
18482
18483 static int
18484 api_sw_interface_span_dump (vat_main_t * vam)
18485 {
18486   unformat_input_t *input = vam->input;
18487   vl_api_sw_interface_span_dump_t *mp;
18488   vl_api_control_ping_t *mp_ping;
18489   u8 is_l2 = 0;
18490   int ret;
18491
18492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (input, "l2"))
18495         is_l2 = 1;
18496       else
18497         break;
18498     }
18499
18500   M (SW_INTERFACE_SPAN_DUMP, mp);
18501   mp->is_l2 = is_l2;
18502   S (mp);
18503
18504   /* Use a control ping for synchronization */
18505   MPING (CONTROL_PING, mp_ping);
18506   S (mp_ping);
18507
18508   W (ret);
18509   return ret;
18510 }
18511
18512 int
18513 api_pg_create_interface (vat_main_t * vam)
18514 {
18515   unformat_input_t *input = vam->input;
18516   vl_api_pg_create_interface_t *mp;
18517
18518   u32 if_id = ~0, gso_size = 0;
18519   u8 gso_enabled = 0;
18520   int ret;
18521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18522     {
18523       if (unformat (input, "if_id %d", &if_id))
18524         ;
18525       else if (unformat (input, "gso-enabled"))
18526         {
18527           gso_enabled = 1;
18528           if (unformat (input, "gso-size %u", &gso_size))
18529             ;
18530           else
18531             {
18532               errmsg ("missing gso-size");
18533               return -99;
18534             }
18535         }
18536       else
18537         break;
18538     }
18539   if (if_id == ~0)
18540     {
18541       errmsg ("missing pg interface index");
18542       return -99;
18543     }
18544
18545   /* Construct the API message */
18546   M (PG_CREATE_INTERFACE, mp);
18547   mp->context = 0;
18548   mp->interface_id = ntohl (if_id);
18549   mp->gso_enabled = gso_enabled;
18550
18551   S (mp);
18552   W (ret);
18553   return ret;
18554 }
18555
18556 int
18557 api_pg_capture (vat_main_t * vam)
18558 {
18559   unformat_input_t *input = vam->input;
18560   vl_api_pg_capture_t *mp;
18561
18562   u32 if_id = ~0;
18563   u8 enable = 1;
18564   u32 count = 1;
18565   u8 pcap_file_set = 0;
18566   u8 *pcap_file = 0;
18567   int ret;
18568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18569     {
18570       if (unformat (input, "if_id %d", &if_id))
18571         ;
18572       else if (unformat (input, "pcap %s", &pcap_file))
18573         pcap_file_set = 1;
18574       else if (unformat (input, "count %d", &count))
18575         ;
18576       else if (unformat (input, "disable"))
18577         enable = 0;
18578       else
18579         break;
18580     }
18581   if (if_id == ~0)
18582     {
18583       errmsg ("missing pg interface index");
18584       return -99;
18585     }
18586   if (pcap_file_set > 0)
18587     {
18588       if (vec_len (pcap_file) > 255)
18589         {
18590           errmsg ("pcap file name is too long");
18591           return -99;
18592         }
18593     }
18594
18595   /* Construct the API message */
18596   M (PG_CAPTURE, mp);
18597   mp->context = 0;
18598   mp->interface_id = ntohl (if_id);
18599   mp->is_enabled = enable;
18600   mp->count = ntohl (count);
18601   if (pcap_file_set != 0)
18602     {
18603       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18604     }
18605   vec_free (pcap_file);
18606
18607   S (mp);
18608   W (ret);
18609   return ret;
18610 }
18611
18612 int
18613 api_pg_enable_disable (vat_main_t * vam)
18614 {
18615   unformat_input_t *input = vam->input;
18616   vl_api_pg_enable_disable_t *mp;
18617
18618   u8 enable = 1;
18619   u8 stream_name_set = 0;
18620   u8 *stream_name = 0;
18621   int ret;
18622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18623     {
18624       if (unformat (input, "stream %s", &stream_name))
18625         stream_name_set = 1;
18626       else if (unformat (input, "disable"))
18627         enable = 0;
18628       else
18629         break;
18630     }
18631
18632   if (stream_name_set > 0)
18633     {
18634       if (vec_len (stream_name) > 255)
18635         {
18636           errmsg ("stream name too long");
18637           return -99;
18638         }
18639     }
18640
18641   /* Construct the API message */
18642   M (PG_ENABLE_DISABLE, mp);
18643   mp->context = 0;
18644   mp->is_enabled = enable;
18645   if (stream_name_set != 0)
18646     {
18647       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18648     }
18649   vec_free (stream_name);
18650
18651   S (mp);
18652   W (ret);
18653   return ret;
18654 }
18655
18656 int
18657 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18658 {
18659   unformat_input_t *input = vam->input;
18660   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18661
18662   u16 *low_ports = 0;
18663   u16 *high_ports = 0;
18664   u16 this_low;
18665   u16 this_hi;
18666   vl_api_prefix_t prefix;
18667   u32 tmp, tmp2;
18668   u8 prefix_set = 0;
18669   u32 vrf_id = ~0;
18670   u8 is_add = 1;
18671   int ret;
18672
18673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18674     {
18675       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18676         prefix_set = 1;
18677       else if (unformat (input, "vrf %d", &vrf_id))
18678         ;
18679       else if (unformat (input, "del"))
18680         is_add = 0;
18681       else if (unformat (input, "port %d", &tmp))
18682         {
18683           if (tmp == 0 || tmp > 65535)
18684             {
18685               errmsg ("port %d out of range", tmp);
18686               return -99;
18687             }
18688           this_low = tmp;
18689           this_hi = this_low + 1;
18690           vec_add1 (low_ports, this_low);
18691           vec_add1 (high_ports, this_hi);
18692         }
18693       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18694         {
18695           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18696             {
18697               errmsg ("incorrect range parameters");
18698               return -99;
18699             }
18700           this_low = tmp;
18701           /* Note: in debug CLI +1 is added to high before
18702              passing to real fn that does "the work"
18703              (ip_source_and_port_range_check_add_del).
18704              This fn is a wrapper around the binary API fn a
18705              control plane will call, which expects this increment
18706              to have occurred. Hence letting the binary API control
18707              plane fn do the increment for consistency between VAT
18708              and other control planes.
18709            */
18710           this_hi = tmp2;
18711           vec_add1 (low_ports, this_low);
18712           vec_add1 (high_ports, this_hi);
18713         }
18714       else
18715         break;
18716     }
18717
18718   if (prefix_set == 0)
18719     {
18720       errmsg ("<address>/<mask> not specified");
18721       return -99;
18722     }
18723
18724   if (vrf_id == ~0)
18725     {
18726       errmsg ("VRF ID required, not specified");
18727       return -99;
18728     }
18729
18730   if (vrf_id == 0)
18731     {
18732       errmsg
18733         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18734       return -99;
18735     }
18736
18737   if (vec_len (low_ports) == 0)
18738     {
18739       errmsg ("At least one port or port range required");
18740       return -99;
18741     }
18742
18743   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18744
18745   mp->is_add = is_add;
18746
18747   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18748
18749   mp->number_of_ranges = vec_len (low_ports);
18750
18751   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18752   vec_free (low_ports);
18753
18754   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18755   vec_free (high_ports);
18756
18757   mp->vrf_id = ntohl (vrf_id);
18758
18759   S (mp);
18760   W (ret);
18761   return ret;
18762 }
18763
18764 int
18765 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18766 {
18767   unformat_input_t *input = vam->input;
18768   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18769   u32 sw_if_index = ~0;
18770   int vrf_set = 0;
18771   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18772   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18773   u8 is_add = 1;
18774   int ret;
18775
18776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18777     {
18778       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18779         ;
18780       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18781         ;
18782       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18783         vrf_set = 1;
18784       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18785         vrf_set = 1;
18786       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18787         vrf_set = 1;
18788       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18789         vrf_set = 1;
18790       else if (unformat (input, "del"))
18791         is_add = 0;
18792       else
18793         break;
18794     }
18795
18796   if (sw_if_index == ~0)
18797     {
18798       errmsg ("Interface required but not specified");
18799       return -99;
18800     }
18801
18802   if (vrf_set == 0)
18803     {
18804       errmsg ("VRF ID required but not specified");
18805       return -99;
18806     }
18807
18808   if (tcp_out_vrf_id == 0
18809       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18810     {
18811       errmsg
18812         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18813       return -99;
18814     }
18815
18816   /* Construct the API message */
18817   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18818
18819   mp->sw_if_index = ntohl (sw_if_index);
18820   mp->is_add = is_add;
18821   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18822   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18823   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18824   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18825
18826   /* send it... */
18827   S (mp);
18828
18829   /* Wait for a reply... */
18830   W (ret);
18831   return ret;
18832 }
18833
18834 static int
18835 api_set_punt (vat_main_t * vam)
18836 {
18837   unformat_input_t *i = vam->input;
18838   vl_api_address_family_t af;
18839   vl_api_set_punt_t *mp;
18840   u32 protocol = ~0;
18841   u32 port = ~0;
18842   int is_add = 1;
18843   int ret;
18844
18845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18846     {
18847       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18848         ;
18849       else if (unformat (i, "protocol %d", &protocol))
18850         ;
18851       else if (unformat (i, "port %d", &port))
18852         ;
18853       else if (unformat (i, "del"))
18854         is_add = 0;
18855       else
18856         {
18857           clib_warning ("parse error '%U'", format_unformat_error, i);
18858           return -99;
18859         }
18860     }
18861
18862   M (SET_PUNT, mp);
18863
18864   mp->is_add = (u8) is_add;
18865   mp->punt.type = PUNT_API_TYPE_L4;
18866   mp->punt.punt.l4.af = af;
18867   mp->punt.punt.l4.protocol = (u8) protocol;
18868   mp->punt.punt.l4.port = htons ((u16) port);
18869
18870   S (mp);
18871   W (ret);
18872   return ret;
18873 }
18874
18875 static int
18876 api_delete_subif (vat_main_t * vam)
18877 {
18878   unformat_input_t *i = vam->input;
18879   vl_api_delete_subif_t *mp;
18880   u32 sw_if_index = ~0;
18881   int ret;
18882
18883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18884     {
18885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18886         ;
18887       if (unformat (i, "sw_if_index %d", &sw_if_index))
18888         ;
18889       else
18890         break;
18891     }
18892
18893   if (sw_if_index == ~0)
18894     {
18895       errmsg ("missing sw_if_index");
18896       return -99;
18897     }
18898
18899   /* Construct the API message */
18900   M (DELETE_SUBIF, mp);
18901   mp->sw_if_index = ntohl (sw_if_index);
18902
18903   S (mp);
18904   W (ret);
18905   return ret;
18906 }
18907
18908 #define foreach_pbb_vtr_op      \
18909 _("disable",  L2_VTR_DISABLED)  \
18910 _("pop",  L2_VTR_POP_2)         \
18911 _("push",  L2_VTR_PUSH_2)
18912
18913 static int
18914 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18915 {
18916   unformat_input_t *i = vam->input;
18917   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18918   u32 sw_if_index = ~0, vtr_op = ~0;
18919   u16 outer_tag = ~0;
18920   u8 dmac[6], smac[6];
18921   u8 dmac_set = 0, smac_set = 0;
18922   u16 vlanid = 0;
18923   u32 sid = ~0;
18924   u32 tmp;
18925   int ret;
18926
18927   /* Shut up coverity */
18928   clib_memset (dmac, 0, sizeof (dmac));
18929   clib_memset (smac, 0, sizeof (smac));
18930
18931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18932     {
18933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18934         ;
18935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18936         ;
18937       else if (unformat (i, "vtr_op %d", &vtr_op))
18938         ;
18939 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18940       foreach_pbb_vtr_op
18941 #undef _
18942         else if (unformat (i, "translate_pbb_stag"))
18943         {
18944           if (unformat (i, "%d", &tmp))
18945             {
18946               vtr_op = L2_VTR_TRANSLATE_2_1;
18947               outer_tag = tmp;
18948             }
18949           else
18950             {
18951               errmsg
18952                 ("translate_pbb_stag operation requires outer tag definition");
18953               return -99;
18954             }
18955         }
18956       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18957         dmac_set++;
18958       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18959         smac_set++;
18960       else if (unformat (i, "sid %d", &sid))
18961         ;
18962       else if (unformat (i, "vlanid %d", &tmp))
18963         vlanid = tmp;
18964       else
18965         {
18966           clib_warning ("parse error '%U'", format_unformat_error, i);
18967           return -99;
18968         }
18969     }
18970
18971   if ((sw_if_index == ~0) || (vtr_op == ~0))
18972     {
18973       errmsg ("missing sw_if_index or vtr operation");
18974       return -99;
18975     }
18976   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18977       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18978     {
18979       errmsg
18980         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18981       return -99;
18982     }
18983
18984   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18985   mp->sw_if_index = ntohl (sw_if_index);
18986   mp->vtr_op = ntohl (vtr_op);
18987   mp->outer_tag = ntohs (outer_tag);
18988   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18989   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18990   mp->b_vlanid = ntohs (vlanid);
18991   mp->i_sid = ntohl (sid);
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 static int
18999 api_flow_classify_set_interface (vat_main_t * vam)
19000 {
19001   unformat_input_t *i = vam->input;
19002   vl_api_flow_classify_set_interface_t *mp;
19003   u32 sw_if_index;
19004   int sw_if_index_set;
19005   u32 ip4_table_index = ~0;
19006   u32 ip6_table_index = ~0;
19007   u8 is_add = 1;
19008   int ret;
19009
19010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19011     {
19012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19013         sw_if_index_set = 1;
19014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19015         sw_if_index_set = 1;
19016       else if (unformat (i, "del"))
19017         is_add = 0;
19018       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19019         ;
19020       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19021         ;
19022       else
19023         {
19024           clib_warning ("parse error '%U'", format_unformat_error, i);
19025           return -99;
19026         }
19027     }
19028
19029   if (sw_if_index_set == 0)
19030     {
19031       errmsg ("missing interface name or sw_if_index");
19032       return -99;
19033     }
19034
19035   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19036
19037   mp->sw_if_index = ntohl (sw_if_index);
19038   mp->ip4_table_index = ntohl (ip4_table_index);
19039   mp->ip6_table_index = ntohl (ip6_table_index);
19040   mp->is_add = is_add;
19041
19042   S (mp);
19043   W (ret);
19044   return ret;
19045 }
19046
19047 static int
19048 api_flow_classify_dump (vat_main_t * vam)
19049 {
19050   unformat_input_t *i = vam->input;
19051   vl_api_flow_classify_dump_t *mp;
19052   vl_api_control_ping_t *mp_ping;
19053   u8 type = FLOW_CLASSIFY_N_TABLES;
19054   int ret;
19055
19056   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19057     ;
19058   else
19059     {
19060       errmsg ("classify table type must be specified");
19061       return -99;
19062     }
19063
19064   if (!vam->json_output)
19065     {
19066       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19067     }
19068
19069   M (FLOW_CLASSIFY_DUMP, mp);
19070   mp->type = type;
19071   /* send it... */
19072   S (mp);
19073
19074   /* Use a control ping for synchronization */
19075   MPING (CONTROL_PING, mp_ping);
19076   S (mp_ping);
19077
19078   /* Wait for a reply... */
19079   W (ret);
19080   return ret;
19081 }
19082
19083 static int
19084 api_feature_enable_disable (vat_main_t * vam)
19085 {
19086   unformat_input_t *i = vam->input;
19087   vl_api_feature_enable_disable_t *mp;
19088   u8 *arc_name = 0;
19089   u8 *feature_name = 0;
19090   u32 sw_if_index = ~0;
19091   u8 enable = 1;
19092   int ret;
19093
19094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (i, "arc_name %s", &arc_name))
19097         ;
19098       else if (unformat (i, "feature_name %s", &feature_name))
19099         ;
19100       else
19101         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19102         ;
19103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19104         ;
19105       else if (unformat (i, "disable"))
19106         enable = 0;
19107       else
19108         break;
19109     }
19110
19111   if (arc_name == 0)
19112     {
19113       errmsg ("missing arc name");
19114       return -99;
19115     }
19116   if (vec_len (arc_name) > 63)
19117     {
19118       errmsg ("arc name too long");
19119     }
19120
19121   if (feature_name == 0)
19122     {
19123       errmsg ("missing feature name");
19124       return -99;
19125     }
19126   if (vec_len (feature_name) > 63)
19127     {
19128       errmsg ("feature name too long");
19129     }
19130
19131   if (sw_if_index == ~0)
19132     {
19133       errmsg ("missing interface name or sw_if_index");
19134       return -99;
19135     }
19136
19137   /* Construct the API message */
19138   M (FEATURE_ENABLE_DISABLE, mp);
19139   mp->sw_if_index = ntohl (sw_if_index);
19140   mp->enable = enable;
19141   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19142   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19143   vec_free (arc_name);
19144   vec_free (feature_name);
19145
19146   S (mp);
19147   W (ret);
19148   return ret;
19149 }
19150
19151 static int
19152 api_feature_gso_enable_disable (vat_main_t * vam)
19153 {
19154   unformat_input_t *i = vam->input;
19155   vl_api_feature_gso_enable_disable_t *mp;
19156   u32 sw_if_index = ~0;
19157   u8 enable = 1;
19158   int ret;
19159
19160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19161     {
19162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19163         ;
19164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19165         ;
19166       else if (unformat (i, "enable"))
19167         enable = 1;
19168       else if (unformat (i, "disable"))
19169         enable = 0;
19170       else
19171         break;
19172     }
19173
19174   if (sw_if_index == ~0)
19175     {
19176       errmsg ("missing interface name or sw_if_index");
19177       return -99;
19178     }
19179
19180   /* Construct the API message */
19181   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19182   mp->sw_if_index = ntohl (sw_if_index);
19183   mp->enable_disable = enable;
19184
19185   S (mp);
19186   W (ret);
19187   return ret;
19188 }
19189
19190 static int
19191 api_sw_interface_tag_add_del (vat_main_t * vam)
19192 {
19193   unformat_input_t *i = vam->input;
19194   vl_api_sw_interface_tag_add_del_t *mp;
19195   u32 sw_if_index = ~0;
19196   u8 *tag = 0;
19197   u8 enable = 1;
19198   int ret;
19199
19200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19201     {
19202       if (unformat (i, "tag %s", &tag))
19203         ;
19204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19205         ;
19206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19207         ;
19208       else if (unformat (i, "del"))
19209         enable = 0;
19210       else
19211         break;
19212     }
19213
19214   if (sw_if_index == ~0)
19215     {
19216       errmsg ("missing interface name or sw_if_index");
19217       return -99;
19218     }
19219
19220   if (enable && (tag == 0))
19221     {
19222       errmsg ("no tag specified");
19223       return -99;
19224     }
19225
19226   /* Construct the API message */
19227   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19228   mp->sw_if_index = ntohl (sw_if_index);
19229   mp->is_add = enable;
19230   if (enable)
19231     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19232   vec_free (tag);
19233
19234   S (mp);
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static int
19240 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19241 {
19242   unformat_input_t *i = vam->input;
19243   vl_api_mac_address_t mac = { 0 };
19244   vl_api_sw_interface_add_del_mac_address_t *mp;
19245   u32 sw_if_index = ~0;
19246   u8 is_add = 1;
19247   u8 mac_set = 0;
19248   int ret;
19249
19250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19253         ;
19254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19255         ;
19256       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19257         mac_set++;
19258       else if (unformat (i, "del"))
19259         is_add = 0;
19260       else
19261         break;
19262     }
19263
19264   if (sw_if_index == ~0)
19265     {
19266       errmsg ("missing interface name or sw_if_index");
19267       return -99;
19268     }
19269
19270   if (!mac_set)
19271     {
19272       errmsg ("missing MAC address");
19273       return -99;
19274     }
19275
19276   /* Construct the API message */
19277   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19278   mp->sw_if_index = ntohl (sw_if_index);
19279   mp->is_add = is_add;
19280   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19281
19282   S (mp);
19283   W (ret);
19284   return ret;
19285 }
19286
19287 static void vl_api_l2_xconnect_details_t_handler
19288   (vl_api_l2_xconnect_details_t * mp)
19289 {
19290   vat_main_t *vam = &vat_main;
19291
19292   print (vam->ofp, "%15d%15d",
19293          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19294 }
19295
19296 static void vl_api_l2_xconnect_details_t_handler_json
19297   (vl_api_l2_xconnect_details_t * mp)
19298 {
19299   vat_main_t *vam = &vat_main;
19300   vat_json_node_t *node = NULL;
19301
19302   if (VAT_JSON_ARRAY != vam->json_tree.type)
19303     {
19304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19305       vat_json_init_array (&vam->json_tree);
19306     }
19307   node = vat_json_array_add (&vam->json_tree);
19308
19309   vat_json_init_object (node);
19310   vat_json_object_add_uint (node, "rx_sw_if_index",
19311                             ntohl (mp->rx_sw_if_index));
19312   vat_json_object_add_uint (node, "tx_sw_if_index",
19313                             ntohl (mp->tx_sw_if_index));
19314 }
19315
19316 static int
19317 api_l2_xconnect_dump (vat_main_t * vam)
19318 {
19319   vl_api_l2_xconnect_dump_t *mp;
19320   vl_api_control_ping_t *mp_ping;
19321   int ret;
19322
19323   if (!vam->json_output)
19324     {
19325       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19326     }
19327
19328   M (L2_XCONNECT_DUMP, mp);
19329
19330   S (mp);
19331
19332   /* Use a control ping for synchronization */
19333   MPING (CONTROL_PING, mp_ping);
19334   S (mp_ping);
19335
19336   W (ret);
19337   return ret;
19338 }
19339
19340 static int
19341 api_hw_interface_set_mtu (vat_main_t * vam)
19342 {
19343   unformat_input_t *i = vam->input;
19344   vl_api_hw_interface_set_mtu_t *mp;
19345   u32 sw_if_index = ~0;
19346   u32 mtu = 0;
19347   int ret;
19348
19349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19350     {
19351       if (unformat (i, "mtu %d", &mtu))
19352         ;
19353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19354         ;
19355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19356         ;
19357       else
19358         break;
19359     }
19360
19361   if (sw_if_index == ~0)
19362     {
19363       errmsg ("missing interface name or sw_if_index");
19364       return -99;
19365     }
19366
19367   if (mtu == 0)
19368     {
19369       errmsg ("no mtu specified");
19370       return -99;
19371     }
19372
19373   /* Construct the API message */
19374   M (HW_INTERFACE_SET_MTU, mp);
19375   mp->sw_if_index = ntohl (sw_if_index);
19376   mp->mtu = ntohs ((u16) mtu);
19377
19378   S (mp);
19379   W (ret);
19380   return ret;
19381 }
19382
19383 static int
19384 api_p2p_ethernet_add (vat_main_t * vam)
19385 {
19386   unformat_input_t *i = vam->input;
19387   vl_api_p2p_ethernet_add_t *mp;
19388   u32 parent_if_index = ~0;
19389   u32 sub_id = ~0;
19390   u8 remote_mac[6];
19391   u8 mac_set = 0;
19392   int ret;
19393
19394   clib_memset (remote_mac, 0, sizeof (remote_mac));
19395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19396     {
19397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19398         ;
19399       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19400         ;
19401       else
19402         if (unformat
19403             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19404         mac_set++;
19405       else if (unformat (i, "sub_id %d", &sub_id))
19406         ;
19407       else
19408         {
19409           clib_warning ("parse error '%U'", format_unformat_error, i);
19410           return -99;
19411         }
19412     }
19413
19414   if (parent_if_index == ~0)
19415     {
19416       errmsg ("missing interface name or sw_if_index");
19417       return -99;
19418     }
19419   if (mac_set == 0)
19420     {
19421       errmsg ("missing remote mac address");
19422       return -99;
19423     }
19424   if (sub_id == ~0)
19425     {
19426       errmsg ("missing sub-interface id");
19427       return -99;
19428     }
19429
19430   M (P2P_ETHERNET_ADD, mp);
19431   mp->parent_if_index = ntohl (parent_if_index);
19432   mp->subif_id = ntohl (sub_id);
19433   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19434
19435   S (mp);
19436   W (ret);
19437   return ret;
19438 }
19439
19440 static int
19441 api_p2p_ethernet_del (vat_main_t * vam)
19442 {
19443   unformat_input_t *i = vam->input;
19444   vl_api_p2p_ethernet_del_t *mp;
19445   u32 parent_if_index = ~0;
19446   u8 remote_mac[6];
19447   u8 mac_set = 0;
19448   int ret;
19449
19450   clib_memset (remote_mac, 0, sizeof (remote_mac));
19451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19452     {
19453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19454         ;
19455       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19456         ;
19457       else
19458         if (unformat
19459             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19460         mac_set++;
19461       else
19462         {
19463           clib_warning ("parse error '%U'", format_unformat_error, i);
19464           return -99;
19465         }
19466     }
19467
19468   if (parent_if_index == ~0)
19469     {
19470       errmsg ("missing interface name or sw_if_index");
19471       return -99;
19472     }
19473   if (mac_set == 0)
19474     {
19475       errmsg ("missing remote mac address");
19476       return -99;
19477     }
19478
19479   M (P2P_ETHERNET_DEL, mp);
19480   mp->parent_if_index = ntohl (parent_if_index);
19481   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19482
19483   S (mp);
19484   W (ret);
19485   return ret;
19486 }
19487
19488 static int
19489 api_lldp_config (vat_main_t * vam)
19490 {
19491   unformat_input_t *i = vam->input;
19492   vl_api_lldp_config_t *mp;
19493   int tx_hold = 0;
19494   int tx_interval = 0;
19495   u8 *sys_name = NULL;
19496   int ret;
19497
19498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19499     {
19500       if (unformat (i, "system-name %s", &sys_name))
19501         ;
19502       else if (unformat (i, "tx-hold %d", &tx_hold))
19503         ;
19504       else if (unformat (i, "tx-interval %d", &tx_interval))
19505         ;
19506       else
19507         {
19508           clib_warning ("parse error '%U'", format_unformat_error, i);
19509           return -99;
19510         }
19511     }
19512
19513   vec_add1 (sys_name, 0);
19514
19515   M (LLDP_CONFIG, mp);
19516   mp->tx_hold = htonl (tx_hold);
19517   mp->tx_interval = htonl (tx_interval);
19518   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19519   vec_free (sys_name);
19520
19521   S (mp);
19522   W (ret);
19523   return ret;
19524 }
19525
19526 static int
19527 api_sw_interface_set_lldp (vat_main_t * vam)
19528 {
19529   unformat_input_t *i = vam->input;
19530   vl_api_sw_interface_set_lldp_t *mp;
19531   u32 sw_if_index = ~0;
19532   u32 enable = 1;
19533   u8 *port_desc = NULL, *mgmt_oid = NULL;
19534   ip4_address_t ip4_addr;
19535   ip6_address_t ip6_addr;
19536   int ret;
19537
19538   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19539   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19540
19541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19542     {
19543       if (unformat (i, "disable"))
19544         enable = 0;
19545       else
19546         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19547         ;
19548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19549         ;
19550       else if (unformat (i, "port-desc %s", &port_desc))
19551         ;
19552       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19553         ;
19554       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19555         ;
19556       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19557         ;
19558       else
19559         break;
19560     }
19561
19562   if (sw_if_index == ~0)
19563     {
19564       errmsg ("missing interface name or sw_if_index");
19565       return -99;
19566     }
19567
19568   /* Construct the API message */
19569   vec_add1 (port_desc, 0);
19570   vec_add1 (mgmt_oid, 0);
19571   M (SW_INTERFACE_SET_LLDP, mp);
19572   mp->sw_if_index = ntohl (sw_if_index);
19573   mp->enable = enable;
19574   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19575   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19576   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19577   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19578   vec_free (port_desc);
19579   vec_free (mgmt_oid);
19580
19581   S (mp);
19582   W (ret);
19583   return ret;
19584 }
19585
19586 static int
19587 api_tcp_configure_src_addresses (vat_main_t * vam)
19588 {
19589   vl_api_tcp_configure_src_addresses_t *mp;
19590   unformat_input_t *i = vam->input;
19591   vl_api_address_t first, last;
19592   u8 range_set = 0;
19593   u32 vrf_id = 0;
19594   int ret;
19595
19596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19597     {
19598       if (unformat (i, "%U - %U",
19599                     unformat_vl_api_address, &first,
19600                     unformat_vl_api_address, &last))
19601         {
19602           if (range_set)
19603             {
19604               errmsg ("one range per message (range already set)");
19605               return -99;
19606             }
19607           range_set = 1;
19608         }
19609       else if (unformat (i, "vrf %d", &vrf_id))
19610         ;
19611       else
19612         break;
19613     }
19614
19615   if (range_set == 0)
19616     {
19617       errmsg ("address range not set");
19618       return -99;
19619     }
19620
19621   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19622
19623   mp->vrf_id = ntohl (vrf_id);
19624   clib_memcpy (&mp->first_address, &first, sizeof (first));
19625   clib_memcpy (&mp->last_address, &last, sizeof (last));
19626
19627   S (mp);
19628   W (ret);
19629   return ret;
19630 }
19631
19632 static void vl_api_app_namespace_add_del_reply_t_handler
19633   (vl_api_app_namespace_add_del_reply_t * mp)
19634 {
19635   vat_main_t *vam = &vat_main;
19636   i32 retval = ntohl (mp->retval);
19637   if (vam->async_mode)
19638     {
19639       vam->async_errors += (retval < 0);
19640     }
19641   else
19642     {
19643       vam->retval = retval;
19644       if (retval == 0)
19645         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19646       vam->result_ready = 1;
19647     }
19648 }
19649
19650 static void vl_api_app_namespace_add_del_reply_t_handler_json
19651   (vl_api_app_namespace_add_del_reply_t * mp)
19652 {
19653   vat_main_t *vam = &vat_main;
19654   vat_json_node_t node;
19655
19656   vat_json_init_object (&node);
19657   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19658   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19659
19660   vat_json_print (vam->ofp, &node);
19661   vat_json_free (&node);
19662
19663   vam->retval = ntohl (mp->retval);
19664   vam->result_ready = 1;
19665 }
19666
19667 static int
19668 api_app_namespace_add_del (vat_main_t * vam)
19669 {
19670   vl_api_app_namespace_add_del_t *mp;
19671   unformat_input_t *i = vam->input;
19672   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19673   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19674   u64 secret;
19675   int ret;
19676
19677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19678     {
19679       if (unformat (i, "id %_%v%_", &ns_id))
19680         ;
19681       else if (unformat (i, "secret %lu", &secret))
19682         secret_set = 1;
19683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19684         sw_if_index_set = 1;
19685       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19686         ;
19687       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19688         ;
19689       else
19690         break;
19691     }
19692   if (!ns_id || !secret_set || !sw_if_index_set)
19693     {
19694       errmsg ("namespace id, secret and sw_if_index must be set");
19695       return -99;
19696     }
19697   if (vec_len (ns_id) > 64)
19698     {
19699       errmsg ("namespace id too long");
19700       return -99;
19701     }
19702   M (APP_NAMESPACE_ADD_DEL, mp);
19703
19704   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19705   mp->secret = clib_host_to_net_u64 (secret);
19706   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19707   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19708   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19709   vec_free (ns_id);
19710   S (mp);
19711   W (ret);
19712   return ret;
19713 }
19714
19715 static int
19716 api_sock_init_shm (vat_main_t * vam)
19717 {
19718 #if VPP_API_TEST_BUILTIN == 0
19719   unformat_input_t *i = vam->input;
19720   vl_api_shm_elem_config_t *config = 0;
19721   u64 size = 64 << 20;
19722   int rv;
19723
19724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19725     {
19726       if (unformat (i, "size %U", unformat_memory_size, &size))
19727         ;
19728       else
19729         break;
19730     }
19731
19732   /*
19733    * Canned custom ring allocator config.
19734    * Should probably parse all of this
19735    */
19736   vec_validate (config, 6);
19737   config[0].type = VL_API_VLIB_RING;
19738   config[0].size = 256;
19739   config[0].count = 32;
19740
19741   config[1].type = VL_API_VLIB_RING;
19742   config[1].size = 1024;
19743   config[1].count = 16;
19744
19745   config[2].type = VL_API_VLIB_RING;
19746   config[2].size = 4096;
19747   config[2].count = 2;
19748
19749   config[3].type = VL_API_CLIENT_RING;
19750   config[3].size = 256;
19751   config[3].count = 32;
19752
19753   config[4].type = VL_API_CLIENT_RING;
19754   config[4].size = 1024;
19755   config[4].count = 16;
19756
19757   config[5].type = VL_API_CLIENT_RING;
19758   config[5].size = 4096;
19759   config[5].count = 2;
19760
19761   config[6].type = VL_API_QUEUE;
19762   config[6].count = 128;
19763   config[6].size = sizeof (uword);
19764
19765   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19766   if (!rv)
19767     vam->client_index_invalid = 1;
19768   return rv;
19769 #else
19770   return -99;
19771 #endif
19772 }
19773
19774 static void
19775 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19776 {
19777   vat_main_t *vam = &vat_main;
19778   fib_prefix_t lcl, rmt;
19779
19780   ip_prefix_decode (&mp->lcl, &lcl);
19781   ip_prefix_decode (&mp->rmt, &rmt);
19782
19783   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19784     {
19785       print (vam->ofp,
19786              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19787              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19788              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19789              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19790              &rmt.fp_addr.ip4, rmt.fp_len,
19791              clib_net_to_host_u16 (mp->rmt_port),
19792              clib_net_to_host_u32 (mp->action_index), mp->tag);
19793     }
19794   else
19795     {
19796       print (vam->ofp,
19797              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19798              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19799              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19800              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19801              &rmt.fp_addr.ip6, rmt.fp_len,
19802              clib_net_to_host_u16 (mp->rmt_port),
19803              clib_net_to_host_u32 (mp->action_index), mp->tag);
19804     }
19805 }
19806
19807 static void
19808 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19809                                              mp)
19810 {
19811   vat_main_t *vam = &vat_main;
19812   vat_json_node_t *node = NULL;
19813   struct in6_addr ip6;
19814   struct in_addr ip4;
19815
19816   fib_prefix_t lcl, rmt;
19817
19818   ip_prefix_decode (&mp->lcl, &lcl);
19819   ip_prefix_decode (&mp->rmt, &rmt);
19820
19821   if (VAT_JSON_ARRAY != vam->json_tree.type)
19822     {
19823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19824       vat_json_init_array (&vam->json_tree);
19825     }
19826   node = vat_json_array_add (&vam->json_tree);
19827   vat_json_init_object (node);
19828
19829   vat_json_object_add_uint (node, "appns_index",
19830                             clib_net_to_host_u32 (mp->appns_index));
19831   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19832   vat_json_object_add_uint (node, "scope", mp->scope);
19833   vat_json_object_add_uint (node, "action_index",
19834                             clib_net_to_host_u32 (mp->action_index));
19835   vat_json_object_add_uint (node, "lcl_port",
19836                             clib_net_to_host_u16 (mp->lcl_port));
19837   vat_json_object_add_uint (node, "rmt_port",
19838                             clib_net_to_host_u16 (mp->rmt_port));
19839   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19840   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19841   vat_json_object_add_string_copy (node, "tag", mp->tag);
19842   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19843     {
19844       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19845       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19846       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19847       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19848     }
19849   else
19850     {
19851       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19852       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19853       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19854       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19855     }
19856 }
19857
19858 static int
19859 api_session_rule_add_del (vat_main_t * vam)
19860 {
19861   vl_api_session_rule_add_del_t *mp;
19862   unformat_input_t *i = vam->input;
19863   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19864   u32 appns_index = 0, scope = 0;
19865   ip4_address_t lcl_ip4, rmt_ip4;
19866   ip6_address_t lcl_ip6, rmt_ip6;
19867   u8 is_ip4 = 1, conn_set = 0;
19868   u8 is_add = 1, *tag = 0;
19869   int ret;
19870   fib_prefix_t lcl, rmt;
19871
19872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19873     {
19874       if (unformat (i, "del"))
19875         is_add = 0;
19876       else if (unformat (i, "add"))
19877         ;
19878       else if (unformat (i, "proto tcp"))
19879         proto = 0;
19880       else if (unformat (i, "proto udp"))
19881         proto = 1;
19882       else if (unformat (i, "appns %d", &appns_index))
19883         ;
19884       else if (unformat (i, "scope %d", &scope))
19885         ;
19886       else if (unformat (i, "tag %_%v%_", &tag))
19887         ;
19888       else
19889         if (unformat
19890             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19891              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19892              &rmt_port))
19893         {
19894           is_ip4 = 1;
19895           conn_set = 1;
19896         }
19897       else
19898         if (unformat
19899             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19900              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19901              &rmt_port))
19902         {
19903           is_ip4 = 0;
19904           conn_set = 1;
19905         }
19906       else if (unformat (i, "action %d", &action))
19907         ;
19908       else
19909         break;
19910     }
19911   if (proto == ~0 || !conn_set || action == ~0)
19912     {
19913       errmsg ("transport proto, connection and action must be set");
19914       return -99;
19915     }
19916
19917   if (scope > 3)
19918     {
19919       errmsg ("scope should be 0-3");
19920       return -99;
19921     }
19922
19923   M (SESSION_RULE_ADD_DEL, mp);
19924
19925   clib_memset (&lcl, 0, sizeof (lcl));
19926   clib_memset (&rmt, 0, sizeof (rmt));
19927   if (is_ip4)
19928     {
19929       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19930       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19931       lcl.fp_len = lcl_plen;
19932       rmt.fp_len = rmt_plen;
19933     }
19934   else
19935     {
19936       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19937       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19938       lcl.fp_len = lcl_plen;
19939       rmt.fp_len = rmt_plen;
19940     }
19941
19942
19943   ip_prefix_encode (&lcl, &mp->lcl);
19944   ip_prefix_encode (&rmt, &mp->rmt);
19945   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19946   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19947   mp->transport_proto =
19948     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19949   mp->action_index = clib_host_to_net_u32 (action);
19950   mp->appns_index = clib_host_to_net_u32 (appns_index);
19951   mp->scope = scope;
19952   mp->is_add = is_add;
19953   if (tag)
19954     {
19955       clib_memcpy (mp->tag, tag, vec_len (tag));
19956       vec_free (tag);
19957     }
19958
19959   S (mp);
19960   W (ret);
19961   return ret;
19962 }
19963
19964 static int
19965 api_session_rules_dump (vat_main_t * vam)
19966 {
19967   vl_api_session_rules_dump_t *mp;
19968   vl_api_control_ping_t *mp_ping;
19969   int ret;
19970
19971   if (!vam->json_output)
19972     {
19973       print (vam->ofp, "%=20s", "Session Rules");
19974     }
19975
19976   M (SESSION_RULES_DUMP, mp);
19977   /* send it... */
19978   S (mp);
19979
19980   /* Use a control ping for synchronization */
19981   MPING (CONTROL_PING, mp_ping);
19982   S (mp_ping);
19983
19984   /* Wait for a reply... */
19985   W (ret);
19986   return ret;
19987 }
19988
19989 static int
19990 api_ip_container_proxy_add_del (vat_main_t * vam)
19991 {
19992   vl_api_ip_container_proxy_add_del_t *mp;
19993   unformat_input_t *i = vam->input;
19994   u32 sw_if_index = ~0;
19995   vl_api_prefix_t pfx = { };
19996   u8 is_add = 1;
19997   int ret;
19998
19999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20000     {
20001       if (unformat (i, "del"))
20002         is_add = 0;
20003       else if (unformat (i, "add"))
20004         ;
20005       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20006         ;
20007       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20008         ;
20009       else
20010         break;
20011     }
20012   if (sw_if_index == ~0 || pfx.len == 0)
20013     {
20014       errmsg ("address and sw_if_index must be set");
20015       return -99;
20016     }
20017
20018   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20019
20020   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20021   mp->is_add = is_add;
20022   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20023
20024   S (mp);
20025   W (ret);
20026   return ret;
20027 }
20028
20029 static int
20030 api_qos_record_enable_disable (vat_main_t * vam)
20031 {
20032   unformat_input_t *i = vam->input;
20033   vl_api_qos_record_enable_disable_t *mp;
20034   u32 sw_if_index, qs = 0xff;
20035   u8 sw_if_index_set = 0;
20036   u8 enable = 1;
20037   int ret;
20038
20039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20040     {
20041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20042         sw_if_index_set = 1;
20043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20044         sw_if_index_set = 1;
20045       else if (unformat (i, "%U", unformat_qos_source, &qs))
20046         ;
20047       else if (unformat (i, "disable"))
20048         enable = 0;
20049       else
20050         {
20051           clib_warning ("parse error '%U'", format_unformat_error, i);
20052           return -99;
20053         }
20054     }
20055
20056   if (sw_if_index_set == 0)
20057     {
20058       errmsg ("missing interface name or sw_if_index");
20059       return -99;
20060     }
20061   if (qs == 0xff)
20062     {
20063       errmsg ("input location must be specified");
20064       return -99;
20065     }
20066
20067   M (QOS_RECORD_ENABLE_DISABLE, mp);
20068
20069   mp->record.sw_if_index = ntohl (sw_if_index);
20070   mp->record.input_source = qs;
20071   mp->enable = enable;
20072
20073   S (mp);
20074   W (ret);
20075   return ret;
20076 }
20077
20078
20079 static int
20080 q_or_quit (vat_main_t * vam)
20081 {
20082 #if VPP_API_TEST_BUILTIN == 0
20083   longjmp (vam->jump_buf, 1);
20084 #endif
20085   return 0;                     /* not so much */
20086 }
20087
20088 static int
20089 q (vat_main_t * vam)
20090 {
20091   return q_or_quit (vam);
20092 }
20093
20094 static int
20095 quit (vat_main_t * vam)
20096 {
20097   return q_or_quit (vam);
20098 }
20099
20100 static int
20101 comment (vat_main_t * vam)
20102 {
20103   return 0;
20104 }
20105
20106 static int
20107 elog_save (vat_main_t * vam)
20108 {
20109 #if VPP_API_TEST_BUILTIN == 0
20110   elog_main_t *em = &vam->elog_main;
20111   unformat_input_t *i = vam->input;
20112   char *file, *chroot_file;
20113   clib_error_t *error;
20114
20115   if (!unformat (i, "%s", &file))
20116     {
20117       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20118       return 0;
20119     }
20120
20121   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20122   if (strstr (file, "..") || index (file, '/'))
20123     {
20124       errmsg ("illegal characters in filename '%s'", file);
20125       return 0;
20126     }
20127
20128   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20129
20130   vec_free (file);
20131
20132   errmsg ("Saving %wd of %wd events to %s",
20133           elog_n_events_in_buffer (em),
20134           elog_buffer_capacity (em), chroot_file);
20135
20136   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20137   vec_free (chroot_file);
20138
20139   if (error)
20140     clib_error_report (error);
20141 #else
20142   errmsg ("Use the vpp event loger...");
20143 #endif
20144
20145   return 0;
20146 }
20147
20148 static int
20149 elog_setup (vat_main_t * vam)
20150 {
20151 #if VPP_API_TEST_BUILTIN == 0
20152   elog_main_t *em = &vam->elog_main;
20153   unformat_input_t *i = vam->input;
20154   u32 nevents = 128 << 10;
20155
20156   (void) unformat (i, "nevents %d", &nevents);
20157
20158   elog_init (em, nevents);
20159   vl_api_set_elog_main (em);
20160   vl_api_set_elog_trace_api_messages (1);
20161   errmsg ("Event logger initialized with %u events", nevents);
20162 #else
20163   errmsg ("Use the vpp event loger...");
20164 #endif
20165   return 0;
20166 }
20167
20168 static int
20169 elog_enable (vat_main_t * vam)
20170 {
20171 #if VPP_API_TEST_BUILTIN == 0
20172   elog_main_t *em = &vam->elog_main;
20173
20174   elog_enable_disable (em, 1 /* enable */ );
20175   vl_api_set_elog_trace_api_messages (1);
20176   errmsg ("Event logger enabled...");
20177 #else
20178   errmsg ("Use the vpp event loger...");
20179 #endif
20180   return 0;
20181 }
20182
20183 static int
20184 elog_disable (vat_main_t * vam)
20185 {
20186 #if VPP_API_TEST_BUILTIN == 0
20187   elog_main_t *em = &vam->elog_main;
20188
20189   elog_enable_disable (em, 0 /* enable */ );
20190   vl_api_set_elog_trace_api_messages (1);
20191   errmsg ("Event logger disabled...");
20192 #else
20193   errmsg ("Use the vpp event loger...");
20194 #endif
20195   return 0;
20196 }
20197
20198 static int
20199 statseg (vat_main_t * vam)
20200 {
20201   ssvm_private_t *ssvmp = &vam->stat_segment;
20202   ssvm_shared_header_t *shared_header = ssvmp->sh;
20203   vlib_counter_t **counters;
20204   u64 thread0_index1_packets;
20205   u64 thread0_index1_bytes;
20206   f64 vector_rate, input_rate;
20207   uword *p;
20208
20209   uword *counter_vector_by_name;
20210   if (vam->stat_segment_lockp == 0)
20211     {
20212       errmsg ("Stat segment not mapped...");
20213       return -99;
20214     }
20215
20216   /* look up "/if/rx for sw_if_index 1 as a test */
20217
20218   clib_spinlock_lock (vam->stat_segment_lockp);
20219
20220   counter_vector_by_name = (uword *) shared_header->opaque[1];
20221
20222   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20223   if (p == 0)
20224     {
20225       clib_spinlock_unlock (vam->stat_segment_lockp);
20226       errmsg ("/if/tx not found?");
20227       return -99;
20228     }
20229
20230   /* Fish per-thread vector of combined counters from shared memory */
20231   counters = (vlib_counter_t **) p[0];
20232
20233   if (vec_len (counters[0]) < 2)
20234     {
20235       clib_spinlock_unlock (vam->stat_segment_lockp);
20236       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20237       return -99;
20238     }
20239
20240   /* Read thread 0 sw_if_index 1 counter */
20241   thread0_index1_packets = counters[0][1].packets;
20242   thread0_index1_bytes = counters[0][1].bytes;
20243
20244   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20245   if (p == 0)
20246     {
20247       clib_spinlock_unlock (vam->stat_segment_lockp);
20248       errmsg ("vector_rate not found?");
20249       return -99;
20250     }
20251
20252   vector_rate = *(f64 *) (p[0]);
20253   p = hash_get_mem (counter_vector_by_name, "input_rate");
20254   if (p == 0)
20255     {
20256       clib_spinlock_unlock (vam->stat_segment_lockp);
20257       errmsg ("input_rate not found?");
20258       return -99;
20259     }
20260   input_rate = *(f64 *) (p[0]);
20261
20262   clib_spinlock_unlock (vam->stat_segment_lockp);
20263
20264   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20265          vector_rate, input_rate);
20266   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20267          thread0_index1_packets, thread0_index1_bytes);
20268
20269   return 0;
20270 }
20271
20272 static int
20273 cmd_cmp (void *a1, void *a2)
20274 {
20275   u8 **c1 = a1;
20276   u8 **c2 = a2;
20277
20278   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20279 }
20280
20281 static int
20282 help (vat_main_t * vam)
20283 {
20284   u8 **cmds = 0;
20285   u8 *name = 0;
20286   hash_pair_t *p;
20287   unformat_input_t *i = vam->input;
20288   int j;
20289
20290   if (unformat (i, "%s", &name))
20291     {
20292       uword *hs;
20293
20294       vec_add1 (name, 0);
20295
20296       hs = hash_get_mem (vam->help_by_name, name);
20297       if (hs)
20298         print (vam->ofp, "usage: %s %s", name, hs[0]);
20299       else
20300         print (vam->ofp, "No such msg / command '%s'", name);
20301       vec_free (name);
20302       return 0;
20303     }
20304
20305   print (vam->ofp, "Help is available for the following:");
20306
20307     /* *INDENT-OFF* */
20308     hash_foreach_pair (p, vam->function_by_name,
20309     ({
20310       vec_add1 (cmds, (u8 *)(p->key));
20311     }));
20312     /* *INDENT-ON* */
20313
20314   vec_sort_with_function (cmds, cmd_cmp);
20315
20316   for (j = 0; j < vec_len (cmds); j++)
20317     print (vam->ofp, "%s", cmds[j]);
20318
20319   vec_free (cmds);
20320   return 0;
20321 }
20322
20323 static int
20324 set (vat_main_t * vam)
20325 {
20326   u8 *name = 0, *value = 0;
20327   unformat_input_t *i = vam->input;
20328
20329   if (unformat (i, "%s", &name))
20330     {
20331       /* The input buffer is a vector, not a string. */
20332       value = vec_dup (i->buffer);
20333       vec_delete (value, i->index, 0);
20334       /* Almost certainly has a trailing newline */
20335       if (value[vec_len (value) - 1] == '\n')
20336         value[vec_len (value) - 1] = 0;
20337       /* Make sure it's a proper string, one way or the other */
20338       vec_add1 (value, 0);
20339       (void) clib_macro_set_value (&vam->macro_main,
20340                                    (char *) name, (char *) value);
20341     }
20342   else
20343     errmsg ("usage: set <name> <value>");
20344
20345   vec_free (name);
20346   vec_free (value);
20347   return 0;
20348 }
20349
20350 static int
20351 unset (vat_main_t * vam)
20352 {
20353   u8 *name = 0;
20354
20355   if (unformat (vam->input, "%s", &name))
20356     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20357       errmsg ("unset: %s wasn't set", name);
20358   vec_free (name);
20359   return 0;
20360 }
20361
20362 typedef struct
20363 {
20364   u8 *name;
20365   u8 *value;
20366 } macro_sort_t;
20367
20368
20369 static int
20370 macro_sort_cmp (void *a1, void *a2)
20371 {
20372   macro_sort_t *s1 = a1;
20373   macro_sort_t *s2 = a2;
20374
20375   return strcmp ((char *) (s1->name), (char *) (s2->name));
20376 }
20377
20378 static int
20379 dump_macro_table (vat_main_t * vam)
20380 {
20381   macro_sort_t *sort_me = 0, *sm;
20382   int i;
20383   hash_pair_t *p;
20384
20385     /* *INDENT-OFF* */
20386     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20387     ({
20388       vec_add2 (sort_me, sm, 1);
20389       sm->name = (u8 *)(p->key);
20390       sm->value = (u8 *) (p->value[0]);
20391     }));
20392     /* *INDENT-ON* */
20393
20394   vec_sort_with_function (sort_me, macro_sort_cmp);
20395
20396   if (vec_len (sort_me))
20397     print (vam->ofp, "%-15s%s", "Name", "Value");
20398   else
20399     print (vam->ofp, "The macro table is empty...");
20400
20401   for (i = 0; i < vec_len (sort_me); i++)
20402     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20403   return 0;
20404 }
20405
20406 static int
20407 dump_node_table (vat_main_t * vam)
20408 {
20409   int i, j;
20410   vlib_node_t *node, *next_node;
20411
20412   if (vec_len (vam->graph_nodes) == 0)
20413     {
20414       print (vam->ofp, "Node table empty, issue get_node_graph...");
20415       return 0;
20416     }
20417
20418   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20419     {
20420       node = vam->graph_nodes[0][i];
20421       print (vam->ofp, "[%d] %s", i, node->name);
20422       for (j = 0; j < vec_len (node->next_nodes); j++)
20423         {
20424           if (node->next_nodes[j] != ~0)
20425             {
20426               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20427               print (vam->ofp, "  [%d] %s", j, next_node->name);
20428             }
20429         }
20430     }
20431   return 0;
20432 }
20433
20434 static int
20435 value_sort_cmp (void *a1, void *a2)
20436 {
20437   name_sort_t *n1 = a1;
20438   name_sort_t *n2 = a2;
20439
20440   if (n1->value < n2->value)
20441     return -1;
20442   if (n1->value > n2->value)
20443     return 1;
20444   return 0;
20445 }
20446
20447
20448 static int
20449 dump_msg_api_table (vat_main_t * vam)
20450 {
20451   api_main_t *am = vlibapi_get_main ();
20452   name_sort_t *nses = 0, *ns;
20453   hash_pair_t *hp;
20454   int i;
20455
20456   /* *INDENT-OFF* */
20457   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20458   ({
20459     vec_add2 (nses, ns, 1);
20460     ns->name = (u8 *)(hp->key);
20461     ns->value = (u32) hp->value[0];
20462   }));
20463   /* *INDENT-ON* */
20464
20465   vec_sort_with_function (nses, value_sort_cmp);
20466
20467   for (i = 0; i < vec_len (nses); i++)
20468     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20469   vec_free (nses);
20470   return 0;
20471 }
20472
20473 static int
20474 get_msg_id (vat_main_t * vam)
20475 {
20476   u8 *name_and_crc;
20477   u32 message_index;
20478
20479   if (unformat (vam->input, "%s", &name_and_crc))
20480     {
20481       message_index = vl_msg_api_get_msg_index (name_and_crc);
20482       if (message_index == ~0)
20483         {
20484           print (vam->ofp, " '%s' not found", name_and_crc);
20485           return 0;
20486         }
20487       print (vam->ofp, " '%s' has message index %d",
20488              name_and_crc, message_index);
20489       return 0;
20490     }
20491   errmsg ("name_and_crc required...");
20492   return 0;
20493 }
20494
20495 static int
20496 search_node_table (vat_main_t * vam)
20497 {
20498   unformat_input_t *line_input = vam->input;
20499   u8 *node_to_find;
20500   int j;
20501   vlib_node_t *node, *next_node;
20502   uword *p;
20503
20504   if (vam->graph_node_index_by_name == 0)
20505     {
20506       print (vam->ofp, "Node table empty, issue get_node_graph...");
20507       return 0;
20508     }
20509
20510   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20511     {
20512       if (unformat (line_input, "%s", &node_to_find))
20513         {
20514           vec_add1 (node_to_find, 0);
20515           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20516           if (p == 0)
20517             {
20518               print (vam->ofp, "%s not found...", node_to_find);
20519               goto out;
20520             }
20521           node = vam->graph_nodes[0][p[0]];
20522           print (vam->ofp, "[%d] %s", p[0], node->name);
20523           for (j = 0; j < vec_len (node->next_nodes); j++)
20524             {
20525               if (node->next_nodes[j] != ~0)
20526                 {
20527                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20528                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20529                 }
20530             }
20531         }
20532
20533       else
20534         {
20535           clib_warning ("parse error '%U'", format_unformat_error,
20536                         line_input);
20537           return -99;
20538         }
20539
20540     out:
20541       vec_free (node_to_find);
20542
20543     }
20544
20545   return 0;
20546 }
20547
20548
20549 static int
20550 script (vat_main_t * vam)
20551 {
20552 #if (VPP_API_TEST_BUILTIN==0)
20553   u8 *s = 0;
20554   char *save_current_file;
20555   unformat_input_t save_input;
20556   jmp_buf save_jump_buf;
20557   u32 save_line_number;
20558
20559   FILE *new_fp, *save_ifp;
20560
20561   if (unformat (vam->input, "%s", &s))
20562     {
20563       new_fp = fopen ((char *) s, "r");
20564       if (new_fp == 0)
20565         {
20566           errmsg ("Couldn't open script file %s", s);
20567           vec_free (s);
20568           return -99;
20569         }
20570     }
20571   else
20572     {
20573       errmsg ("Missing script name");
20574       return -99;
20575     }
20576
20577   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20578   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20579   save_ifp = vam->ifp;
20580   save_line_number = vam->input_line_number;
20581   save_current_file = (char *) vam->current_file;
20582
20583   vam->input_line_number = 0;
20584   vam->ifp = new_fp;
20585   vam->current_file = s;
20586   do_one_file (vam);
20587
20588   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20589   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20590   vam->ifp = save_ifp;
20591   vam->input_line_number = save_line_number;
20592   vam->current_file = (u8 *) save_current_file;
20593   vec_free (s);
20594
20595   return 0;
20596 #else
20597   clib_warning ("use the exec command...");
20598   return -99;
20599 #endif
20600 }
20601
20602 static int
20603 echo (vat_main_t * vam)
20604 {
20605   print (vam->ofp, "%v", vam->input->buffer);
20606   return 0;
20607 }
20608
20609 /* List of API message constructors, CLI names map to api_xxx */
20610 #define foreach_vpe_api_msg                                             \
20611 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20612 _(sw_interface_dump,"")                                                 \
20613 _(sw_interface_set_flags,                                               \
20614   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20615 _(sw_interface_add_del_address,                                         \
20616   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20617 _(sw_interface_set_rx_mode,                                             \
20618   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20619 _(sw_interface_set_rx_placement,                                        \
20620   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20621 _(sw_interface_rx_placement_dump,                                       \
20622   "[<intfc> | sw_if_index <id>]")                                         \
20623 _(sw_interface_set_table,                                               \
20624   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20625 _(sw_interface_set_mpls_enable,                                         \
20626   "<intfc> | sw_if_index [disable | dis]")                              \
20627 _(sw_interface_set_vpath,                                               \
20628   "<intfc> | sw_if_index <id> enable | disable")                        \
20629 _(sw_interface_set_vxlan_bypass,                                        \
20630   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20631 _(sw_interface_set_geneve_bypass,                                       \
20632   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20633 _(sw_interface_set_l2_xconnect,                                         \
20634   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20635   "enable | disable")                                                   \
20636 _(sw_interface_set_l2_bridge,                                           \
20637   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20638   "[shg <split-horizon-group>] [bvi]\n"                                 \
20639   "enable | disable")                                                   \
20640 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20641 _(bridge_domain_add_del,                                                \
20642   "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") \
20643 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20644 _(l2fib_add_del,                                                        \
20645   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20646 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20647 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20648 _(l2_flags,                                                             \
20649   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20650 _(bridge_flags,                                                         \
20651   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20652 _(tap_create_v2,                                                        \
20653   "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]") \
20654 _(tap_delete_v2,                                                        \
20655   "<vpp-if-name> | sw_if_index <id>")                                   \
20656 _(sw_interface_tap_v2_dump, "")                                         \
20657 _(virtio_pci_create,                                                    \
20658   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20659 _(virtio_pci_delete,                                                    \
20660   "<vpp-if-name> | sw_if_index <id>")                                   \
20661 _(sw_interface_virtio_pci_dump, "")                                     \
20662 _(bond_create,                                                          \
20663   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20664   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20665   "[id <if-id>]")                                                       \
20666 _(bond_delete,                                                          \
20667   "<vpp-if-name> | sw_if_index <id>")                                   \
20668 _(bond_enslave,                                                         \
20669   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20670 _(bond_detach_slave,                                                    \
20671   "sw_if_index <n>")                                                    \
20672  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20673 _(sw_interface_bond_dump, "")                                           \
20674 _(sw_interface_slave_dump,                                              \
20675   "<vpp-if-name> | sw_if_index <id>")                                   \
20676 _(ip_table_add_del,                                                     \
20677   "table <n> [ipv6] [add | del]\n")                                     \
20678 _(ip_route_add_del,                                                     \
20679   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20680   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20681   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20682   "[multipath] [count <n>] [del]")                                      \
20683 _(ip_mroute_add_del,                                                    \
20684   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20685   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20686 _(mpls_table_add_del,                                                   \
20687   "table <n> [add | del]\n")                                            \
20688 _(mpls_route_add_del,                                                   \
20689   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20690   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20691   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20692   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20693   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20694   "[count <n>] [del]")                                                  \
20695 _(mpls_ip_bind_unbind,                                                  \
20696   "<label> <addr/len>")                                                 \
20697 _(mpls_tunnel_add_del,                                                  \
20698   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20699   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20700   "[l2-only]  [out-label <n>]")                                         \
20701 _(sr_mpls_policy_add,                                                   \
20702   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20703 _(sr_mpls_policy_del,                                                   \
20704   "bsid <id>")                                                          \
20705 _(bier_table_add_del,                                                   \
20706   "<label> <sub-domain> <set> <bsl> [del]")                             \
20707 _(bier_route_add_del,                                                   \
20708   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20709   "[<intfc> | sw_if_index <id>]"                                        \
20710   "[weight <n>] [del] [multipath]")                                     \
20711 _(sw_interface_set_unnumbered,                                          \
20712   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20713 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20714 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20715   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20716   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20717   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20718 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20719 _(ip_table_flush, "table <n> [ipv6]")                                   \
20720 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20721 _(set_ip_flow_hash,                                                     \
20722   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20723 _(sw_interface_ip6_enable_disable,                                      \
20724   "<intfc> | sw_if_index <id> enable | disable")                        \
20725 _(l2_patch_add_del,                                                     \
20726   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20727   "enable | disable")                                                   \
20728 _(sr_localsid_add_del,                                                  \
20729   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20730   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20731 _(classify_add_del_table,                                               \
20732   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20733   " [del] [del-chain] mask <mask-value>\n"                              \
20734   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20735   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20736 _(classify_add_del_session,                                             \
20737   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20738   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20739   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20740   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20741 _(classify_set_interface_ip_table,                                      \
20742   "<intfc> | sw_if_index <nn> table <nn>")                              \
20743 _(classify_set_interface_l2_tables,                                     \
20744   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20745   "  [other-table <nn>]")                                               \
20746 _(get_node_index, "node <node-name")                                    \
20747 _(add_node_next, "node <node-name> next <next-node-name>")              \
20748 _(l2tpv3_create_tunnel,                                                 \
20749   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20750   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20751   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20752 _(l2tpv3_set_tunnel_cookies,                                            \
20753   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20754   "[new_remote_cookie <nn>]\n")                                         \
20755 _(l2tpv3_interface_enable_disable,                                      \
20756   "<intfc> | sw_if_index <nn> enable | disable")                        \
20757 _(l2tpv3_set_lookup_key,                                                \
20758   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20759 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20760 _(vxlan_offload_rx,                                                     \
20761   "hw { <interface name> | hw_if_index <nn>} "                          \
20762   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20763 _(vxlan_add_del_tunnel,                                                 \
20764   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20765   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20766   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20767 _(geneve_add_del_tunnel,                                                \
20768   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20769   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20770   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20771 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20772 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20773 _(gre_tunnel_add_del,                                                   \
20774   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20775   "[teb | erspan <session-id>] [del]")                                  \
20776 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20777 _(l2_fib_clear_table, "")                                               \
20778 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20779 _(l2_interface_vlan_tag_rewrite,                                        \
20780   "<intfc> | sw_if_index <nn> \n"                                       \
20781   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20782   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20783 _(create_vhost_user_if,                                                 \
20784         "socket <filename> [server] [renumber <dev_instance>] "         \
20785         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20786         "[mac <mac_address>]")                                          \
20787 _(modify_vhost_user_if,                                                 \
20788         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20789         "[server] [renumber <dev_instance>] [gso]")                     \
20790 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20791 _(sw_interface_vhost_user_dump, "")                                     \
20792 _(show_version, "")                                                     \
20793 _(show_threads, "")                                                     \
20794 _(vxlan_gpe_add_del_tunnel,                                             \
20795   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20796   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20797   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20798   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20799 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20800 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20801 _(interface_name_renumber,                                              \
20802   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20803 _(input_acl_set_interface,                                              \
20804   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20805   "  [l2-table <nn>] [del]")                                            \
20806 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20807 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20808 _(ip_dump, "ipv4 | ipv6")                                               \
20809 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20810 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20811   "  spid_id <n> ")                                                     \
20812 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20813   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20814   "  integ_alg <alg> integ_key <hex>")                                  \
20815 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20816   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20817   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20818   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20819 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20820   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20821   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20822   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20823   "  [instance <n>]")     \
20824 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20825 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20826 _(delete_loopback,"sw_if_index <nn>")                                   \
20827 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20828 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20829 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20830 _(want_interface_events,  "enable|disable")                             \
20831 _(get_first_msg_id, "client <name>")                                    \
20832 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20833 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20834   "fib-id <nn> [ip4][ip6][default]")                                    \
20835 _(get_node_graph, " ")                                                  \
20836 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20837 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20838 _(ioam_disable, "")                                                     \
20839 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20840                             " sw_if_index <sw_if_index> p <priority> "  \
20841                             "w <weight>] [del]")                        \
20842 _(one_add_del_locator, "locator-set <locator_name> "                    \
20843                         "iface <intf> | sw_if_index <sw_if_index> "     \
20844                         "p <priority> w <weight> [del]")                \
20845 _(one_add_del_local_eid,"vni <vni> eid "                                \
20846                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20847                          "locator-set <locator_name> [del]"             \
20848                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20849 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20850 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20851 _(one_enable_disable, "enable|disable")                                 \
20852 _(one_map_register_enable_disable, "enable|disable")                    \
20853 _(one_map_register_fallback_threshold, "<value>")                       \
20854 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20855 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20856                                "[seid <seid>] "                         \
20857                                "rloc <locator> p <prio> "               \
20858                                "w <weight> [rloc <loc> ... ] "          \
20859                                "action <action> [del-all]")             \
20860 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20861                           "<local-eid>")                                \
20862 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20863 _(one_use_petr, "ip-address> | disable")                                \
20864 _(one_map_request_mode, "src-dst|dst-only")                             \
20865 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20866 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20867 _(one_locator_set_dump, "[local | remote]")                             \
20868 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20869 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20870                        "[local] | [remote]")                            \
20871 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20872 _(one_ndp_bd_get, "")                                                   \
20873 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20874 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20875 _(one_l2_arp_bd_get, "")                                                \
20876 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20877 _(one_stats_enable_disable, "enable|disable")                           \
20878 _(show_one_stats_enable_disable, "")                                    \
20879 _(one_eid_table_vni_dump, "")                                           \
20880 _(one_eid_table_map_dump, "l2|l3")                                      \
20881 _(one_map_resolver_dump, "")                                            \
20882 _(one_map_server_dump, "")                                              \
20883 _(one_adjacencies_get, "vni <vni>")                                     \
20884 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20885 _(show_one_rloc_probe_state, "")                                        \
20886 _(show_one_map_register_state, "")                                      \
20887 _(show_one_status, "")                                                  \
20888 _(one_stats_dump, "")                                                   \
20889 _(one_stats_flush, "")                                                  \
20890 _(one_get_map_request_itr_rlocs, "")                                    \
20891 _(one_map_register_set_ttl, "<ttl>")                                    \
20892 _(one_set_transport_protocol, "udp|api")                                \
20893 _(one_get_transport_protocol, "")                                       \
20894 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20895 _(one_show_xtr_mode, "")                                                \
20896 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20897 _(one_show_pitr_mode, "")                                               \
20898 _(one_enable_disable_petr_mode, "enable|disable")                       \
20899 _(one_show_petr_mode, "")                                               \
20900 _(show_one_nsh_mapping, "")                                             \
20901 _(show_one_pitr, "")                                                    \
20902 _(show_one_use_petr, "")                                                \
20903 _(show_one_map_request_mode, "")                                        \
20904 _(show_one_map_register_ttl, "")                                        \
20905 _(show_one_map_register_fallback_threshold, "")                         \
20906 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20907                             " sw_if_index <sw_if_index> p <priority> "  \
20908                             "w <weight>] [del]")                        \
20909 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20910                         "iface <intf> | sw_if_index <sw_if_index> "     \
20911                         "p <priority> w <weight> [del]")                \
20912 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20913                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20914                          "locator-set <locator_name> [del]"             \
20915                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20916 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20917 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20918 _(lisp_enable_disable, "enable|disable")                                \
20919 _(lisp_map_register_enable_disable, "enable|disable")                   \
20920 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20921 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20922                                "[seid <seid>] "                         \
20923                                "rloc <locator> p <prio> "               \
20924                                "w <weight> [rloc <loc> ... ] "          \
20925                                "action <action> [del-all]")             \
20926 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20927                           "<local-eid>")                                \
20928 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20929 _(lisp_use_petr, "<ip-address> | disable")                              \
20930 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20931 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20932 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20933 _(lisp_locator_set_dump, "[local | remote]")                            \
20934 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20935 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20936                        "[local] | [remote]")                            \
20937 _(lisp_eid_table_vni_dump, "")                                          \
20938 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20939 _(lisp_map_resolver_dump, "")                                           \
20940 _(lisp_map_server_dump, "")                                             \
20941 _(lisp_adjacencies_get, "vni <vni>")                                    \
20942 _(gpe_fwd_entry_vnis_get, "")                                           \
20943 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20944 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20945                                 "[table <table-id>]")                   \
20946 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20947 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20948 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20949 _(gpe_get_encap_mode, "")                                               \
20950 _(lisp_gpe_add_del_iface, "up|down")                                    \
20951 _(lisp_gpe_enable_disable, "enable|disable")                            \
20952 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20953   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20954 _(show_lisp_rloc_probe_state, "")                                       \
20955 _(show_lisp_map_register_state, "")                                     \
20956 _(show_lisp_status, "")                                                 \
20957 _(lisp_get_map_request_itr_rlocs, "")                                   \
20958 _(show_lisp_pitr, "")                                                   \
20959 _(show_lisp_use_petr, "")                                               \
20960 _(show_lisp_map_request_mode, "")                                       \
20961 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20962 _(af_packet_delete, "name <host interface name>")                       \
20963 _(af_packet_dump, "")                                                   \
20964 _(policer_add_del, "name <policer name> <params> [del]")                \
20965 _(policer_dump, "[name <policer name>]")                                \
20966 _(policer_classify_set_interface,                                       \
20967   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20968   "  [l2-table <nn>] [del]")                                            \
20969 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20970 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20971 _(mpls_table_dump, "")                                                  \
20972 _(mpls_route_dump, "table-id <ID>")                                     \
20973 _(classify_table_ids, "")                                               \
20974 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20975 _(classify_table_info, "table_id <nn>")                                 \
20976 _(classify_session_dump, "table_id <nn>")                               \
20977 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20978     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20979     "[template_interval <nn>] [udp_checksum]")                          \
20980 _(ipfix_exporter_dump, "")                                              \
20981 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20982 _(ipfix_classify_stream_dump, "")                                       \
20983 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20984 _(ipfix_classify_table_dump, "")                                        \
20985 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20986 _(sw_interface_span_dump, "[l2]")                                           \
20987 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20988 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20989 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20990 _(pg_enable_disable, "[stream <id>] disable")                           \
20991 _(ip_source_and_port_range_check_add_del,                               \
20992   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20993 _(ip_source_and_port_range_check_interface_add_del,                     \
20994   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20995   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20996 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20997 _(l2_interface_pbb_tag_rewrite,                                         \
20998   "<intfc> | sw_if_index <nn> \n"                                       \
20999   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21000   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21001 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21002 _(flow_classify_set_interface,                                          \
21003   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21004 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21005 _(ip_table_dump, "")                                                    \
21006 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21007 _(ip_mtable_dump, "")                                                   \
21008 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21009 _(feature_enable_disable, "arc_name <arc_name> "                        \
21010   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21011 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21012   "[enable | disable] ")                                                \
21013 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21014 "[disable]")                                                            \
21015 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21016   "mac <mac-address> [del]")                                            \
21017 _(l2_xconnect_dump, "")                                                 \
21018 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21019 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21020 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21021 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21022 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21023 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21024   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21025 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21026 _(sock_init_shm, "size <nnn>")                                          \
21027 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21028 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21029   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21030 _(session_rules_dump, "")                                               \
21031 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21032 _(output_acl_set_interface,                                             \
21033   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21034   "  [l2-table <nn>] [del]")                                            \
21035 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21036
21037 /* List of command functions, CLI names map directly to functions */
21038 #define foreach_cli_function                                    \
21039 _(comment, "usage: comment <ignore-rest-of-line>")              \
21040 _(dump_interface_table, "usage: dump_interface_table")          \
21041 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21042 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21043 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21044 _(dump_macro_table, "usage: dump_macro_table ")                 \
21045 _(dump_node_table, "usage: dump_node_table")                    \
21046 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21047 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21048 _(elog_disable, "usage: elog_disable")                          \
21049 _(elog_enable, "usage: elog_enable")                            \
21050 _(elog_save, "usage: elog_save <filename>")                     \
21051 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21052 _(echo, "usage: echo <message>")                                \
21053 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21054 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21055 _(help, "usage: help")                                          \
21056 _(q, "usage: quit")                                             \
21057 _(quit, "usage: quit")                                          \
21058 _(search_node_table, "usage: search_node_table <name>...")      \
21059 _(set, "usage: set <variable-name> <value>")                    \
21060 _(script, "usage: script <file-name>")                          \
21061 _(statseg, "usage: statseg")                                    \
21062 _(unset, "usage: unset <variable-name>")
21063
21064 #define _(N,n)                                  \
21065     static void vl_api_##n##_t_handler_uni      \
21066     (vl_api_##n##_t * mp)                       \
21067     {                                           \
21068         vat_main_t * vam = &vat_main;           \
21069         if (vam->json_output) {                 \
21070             vl_api_##n##_t_handler_json(mp);    \
21071         } else {                                \
21072             vl_api_##n##_t_handler(mp);         \
21073         }                                       \
21074     }
21075 foreach_vpe_api_reply_msg;
21076 #if VPP_API_TEST_BUILTIN == 0
21077 foreach_standalone_reply_msg;
21078 #endif
21079 #undef _
21080
21081 void
21082 vat_api_hookup (vat_main_t * vam)
21083 {
21084 #define _(N,n)                                                  \
21085     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21086                            vl_api_##n##_t_handler_uni,          \
21087                            vl_noop_handler,                     \
21088                            vl_api_##n##_t_endian,               \
21089                            vl_api_##n##_t_print,                \
21090                            sizeof(vl_api_##n##_t), 1);
21091   foreach_vpe_api_reply_msg;
21092 #if VPP_API_TEST_BUILTIN == 0
21093   foreach_standalone_reply_msg;
21094 #endif
21095 #undef _
21096
21097 #if (VPP_API_TEST_BUILTIN==0)
21098   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21099
21100   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21101
21102   vam->function_by_name = hash_create_string (0, sizeof (uword));
21103
21104   vam->help_by_name = hash_create_string (0, sizeof (uword));
21105 #endif
21106
21107   /* API messages we can send */
21108 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21109   foreach_vpe_api_msg;
21110 #undef _
21111
21112   /* Help strings */
21113 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21114   foreach_vpe_api_msg;
21115 #undef _
21116
21117   /* CLI functions */
21118 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21119   foreach_cli_function;
21120 #undef _
21121
21122   /* Help strings */
21123 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21124   foreach_cli_function;
21125 #undef _
21126 }
21127
21128 #if VPP_API_TEST_BUILTIN
21129 static clib_error_t *
21130 vat_api_hookup_shim (vlib_main_t * vm)
21131 {
21132   vat_api_hookup (&vat_main);
21133   return 0;
21134 }
21135
21136 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21137 #endif
21138
21139 /*
21140  * fd.io coding-style-patch-verification: ON
21141  *
21142  * Local Variables:
21143  * eval: (c-set-style "gnu")
21144  * End:
21145  */