sr: srv6 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   ip46_address_t nh_addr;
9329   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9330
9331   bool nexthop_set = 0;
9332
9333   int ret;
9334
9335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9336     {
9337       if (unformat (i, "del"))
9338         is_del = 1;
9339       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9340       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9341         nexthop_set = 1;
9342       else if (unformat (i, "behavior %u", &behavior));
9343       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9344       else if (unformat (i, "fib-table %u", &fib_table));
9345       else if (unformat (i, "end.psp %u", &behavior));
9346       else
9347         break;
9348     }
9349
9350   M (SR_LOCALSID_ADD_DEL, mp);
9351
9352   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9353
9354   if (nexthop_set)
9355     {
9356       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9357     }
9358   mp->behavior = behavior;
9359   mp->sw_if_index = ntohl (sw_if_index);
9360   mp->fib_table = ntohl (fib_table);
9361   mp->end_psp = end_psp;
9362   mp->is_del = is_del;
9363
9364   S (mp);
9365   W (ret);
9366   return ret;
9367 }
9368
9369 static int
9370 api_ioam_enable (vat_main_t * vam)
9371 {
9372   unformat_input_t *input = vam->input;
9373   vl_api_ioam_enable_t *mp;
9374   u32 id = 0;
9375   int has_trace_option = 0;
9376   int has_pot_option = 0;
9377   int has_seqno_option = 0;
9378   int has_analyse_option = 0;
9379   int ret;
9380
9381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9382     {
9383       if (unformat (input, "trace"))
9384         has_trace_option = 1;
9385       else if (unformat (input, "pot"))
9386         has_pot_option = 1;
9387       else if (unformat (input, "seqno"))
9388         has_seqno_option = 1;
9389       else if (unformat (input, "analyse"))
9390         has_analyse_option = 1;
9391       else
9392         break;
9393     }
9394   M (IOAM_ENABLE, mp);
9395   mp->id = htons (id);
9396   mp->seqno = has_seqno_option;
9397   mp->analyse = has_analyse_option;
9398   mp->pot_enable = has_pot_option;
9399   mp->trace_enable = has_trace_option;
9400
9401   S (mp);
9402   W (ret);
9403   return ret;
9404 }
9405
9406
9407 static int
9408 api_ioam_disable (vat_main_t * vam)
9409 {
9410   vl_api_ioam_disable_t *mp;
9411   int ret;
9412
9413   M (IOAM_DISABLE, mp);
9414   S (mp);
9415   W (ret);
9416   return ret;
9417 }
9418
9419 #define foreach_tcp_proto_field                 \
9420 _(src_port)                                     \
9421 _(dst_port)
9422
9423 #define foreach_udp_proto_field                 \
9424 _(src_port)                                     \
9425 _(dst_port)
9426
9427 #define foreach_ip4_proto_field                 \
9428 _(src_address)                                  \
9429 _(dst_address)                                  \
9430 _(tos)                                          \
9431 _(length)                                       \
9432 _(fragment_id)                                  \
9433 _(ttl)                                          \
9434 _(protocol)                                     \
9435 _(checksum)
9436
9437 typedef struct
9438 {
9439   u16 src_port, dst_port;
9440 } tcpudp_header_t;
9441
9442 #if VPP_API_TEST_BUILTIN == 0
9443 uword
9444 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9445 {
9446   u8 **maskp = va_arg (*args, u8 **);
9447   u8 *mask = 0;
9448   u8 found_something = 0;
9449   tcp_header_t *tcp;
9450
9451 #define _(a) u8 a=0;
9452   foreach_tcp_proto_field;
9453 #undef _
9454
9455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9456     {
9457       if (0);
9458 #define _(a) else if (unformat (input, #a)) a=1;
9459       foreach_tcp_proto_field
9460 #undef _
9461         else
9462         break;
9463     }
9464
9465 #define _(a) found_something += a;
9466   foreach_tcp_proto_field;
9467 #undef _
9468
9469   if (found_something == 0)
9470     return 0;
9471
9472   vec_validate (mask, sizeof (*tcp) - 1);
9473
9474   tcp = (tcp_header_t *) mask;
9475
9476 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9477   foreach_tcp_proto_field;
9478 #undef _
9479
9480   *maskp = mask;
9481   return 1;
9482 }
9483
9484 uword
9485 unformat_udp_mask (unformat_input_t * input, va_list * args)
9486 {
9487   u8 **maskp = va_arg (*args, u8 **);
9488   u8 *mask = 0;
9489   u8 found_something = 0;
9490   udp_header_t *udp;
9491
9492 #define _(a) u8 a=0;
9493   foreach_udp_proto_field;
9494 #undef _
9495
9496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9497     {
9498       if (0);
9499 #define _(a) else if (unformat (input, #a)) a=1;
9500       foreach_udp_proto_field
9501 #undef _
9502         else
9503         break;
9504     }
9505
9506 #define _(a) found_something += a;
9507   foreach_udp_proto_field;
9508 #undef _
9509
9510   if (found_something == 0)
9511     return 0;
9512
9513   vec_validate (mask, sizeof (*udp) - 1);
9514
9515   udp = (udp_header_t *) mask;
9516
9517 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9518   foreach_udp_proto_field;
9519 #undef _
9520
9521   *maskp = mask;
9522   return 1;
9523 }
9524
9525 uword
9526 unformat_l4_mask (unformat_input_t * input, va_list * args)
9527 {
9528   u8 **maskp = va_arg (*args, u8 **);
9529   u16 src_port = 0, dst_port = 0;
9530   tcpudp_header_t *tcpudp;
9531
9532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9533     {
9534       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9535         return 1;
9536       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9537         return 1;
9538       else if (unformat (input, "src_port"))
9539         src_port = 0xFFFF;
9540       else if (unformat (input, "dst_port"))
9541         dst_port = 0xFFFF;
9542       else
9543         return 0;
9544     }
9545
9546   if (!src_port && !dst_port)
9547     return 0;
9548
9549   u8 *mask = 0;
9550   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9551
9552   tcpudp = (tcpudp_header_t *) mask;
9553   tcpudp->src_port = src_port;
9554   tcpudp->dst_port = dst_port;
9555
9556   *maskp = mask;
9557
9558   return 1;
9559 }
9560
9561 uword
9562 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9563 {
9564   u8 **maskp = va_arg (*args, u8 **);
9565   u8 *mask = 0;
9566   u8 found_something = 0;
9567   ip4_header_t *ip;
9568
9569 #define _(a) u8 a=0;
9570   foreach_ip4_proto_field;
9571 #undef _
9572   u8 version = 0;
9573   u8 hdr_length = 0;
9574
9575
9576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9577     {
9578       if (unformat (input, "version"))
9579         version = 1;
9580       else if (unformat (input, "hdr_length"))
9581         hdr_length = 1;
9582       else if (unformat (input, "src"))
9583         src_address = 1;
9584       else if (unformat (input, "dst"))
9585         dst_address = 1;
9586       else if (unformat (input, "proto"))
9587         protocol = 1;
9588
9589 #define _(a) else if (unformat (input, #a)) a=1;
9590       foreach_ip4_proto_field
9591 #undef _
9592         else
9593         break;
9594     }
9595
9596 #define _(a) found_something += a;
9597   foreach_ip4_proto_field;
9598 #undef _
9599
9600   if (found_something == 0)
9601     return 0;
9602
9603   vec_validate (mask, sizeof (*ip) - 1);
9604
9605   ip = (ip4_header_t *) mask;
9606
9607 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9608   foreach_ip4_proto_field;
9609 #undef _
9610
9611   ip->ip_version_and_header_length = 0;
9612
9613   if (version)
9614     ip->ip_version_and_header_length |= 0xF0;
9615
9616   if (hdr_length)
9617     ip->ip_version_and_header_length |= 0x0F;
9618
9619   *maskp = mask;
9620   return 1;
9621 }
9622
9623 #define foreach_ip6_proto_field                 \
9624 _(src_address)                                  \
9625 _(dst_address)                                  \
9626 _(payload_length)                               \
9627 _(hop_limit)                                    \
9628 _(protocol)
9629
9630 uword
9631 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9632 {
9633   u8 **maskp = va_arg (*args, u8 **);
9634   u8 *mask = 0;
9635   u8 found_something = 0;
9636   ip6_header_t *ip;
9637   u32 ip_version_traffic_class_and_flow_label;
9638
9639 #define _(a) u8 a=0;
9640   foreach_ip6_proto_field;
9641 #undef _
9642   u8 version = 0;
9643   u8 traffic_class = 0;
9644   u8 flow_label = 0;
9645
9646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (input, "version"))
9649         version = 1;
9650       else if (unformat (input, "traffic-class"))
9651         traffic_class = 1;
9652       else if (unformat (input, "flow-label"))
9653         flow_label = 1;
9654       else if (unformat (input, "src"))
9655         src_address = 1;
9656       else if (unformat (input, "dst"))
9657         dst_address = 1;
9658       else if (unformat (input, "proto"))
9659         protocol = 1;
9660
9661 #define _(a) else if (unformat (input, #a)) a=1;
9662       foreach_ip6_proto_field
9663 #undef _
9664         else
9665         break;
9666     }
9667
9668 #define _(a) found_something += a;
9669   foreach_ip6_proto_field;
9670 #undef _
9671
9672   if (found_something == 0)
9673     return 0;
9674
9675   vec_validate (mask, sizeof (*ip) - 1);
9676
9677   ip = (ip6_header_t *) mask;
9678
9679 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9680   foreach_ip6_proto_field;
9681 #undef _
9682
9683   ip_version_traffic_class_and_flow_label = 0;
9684
9685   if (version)
9686     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9687
9688   if (traffic_class)
9689     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9690
9691   if (flow_label)
9692     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9693
9694   ip->ip_version_traffic_class_and_flow_label =
9695     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9696
9697   *maskp = mask;
9698   return 1;
9699 }
9700
9701 uword
9702 unformat_l3_mask (unformat_input_t * input, va_list * args)
9703 {
9704   u8 **maskp = va_arg (*args, u8 **);
9705
9706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9707     {
9708       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9709         return 1;
9710       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9711         return 1;
9712       else
9713         break;
9714     }
9715   return 0;
9716 }
9717
9718 uword
9719 unformat_l2_mask (unformat_input_t * input, va_list * args)
9720 {
9721   u8 **maskp = va_arg (*args, u8 **);
9722   u8 *mask = 0;
9723   u8 src = 0;
9724   u8 dst = 0;
9725   u8 proto = 0;
9726   u8 tag1 = 0;
9727   u8 tag2 = 0;
9728   u8 ignore_tag1 = 0;
9729   u8 ignore_tag2 = 0;
9730   u8 cos1 = 0;
9731   u8 cos2 = 0;
9732   u8 dot1q = 0;
9733   u8 dot1ad = 0;
9734   int len = 14;
9735
9736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9737     {
9738       if (unformat (input, "src"))
9739         src = 1;
9740       else if (unformat (input, "dst"))
9741         dst = 1;
9742       else if (unformat (input, "proto"))
9743         proto = 1;
9744       else if (unformat (input, "tag1"))
9745         tag1 = 1;
9746       else if (unformat (input, "tag2"))
9747         tag2 = 1;
9748       else if (unformat (input, "ignore-tag1"))
9749         ignore_tag1 = 1;
9750       else if (unformat (input, "ignore-tag2"))
9751         ignore_tag2 = 1;
9752       else if (unformat (input, "cos1"))
9753         cos1 = 1;
9754       else if (unformat (input, "cos2"))
9755         cos2 = 1;
9756       else if (unformat (input, "dot1q"))
9757         dot1q = 1;
9758       else if (unformat (input, "dot1ad"))
9759         dot1ad = 1;
9760       else
9761         break;
9762     }
9763   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9764        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9765     return 0;
9766
9767   if (tag1 || ignore_tag1 || cos1 || dot1q)
9768     len = 18;
9769   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9770     len = 22;
9771
9772   vec_validate (mask, len - 1);
9773
9774   if (dst)
9775     clib_memset (mask, 0xff, 6);
9776
9777   if (src)
9778     clib_memset (mask + 6, 0xff, 6);
9779
9780   if (tag2 || dot1ad)
9781     {
9782       /* inner vlan tag */
9783       if (tag2)
9784         {
9785           mask[19] = 0xff;
9786           mask[18] = 0x0f;
9787         }
9788       if (cos2)
9789         mask[18] |= 0xe0;
9790       if (proto)
9791         mask[21] = mask[20] = 0xff;
9792       if (tag1)
9793         {
9794           mask[15] = 0xff;
9795           mask[14] = 0x0f;
9796         }
9797       if (cos1)
9798         mask[14] |= 0xe0;
9799       *maskp = mask;
9800       return 1;
9801     }
9802   if (tag1 | dot1q)
9803     {
9804       if (tag1)
9805         {
9806           mask[15] = 0xff;
9807           mask[14] = 0x0f;
9808         }
9809       if (cos1)
9810         mask[14] |= 0xe0;
9811       if (proto)
9812         mask[16] = mask[17] = 0xff;
9813
9814       *maskp = mask;
9815       return 1;
9816     }
9817   if (cos2)
9818     mask[18] |= 0xe0;
9819   if (cos1)
9820     mask[14] |= 0xe0;
9821   if (proto)
9822     mask[12] = mask[13] = 0xff;
9823
9824   *maskp = mask;
9825   return 1;
9826 }
9827
9828 uword
9829 unformat_classify_mask (unformat_input_t * input, va_list * args)
9830 {
9831   u8 **maskp = va_arg (*args, u8 **);
9832   u32 *skipp = va_arg (*args, u32 *);
9833   u32 *matchp = va_arg (*args, u32 *);
9834   u32 match;
9835   u8 *mask = 0;
9836   u8 *l2 = 0;
9837   u8 *l3 = 0;
9838   u8 *l4 = 0;
9839   int i;
9840
9841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9842     {
9843       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9844         ;
9845       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9846         ;
9847       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9848         ;
9849       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9850         ;
9851       else
9852         break;
9853     }
9854
9855   if (l4 && !l3)
9856     {
9857       vec_free (mask);
9858       vec_free (l2);
9859       vec_free (l4);
9860       return 0;
9861     }
9862
9863   if (mask || l2 || l3 || l4)
9864     {
9865       if (l2 || l3 || l4)
9866         {
9867           /* "With a free Ethernet header in every package" */
9868           if (l2 == 0)
9869             vec_validate (l2, 13);
9870           mask = l2;
9871           if (vec_len (l3))
9872             {
9873               vec_append (mask, l3);
9874               vec_free (l3);
9875             }
9876           if (vec_len (l4))
9877             {
9878               vec_append (mask, l4);
9879               vec_free (l4);
9880             }
9881         }
9882
9883       /* Scan forward looking for the first significant mask octet */
9884       for (i = 0; i < vec_len (mask); i++)
9885         if (mask[i])
9886           break;
9887
9888       /* compute (skip, match) params */
9889       *skipp = i / sizeof (u32x4);
9890       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9891
9892       /* Pad mask to an even multiple of the vector size */
9893       while (vec_len (mask) % sizeof (u32x4))
9894         vec_add1 (mask, 0);
9895
9896       match = vec_len (mask) / sizeof (u32x4);
9897
9898       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9899         {
9900           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9901           if (*tmp || *(tmp + 1))
9902             break;
9903           match--;
9904         }
9905       if (match == 0)
9906         clib_warning ("BUG: match 0");
9907
9908       _vec_len (mask) = match * sizeof (u32x4);
9909
9910       *matchp = match;
9911       *maskp = mask;
9912
9913       return 1;
9914     }
9915
9916   return 0;
9917 }
9918 #endif /* VPP_API_TEST_BUILTIN */
9919
9920 #define foreach_l2_next                         \
9921 _(drop, DROP)                                   \
9922 _(ethernet, ETHERNET_INPUT)                     \
9923 _(ip4, IP4_INPUT)                               \
9924 _(ip6, IP6_INPUT)
9925
9926 uword
9927 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9928 {
9929   u32 *miss_next_indexp = va_arg (*args, u32 *);
9930   u32 next_index = 0;
9931   u32 tmp;
9932
9933 #define _(n,N) \
9934   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9935   foreach_l2_next;
9936 #undef _
9937
9938   if (unformat (input, "%d", &tmp))
9939     {
9940       next_index = tmp;
9941       goto out;
9942     }
9943
9944   return 0;
9945
9946 out:
9947   *miss_next_indexp = next_index;
9948   return 1;
9949 }
9950
9951 #define foreach_ip_next                         \
9952 _(drop, DROP)                                   \
9953 _(local, LOCAL)                                 \
9954 _(rewrite, REWRITE)
9955
9956 uword
9957 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9958 {
9959   u32 *miss_next_indexp = va_arg (*args, u32 *);
9960   u32 next_index = 0;
9961   u32 tmp;
9962
9963 #define _(n,N) \
9964   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9965   foreach_ip_next;
9966 #undef _
9967
9968   if (unformat (input, "%d", &tmp))
9969     {
9970       next_index = tmp;
9971       goto out;
9972     }
9973
9974   return 0;
9975
9976 out:
9977   *miss_next_indexp = next_index;
9978   return 1;
9979 }
9980
9981 #define foreach_acl_next                        \
9982 _(deny, DENY)
9983
9984 uword
9985 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9986 {
9987   u32 *miss_next_indexp = va_arg (*args, u32 *);
9988   u32 next_index = 0;
9989   u32 tmp;
9990
9991 #define _(n,N) \
9992   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9993   foreach_acl_next;
9994 #undef _
9995
9996   if (unformat (input, "permit"))
9997     {
9998       next_index = ~0;
9999       goto out;
10000     }
10001   else if (unformat (input, "%d", &tmp))
10002     {
10003       next_index = tmp;
10004       goto out;
10005     }
10006
10007   return 0;
10008
10009 out:
10010   *miss_next_indexp = next_index;
10011   return 1;
10012 }
10013
10014 uword
10015 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10016 {
10017   u32 *r = va_arg (*args, u32 *);
10018
10019   if (unformat (input, "conform-color"))
10020     *r = POLICE_CONFORM;
10021   else if (unformat (input, "exceed-color"))
10022     *r = POLICE_EXCEED;
10023   else
10024     return 0;
10025
10026   return 1;
10027 }
10028
10029 static int
10030 api_classify_add_del_table (vat_main_t * vam)
10031 {
10032   unformat_input_t *i = vam->input;
10033   vl_api_classify_add_del_table_t *mp;
10034
10035   u32 nbuckets = 2;
10036   u32 skip = ~0;
10037   u32 match = ~0;
10038   int is_add = 1;
10039   int del_chain = 0;
10040   u32 table_index = ~0;
10041   u32 next_table_index = ~0;
10042   u32 miss_next_index = ~0;
10043   u32 memory_size = 32 << 20;
10044   u8 *mask = 0;
10045   u32 current_data_flag = 0;
10046   int current_data_offset = 0;
10047   int ret;
10048
10049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050     {
10051       if (unformat (i, "del"))
10052         is_add = 0;
10053       else if (unformat (i, "del-chain"))
10054         {
10055           is_add = 0;
10056           del_chain = 1;
10057         }
10058       else if (unformat (i, "buckets %d", &nbuckets))
10059         ;
10060       else if (unformat (i, "memory_size %d", &memory_size))
10061         ;
10062       else if (unformat (i, "skip %d", &skip))
10063         ;
10064       else if (unformat (i, "match %d", &match))
10065         ;
10066       else if (unformat (i, "table %d", &table_index))
10067         ;
10068       else if (unformat (i, "mask %U", unformat_classify_mask,
10069                          &mask, &skip, &match))
10070         ;
10071       else if (unformat (i, "next-table %d", &next_table_index))
10072         ;
10073       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10074                          &miss_next_index))
10075         ;
10076       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10077                          &miss_next_index))
10078         ;
10079       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10080                          &miss_next_index))
10081         ;
10082       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10083         ;
10084       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10085         ;
10086       else
10087         break;
10088     }
10089
10090   if (is_add && mask == 0)
10091     {
10092       errmsg ("Mask required");
10093       return -99;
10094     }
10095
10096   if (is_add && skip == ~0)
10097     {
10098       errmsg ("skip count required");
10099       return -99;
10100     }
10101
10102   if (is_add && match == ~0)
10103     {
10104       errmsg ("match count required");
10105       return -99;
10106     }
10107
10108   if (!is_add && table_index == ~0)
10109     {
10110       errmsg ("table index required for delete");
10111       return -99;
10112     }
10113
10114   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10115
10116   mp->is_add = is_add;
10117   mp->del_chain = del_chain;
10118   mp->table_index = ntohl (table_index);
10119   mp->nbuckets = ntohl (nbuckets);
10120   mp->memory_size = ntohl (memory_size);
10121   mp->skip_n_vectors = ntohl (skip);
10122   mp->match_n_vectors = ntohl (match);
10123   mp->next_table_index = ntohl (next_table_index);
10124   mp->miss_next_index = ntohl (miss_next_index);
10125   mp->current_data_flag = ntohl (current_data_flag);
10126   mp->current_data_offset = ntohl (current_data_offset);
10127   mp->mask_len = ntohl (vec_len (mask));
10128   clib_memcpy (mp->mask, mask, vec_len (mask));
10129
10130   vec_free (mask);
10131
10132   S (mp);
10133   W (ret);
10134   return ret;
10135 }
10136
10137 #if VPP_API_TEST_BUILTIN == 0
10138 uword
10139 unformat_l4_match (unformat_input_t * input, va_list * args)
10140 {
10141   u8 **matchp = va_arg (*args, u8 **);
10142
10143   u8 *proto_header = 0;
10144   int src_port = 0;
10145   int dst_port = 0;
10146
10147   tcpudp_header_t h;
10148
10149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (input, "src_port %d", &src_port))
10152         ;
10153       else if (unformat (input, "dst_port %d", &dst_port))
10154         ;
10155       else
10156         return 0;
10157     }
10158
10159   h.src_port = clib_host_to_net_u16 (src_port);
10160   h.dst_port = clib_host_to_net_u16 (dst_port);
10161   vec_validate (proto_header, sizeof (h) - 1);
10162   memcpy (proto_header, &h, sizeof (h));
10163
10164   *matchp = proto_header;
10165
10166   return 1;
10167 }
10168
10169 uword
10170 unformat_ip4_match (unformat_input_t * input, va_list * args)
10171 {
10172   u8 **matchp = va_arg (*args, u8 **);
10173   u8 *match = 0;
10174   ip4_header_t *ip;
10175   int version = 0;
10176   u32 version_val;
10177   int hdr_length = 0;
10178   u32 hdr_length_val;
10179   int src = 0, dst = 0;
10180   ip4_address_t src_val, dst_val;
10181   int proto = 0;
10182   u32 proto_val;
10183   int tos = 0;
10184   u32 tos_val;
10185   int length = 0;
10186   u32 length_val;
10187   int fragment_id = 0;
10188   u32 fragment_id_val;
10189   int ttl = 0;
10190   int ttl_val;
10191   int checksum = 0;
10192   u32 checksum_val;
10193
10194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10195     {
10196       if (unformat (input, "version %d", &version_val))
10197         version = 1;
10198       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10199         hdr_length = 1;
10200       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10201         src = 1;
10202       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10203         dst = 1;
10204       else if (unformat (input, "proto %d", &proto_val))
10205         proto = 1;
10206       else if (unformat (input, "tos %d", &tos_val))
10207         tos = 1;
10208       else if (unformat (input, "length %d", &length_val))
10209         length = 1;
10210       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10211         fragment_id = 1;
10212       else if (unformat (input, "ttl %d", &ttl_val))
10213         ttl = 1;
10214       else if (unformat (input, "checksum %d", &checksum_val))
10215         checksum = 1;
10216       else
10217         break;
10218     }
10219
10220   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10221       + ttl + checksum == 0)
10222     return 0;
10223
10224   /*
10225    * Aligned because we use the real comparison functions
10226    */
10227   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10228
10229   ip = (ip4_header_t *) match;
10230
10231   /* These are realistically matched in practice */
10232   if (src)
10233     ip->src_address.as_u32 = src_val.as_u32;
10234
10235   if (dst)
10236     ip->dst_address.as_u32 = dst_val.as_u32;
10237
10238   if (proto)
10239     ip->protocol = proto_val;
10240
10241
10242   /* These are not, but they're included for completeness */
10243   if (version)
10244     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10245
10246   if (hdr_length)
10247     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10248
10249   if (tos)
10250     ip->tos = tos_val;
10251
10252   if (length)
10253     ip->length = clib_host_to_net_u16 (length_val);
10254
10255   if (ttl)
10256     ip->ttl = ttl_val;
10257
10258   if (checksum)
10259     ip->checksum = clib_host_to_net_u16 (checksum_val);
10260
10261   *matchp = match;
10262   return 1;
10263 }
10264
10265 uword
10266 unformat_ip6_match (unformat_input_t * input, va_list * args)
10267 {
10268   u8 **matchp = va_arg (*args, u8 **);
10269   u8 *match = 0;
10270   ip6_header_t *ip;
10271   int version = 0;
10272   u32 version_val;
10273   u8 traffic_class = 0;
10274   u32 traffic_class_val = 0;
10275   u8 flow_label = 0;
10276   u8 flow_label_val;
10277   int src = 0, dst = 0;
10278   ip6_address_t src_val, dst_val;
10279   int proto = 0;
10280   u32 proto_val;
10281   int payload_length = 0;
10282   u32 payload_length_val;
10283   int hop_limit = 0;
10284   int hop_limit_val;
10285   u32 ip_version_traffic_class_and_flow_label;
10286
10287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (input, "version %d", &version_val))
10290         version = 1;
10291       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10292         traffic_class = 1;
10293       else if (unformat (input, "flow_label %d", &flow_label_val))
10294         flow_label = 1;
10295       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10296         src = 1;
10297       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10298         dst = 1;
10299       else if (unformat (input, "proto %d", &proto_val))
10300         proto = 1;
10301       else if (unformat (input, "payload_length %d", &payload_length_val))
10302         payload_length = 1;
10303       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10304         hop_limit = 1;
10305       else
10306         break;
10307     }
10308
10309   if (version + traffic_class + flow_label + src + dst + proto +
10310       payload_length + hop_limit == 0)
10311     return 0;
10312
10313   /*
10314    * Aligned because we use the real comparison functions
10315    */
10316   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10317
10318   ip = (ip6_header_t *) match;
10319
10320   if (src)
10321     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10322
10323   if (dst)
10324     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10325
10326   if (proto)
10327     ip->protocol = proto_val;
10328
10329   ip_version_traffic_class_and_flow_label = 0;
10330
10331   if (version)
10332     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10333
10334   if (traffic_class)
10335     ip_version_traffic_class_and_flow_label |=
10336       (traffic_class_val & 0xFF) << 20;
10337
10338   if (flow_label)
10339     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10340
10341   ip->ip_version_traffic_class_and_flow_label =
10342     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10343
10344   if (payload_length)
10345     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10346
10347   if (hop_limit)
10348     ip->hop_limit = hop_limit_val;
10349
10350   *matchp = match;
10351   return 1;
10352 }
10353
10354 uword
10355 unformat_l3_match (unformat_input_t * input, va_list * args)
10356 {
10357   u8 **matchp = va_arg (*args, u8 **);
10358
10359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10360     {
10361       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10362         return 1;
10363       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10364         return 1;
10365       else
10366         break;
10367     }
10368   return 0;
10369 }
10370
10371 uword
10372 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10373 {
10374   u8 *tagp = va_arg (*args, u8 *);
10375   u32 tag;
10376
10377   if (unformat (input, "%d", &tag))
10378     {
10379       tagp[0] = (tag >> 8) & 0x0F;
10380       tagp[1] = tag & 0xFF;
10381       return 1;
10382     }
10383
10384   return 0;
10385 }
10386
10387 uword
10388 unformat_l2_match (unformat_input_t * input, va_list * args)
10389 {
10390   u8 **matchp = va_arg (*args, u8 **);
10391   u8 *match = 0;
10392   u8 src = 0;
10393   u8 src_val[6];
10394   u8 dst = 0;
10395   u8 dst_val[6];
10396   u8 proto = 0;
10397   u16 proto_val;
10398   u8 tag1 = 0;
10399   u8 tag1_val[2];
10400   u8 tag2 = 0;
10401   u8 tag2_val[2];
10402   int len = 14;
10403   u8 ignore_tag1 = 0;
10404   u8 ignore_tag2 = 0;
10405   u8 cos1 = 0;
10406   u8 cos2 = 0;
10407   u32 cos1_val = 0;
10408   u32 cos2_val = 0;
10409
10410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10411     {
10412       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10413         src = 1;
10414       else
10415         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10416         dst = 1;
10417       else if (unformat (input, "proto %U",
10418                          unformat_ethernet_type_host_byte_order, &proto_val))
10419         proto = 1;
10420       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10421         tag1 = 1;
10422       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10423         tag2 = 1;
10424       else if (unformat (input, "ignore-tag1"))
10425         ignore_tag1 = 1;
10426       else if (unformat (input, "ignore-tag2"))
10427         ignore_tag2 = 1;
10428       else if (unformat (input, "cos1 %d", &cos1_val))
10429         cos1 = 1;
10430       else if (unformat (input, "cos2 %d", &cos2_val))
10431         cos2 = 1;
10432       else
10433         break;
10434     }
10435   if ((src + dst + proto + tag1 + tag2 +
10436        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10437     return 0;
10438
10439   if (tag1 || ignore_tag1 || cos1)
10440     len = 18;
10441   if (tag2 || ignore_tag2 || cos2)
10442     len = 22;
10443
10444   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10445
10446   if (dst)
10447     clib_memcpy (match, dst_val, 6);
10448
10449   if (src)
10450     clib_memcpy (match + 6, src_val, 6);
10451
10452   if (tag2)
10453     {
10454       /* inner vlan tag */
10455       match[19] = tag2_val[1];
10456       match[18] = tag2_val[0];
10457       if (cos2)
10458         match[18] |= (cos2_val & 0x7) << 5;
10459       if (proto)
10460         {
10461           match[21] = proto_val & 0xff;
10462           match[20] = proto_val >> 8;
10463         }
10464       if (tag1)
10465         {
10466           match[15] = tag1_val[1];
10467           match[14] = tag1_val[0];
10468         }
10469       if (cos1)
10470         match[14] |= (cos1_val & 0x7) << 5;
10471       *matchp = match;
10472       return 1;
10473     }
10474   if (tag1)
10475     {
10476       match[15] = tag1_val[1];
10477       match[14] = tag1_val[0];
10478       if (proto)
10479         {
10480           match[17] = proto_val & 0xff;
10481           match[16] = proto_val >> 8;
10482         }
10483       if (cos1)
10484         match[14] |= (cos1_val & 0x7) << 5;
10485
10486       *matchp = match;
10487       return 1;
10488     }
10489   if (cos2)
10490     match[18] |= (cos2_val & 0x7) << 5;
10491   if (cos1)
10492     match[14] |= (cos1_val & 0x7) << 5;
10493   if (proto)
10494     {
10495       match[13] = proto_val & 0xff;
10496       match[12] = proto_val >> 8;
10497     }
10498
10499   *matchp = match;
10500   return 1;
10501 }
10502
10503 uword
10504 unformat_qos_source (unformat_input_t * input, va_list * args)
10505 {
10506   int *qs = va_arg (*args, int *);
10507
10508   if (unformat (input, "ip"))
10509     *qs = QOS_SOURCE_IP;
10510   else if (unformat (input, "mpls"))
10511     *qs = QOS_SOURCE_MPLS;
10512   else if (unformat (input, "ext"))
10513     *qs = QOS_SOURCE_EXT;
10514   else if (unformat (input, "vlan"))
10515     *qs = QOS_SOURCE_VLAN;
10516   else
10517     return 0;
10518
10519   return 1;
10520 }
10521 #endif
10522
10523 uword
10524 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10525 {
10526   u8 **matchp = va_arg (*args, u8 **);
10527   u32 skip_n_vectors = va_arg (*args, u32);
10528   u32 match_n_vectors = va_arg (*args, u32);
10529
10530   u8 *match = 0;
10531   u8 *l2 = 0;
10532   u8 *l3 = 0;
10533   u8 *l4 = 0;
10534
10535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (input, "hex %U", unformat_hex_string, &match))
10538         ;
10539       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10540         ;
10541       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10542         ;
10543       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10544         ;
10545       else
10546         break;
10547     }
10548
10549   if (l4 && !l3)
10550     {
10551       vec_free (match);
10552       vec_free (l2);
10553       vec_free (l4);
10554       return 0;
10555     }
10556
10557   if (match || l2 || l3 || l4)
10558     {
10559       if (l2 || l3 || l4)
10560         {
10561           /* "Win a free Ethernet header in every packet" */
10562           if (l2 == 0)
10563             vec_validate_aligned (l2, 13, sizeof (u32x4));
10564           match = l2;
10565           if (vec_len (l3))
10566             {
10567               vec_append_aligned (match, l3, sizeof (u32x4));
10568               vec_free (l3);
10569             }
10570           if (vec_len (l4))
10571             {
10572               vec_append_aligned (match, l4, sizeof (u32x4));
10573               vec_free (l4);
10574             }
10575         }
10576
10577       /* Make sure the vector is big enough even if key is all 0's */
10578       vec_validate_aligned
10579         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10580          sizeof (u32x4));
10581
10582       /* Set size, include skipped vectors */
10583       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10584
10585       *matchp = match;
10586
10587       return 1;
10588     }
10589
10590   return 0;
10591 }
10592
10593 static int
10594 api_classify_add_del_session (vat_main_t * vam)
10595 {
10596   unformat_input_t *i = vam->input;
10597   vl_api_classify_add_del_session_t *mp;
10598   int is_add = 1;
10599   u32 table_index = ~0;
10600   u32 hit_next_index = ~0;
10601   u32 opaque_index = ~0;
10602   u8 *match = 0;
10603   i32 advance = 0;
10604   u32 skip_n_vectors = 0;
10605   u32 match_n_vectors = 0;
10606   u32 action = 0;
10607   u32 metadata = 0;
10608   int ret;
10609
10610   /*
10611    * Warning: you have to supply skip_n and match_n
10612    * because the API client cant simply look at the classify
10613    * table object.
10614    */
10615
10616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10617     {
10618       if (unformat (i, "del"))
10619         is_add = 0;
10620       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10621                          &hit_next_index))
10622         ;
10623       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10624                          &hit_next_index))
10625         ;
10626       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10627                          &hit_next_index))
10628         ;
10629       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10630         ;
10631       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10632         ;
10633       else if (unformat (i, "opaque-index %d", &opaque_index))
10634         ;
10635       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10636         ;
10637       else if (unformat (i, "match_n %d", &match_n_vectors))
10638         ;
10639       else if (unformat (i, "match %U", api_unformat_classify_match,
10640                          &match, skip_n_vectors, match_n_vectors))
10641         ;
10642       else if (unformat (i, "advance %d", &advance))
10643         ;
10644       else if (unformat (i, "table-index %d", &table_index))
10645         ;
10646       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10647         action = 1;
10648       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10649         action = 2;
10650       else if (unformat (i, "action %d", &action))
10651         ;
10652       else if (unformat (i, "metadata %d", &metadata))
10653         ;
10654       else
10655         break;
10656     }
10657
10658   if (table_index == ~0)
10659     {
10660       errmsg ("Table index required");
10661       return -99;
10662     }
10663
10664   if (is_add && match == 0)
10665     {
10666       errmsg ("Match value required");
10667       return -99;
10668     }
10669
10670   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10671
10672   mp->is_add = is_add;
10673   mp->table_index = ntohl (table_index);
10674   mp->hit_next_index = ntohl (hit_next_index);
10675   mp->opaque_index = ntohl (opaque_index);
10676   mp->advance = ntohl (advance);
10677   mp->action = action;
10678   mp->metadata = ntohl (metadata);
10679   mp->match_len = ntohl (vec_len (match));
10680   clib_memcpy (mp->match, match, vec_len (match));
10681   vec_free (match);
10682
10683   S (mp);
10684   W (ret);
10685   return ret;
10686 }
10687
10688 static int
10689 api_classify_set_interface_ip_table (vat_main_t * vam)
10690 {
10691   unformat_input_t *i = vam->input;
10692   vl_api_classify_set_interface_ip_table_t *mp;
10693   u32 sw_if_index;
10694   int sw_if_index_set;
10695   u32 table_index = ~0;
10696   u8 is_ipv6 = 0;
10697   int ret;
10698
10699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10700     {
10701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10702         sw_if_index_set = 1;
10703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10704         sw_if_index_set = 1;
10705       else if (unformat (i, "table %d", &table_index))
10706         ;
10707       else
10708         {
10709           clib_warning ("parse error '%U'", format_unformat_error, i);
10710           return -99;
10711         }
10712     }
10713
10714   if (sw_if_index_set == 0)
10715     {
10716       errmsg ("missing interface name or sw_if_index");
10717       return -99;
10718     }
10719
10720
10721   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10722
10723   mp->sw_if_index = ntohl (sw_if_index);
10724   mp->table_index = ntohl (table_index);
10725   mp->is_ipv6 = is_ipv6;
10726
10727   S (mp);
10728   W (ret);
10729   return ret;
10730 }
10731
10732 static int
10733 api_classify_set_interface_l2_tables (vat_main_t * vam)
10734 {
10735   unformat_input_t *i = vam->input;
10736   vl_api_classify_set_interface_l2_tables_t *mp;
10737   u32 sw_if_index;
10738   int sw_if_index_set;
10739   u32 ip4_table_index = ~0;
10740   u32 ip6_table_index = ~0;
10741   u32 other_table_index = ~0;
10742   u32 is_input = 1;
10743   int ret;
10744
10745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10746     {
10747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10748         sw_if_index_set = 1;
10749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10750         sw_if_index_set = 1;
10751       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10752         ;
10753       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10754         ;
10755       else if (unformat (i, "other-table %d", &other_table_index))
10756         ;
10757       else if (unformat (i, "is-input %d", &is_input))
10758         ;
10759       else
10760         {
10761           clib_warning ("parse error '%U'", format_unformat_error, i);
10762           return -99;
10763         }
10764     }
10765
10766   if (sw_if_index_set == 0)
10767     {
10768       errmsg ("missing interface name or sw_if_index");
10769       return -99;
10770     }
10771
10772
10773   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10774
10775   mp->sw_if_index = ntohl (sw_if_index);
10776   mp->ip4_table_index = ntohl (ip4_table_index);
10777   mp->ip6_table_index = ntohl (ip6_table_index);
10778   mp->other_table_index = ntohl (other_table_index);
10779   mp->is_input = (u8) is_input;
10780
10781   S (mp);
10782   W (ret);
10783   return ret;
10784 }
10785
10786 static int
10787 api_set_ipfix_exporter (vat_main_t * vam)
10788 {
10789   unformat_input_t *i = vam->input;
10790   vl_api_set_ipfix_exporter_t *mp;
10791   ip4_address_t collector_address;
10792   u8 collector_address_set = 0;
10793   u32 collector_port = ~0;
10794   ip4_address_t src_address;
10795   u8 src_address_set = 0;
10796   u32 vrf_id = ~0;
10797   u32 path_mtu = ~0;
10798   u32 template_interval = ~0;
10799   u8 udp_checksum = 0;
10800   int ret;
10801
10802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10803     {
10804       if (unformat (i, "collector_address %U", unformat_ip4_address,
10805                     &collector_address))
10806         collector_address_set = 1;
10807       else if (unformat (i, "collector_port %d", &collector_port))
10808         ;
10809       else if (unformat (i, "src_address %U", unformat_ip4_address,
10810                          &src_address))
10811         src_address_set = 1;
10812       else if (unformat (i, "vrf_id %d", &vrf_id))
10813         ;
10814       else if (unformat (i, "path_mtu %d", &path_mtu))
10815         ;
10816       else if (unformat (i, "template_interval %d", &template_interval))
10817         ;
10818       else if (unformat (i, "udp_checksum"))
10819         udp_checksum = 1;
10820       else
10821         break;
10822     }
10823
10824   if (collector_address_set == 0)
10825     {
10826       errmsg ("collector_address required");
10827       return -99;
10828     }
10829
10830   if (src_address_set == 0)
10831     {
10832       errmsg ("src_address required");
10833       return -99;
10834     }
10835
10836   M (SET_IPFIX_EXPORTER, mp);
10837
10838   memcpy (mp->collector_address.un.ip4, collector_address.data,
10839           sizeof (collector_address.data));
10840   mp->collector_port = htons ((u16) collector_port);
10841   memcpy (mp->src_address.un.ip4, src_address.data,
10842           sizeof (src_address.data));
10843   mp->vrf_id = htonl (vrf_id);
10844   mp->path_mtu = htonl (path_mtu);
10845   mp->template_interval = htonl (template_interval);
10846   mp->udp_checksum = udp_checksum;
10847
10848   S (mp);
10849   W (ret);
10850   return ret;
10851 }
10852
10853 static int
10854 api_set_ipfix_classify_stream (vat_main_t * vam)
10855 {
10856   unformat_input_t *i = vam->input;
10857   vl_api_set_ipfix_classify_stream_t *mp;
10858   u32 domain_id = 0;
10859   u32 src_port = UDP_DST_PORT_ipfix;
10860   int ret;
10861
10862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10863     {
10864       if (unformat (i, "domain %d", &domain_id))
10865         ;
10866       else if (unformat (i, "src_port %d", &src_port))
10867         ;
10868       else
10869         {
10870           errmsg ("unknown input `%U'", format_unformat_error, i);
10871           return -99;
10872         }
10873     }
10874
10875   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10876
10877   mp->domain_id = htonl (domain_id);
10878   mp->src_port = htons ((u16) src_port);
10879
10880   S (mp);
10881   W (ret);
10882   return ret;
10883 }
10884
10885 static int
10886 api_ipfix_classify_table_add_del (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_ipfix_classify_table_add_del_t *mp;
10890   int is_add = -1;
10891   u32 classify_table_index = ~0;
10892   u8 ip_version = 0;
10893   u8 transport_protocol = 255;
10894   int ret;
10895
10896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10897     {
10898       if (unformat (i, "add"))
10899         is_add = 1;
10900       else if (unformat (i, "del"))
10901         is_add = 0;
10902       else if (unformat (i, "table %d", &classify_table_index))
10903         ;
10904       else if (unformat (i, "ip4"))
10905         ip_version = 4;
10906       else if (unformat (i, "ip6"))
10907         ip_version = 6;
10908       else if (unformat (i, "tcp"))
10909         transport_protocol = 6;
10910       else if (unformat (i, "udp"))
10911         transport_protocol = 17;
10912       else
10913         {
10914           errmsg ("unknown input `%U'", format_unformat_error, i);
10915           return -99;
10916         }
10917     }
10918
10919   if (is_add == -1)
10920     {
10921       errmsg ("expecting: add|del");
10922       return -99;
10923     }
10924   if (classify_table_index == ~0)
10925     {
10926       errmsg ("classifier table not specified");
10927       return -99;
10928     }
10929   if (ip_version == 0)
10930     {
10931       errmsg ("IP version not specified");
10932       return -99;
10933     }
10934
10935   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10936
10937   mp->is_add = is_add;
10938   mp->table_id = htonl (classify_table_index);
10939   mp->ip_version = ip_version;
10940   mp->transport_protocol = transport_protocol;
10941
10942   S (mp);
10943   W (ret);
10944   return ret;
10945 }
10946
10947 static int
10948 api_get_node_index (vat_main_t * vam)
10949 {
10950   unformat_input_t *i = vam->input;
10951   vl_api_get_node_index_t *mp;
10952   u8 *name = 0;
10953   int ret;
10954
10955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10956     {
10957       if (unformat (i, "node %s", &name))
10958         ;
10959       else
10960         break;
10961     }
10962   if (name == 0)
10963     {
10964       errmsg ("node name required");
10965       return -99;
10966     }
10967   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10968     {
10969       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10970       return -99;
10971     }
10972
10973   M (GET_NODE_INDEX, mp);
10974   clib_memcpy (mp->node_name, name, vec_len (name));
10975   vec_free (name);
10976
10977   S (mp);
10978   W (ret);
10979   return ret;
10980 }
10981
10982 static int
10983 api_get_next_index (vat_main_t * vam)
10984 {
10985   unformat_input_t *i = vam->input;
10986   vl_api_get_next_index_t *mp;
10987   u8 *node_name = 0, *next_node_name = 0;
10988   int ret;
10989
10990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10991     {
10992       if (unformat (i, "node-name %s", &node_name))
10993         ;
10994       else if (unformat (i, "next-node-name %s", &next_node_name))
10995         break;
10996     }
10997
10998   if (node_name == 0)
10999     {
11000       errmsg ("node name required");
11001       return -99;
11002     }
11003   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11004     {
11005       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11006       return -99;
11007     }
11008
11009   if (next_node_name == 0)
11010     {
11011       errmsg ("next node name required");
11012       return -99;
11013     }
11014   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11015     {
11016       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11017       return -99;
11018     }
11019
11020   M (GET_NEXT_INDEX, mp);
11021   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11022   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11023   vec_free (node_name);
11024   vec_free (next_node_name);
11025
11026   S (mp);
11027   W (ret);
11028   return ret;
11029 }
11030
11031 static int
11032 api_add_node_next (vat_main_t * vam)
11033 {
11034   unformat_input_t *i = vam->input;
11035   vl_api_add_node_next_t *mp;
11036   u8 *name = 0;
11037   u8 *next = 0;
11038   int ret;
11039
11040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11041     {
11042       if (unformat (i, "node %s", &name))
11043         ;
11044       else if (unformat (i, "next %s", &next))
11045         ;
11046       else
11047         break;
11048     }
11049   if (name == 0)
11050     {
11051       errmsg ("node name required");
11052       return -99;
11053     }
11054   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11055     {
11056       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11057       return -99;
11058     }
11059   if (next == 0)
11060     {
11061       errmsg ("next node required");
11062       return -99;
11063     }
11064   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11065     {
11066       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11067       return -99;
11068     }
11069
11070   M (ADD_NODE_NEXT, mp);
11071   clib_memcpy (mp->node_name, name, vec_len (name));
11072   clib_memcpy (mp->next_name, next, vec_len (next));
11073   vec_free (name);
11074   vec_free (next);
11075
11076   S (mp);
11077   W (ret);
11078   return ret;
11079 }
11080
11081 static int
11082 api_l2tpv3_create_tunnel (vat_main_t * vam)
11083 {
11084   unformat_input_t *i = vam->input;
11085   ip6_address_t client_address, our_address;
11086   int client_address_set = 0;
11087   int our_address_set = 0;
11088   u32 local_session_id = 0;
11089   u32 remote_session_id = 0;
11090   u64 local_cookie = 0;
11091   u64 remote_cookie = 0;
11092   u8 l2_sublayer_present = 0;
11093   vl_api_l2tpv3_create_tunnel_t *mp;
11094   int ret;
11095
11096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11097     {
11098       if (unformat (i, "client_address %U", unformat_ip6_address,
11099                     &client_address))
11100         client_address_set = 1;
11101       else if (unformat (i, "our_address %U", unformat_ip6_address,
11102                          &our_address))
11103         our_address_set = 1;
11104       else if (unformat (i, "local_session_id %d", &local_session_id))
11105         ;
11106       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11107         ;
11108       else if (unformat (i, "local_cookie %lld", &local_cookie))
11109         ;
11110       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11111         ;
11112       else if (unformat (i, "l2-sublayer-present"))
11113         l2_sublayer_present = 1;
11114       else
11115         break;
11116     }
11117
11118   if (client_address_set == 0)
11119     {
11120       errmsg ("client_address required");
11121       return -99;
11122     }
11123
11124   if (our_address_set == 0)
11125     {
11126       errmsg ("our_address required");
11127       return -99;
11128     }
11129
11130   M (L2TPV3_CREATE_TUNNEL, mp);
11131
11132   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11133                sizeof (ip6_address_t));
11134
11135   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11136                sizeof (ip6_address_t));
11137
11138   mp->local_session_id = ntohl (local_session_id);
11139   mp->remote_session_id = ntohl (remote_session_id);
11140   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11141   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11142   mp->l2_sublayer_present = l2_sublayer_present;
11143
11144   S (mp);
11145   W (ret);
11146   return ret;
11147 }
11148
11149 static int
11150 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11151 {
11152   unformat_input_t *i = vam->input;
11153   u32 sw_if_index;
11154   u8 sw_if_index_set = 0;
11155   u64 new_local_cookie = 0;
11156   u64 new_remote_cookie = 0;
11157   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11158   int ret;
11159
11160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11161     {
11162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11165         sw_if_index_set = 1;
11166       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11167         ;
11168       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11169         ;
11170       else
11171         break;
11172     }
11173
11174   if (sw_if_index_set == 0)
11175     {
11176       errmsg ("missing interface name or sw_if_index");
11177       return -99;
11178     }
11179
11180   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11181
11182   mp->sw_if_index = ntohl (sw_if_index);
11183   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11184   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11185
11186   S (mp);
11187   W (ret);
11188   return ret;
11189 }
11190
11191 static int
11192 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11193 {
11194   unformat_input_t *i = vam->input;
11195   vl_api_l2tpv3_interface_enable_disable_t *mp;
11196   u32 sw_if_index;
11197   u8 sw_if_index_set = 0;
11198   u8 enable_disable = 1;
11199   int ret;
11200
11201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11202     {
11203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11204         sw_if_index_set = 1;
11205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11206         sw_if_index_set = 1;
11207       else if (unformat (i, "enable"))
11208         enable_disable = 1;
11209       else if (unformat (i, "disable"))
11210         enable_disable = 0;
11211       else
11212         break;
11213     }
11214
11215   if (sw_if_index_set == 0)
11216     {
11217       errmsg ("missing interface name or sw_if_index");
11218       return -99;
11219     }
11220
11221   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11222
11223   mp->sw_if_index = ntohl (sw_if_index);
11224   mp->enable_disable = enable_disable;
11225
11226   S (mp);
11227   W (ret);
11228   return ret;
11229 }
11230
11231 static int
11232 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11233 {
11234   unformat_input_t *i = vam->input;
11235   vl_api_l2tpv3_set_lookup_key_t *mp;
11236   u8 key = ~0;
11237   int ret;
11238
11239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11240     {
11241       if (unformat (i, "lookup_v6_src"))
11242         key = L2T_LOOKUP_SRC_ADDRESS;
11243       else if (unformat (i, "lookup_v6_dst"))
11244         key = L2T_LOOKUP_DST_ADDRESS;
11245       else if (unformat (i, "lookup_session_id"))
11246         key = L2T_LOOKUP_SESSION_ID;
11247       else
11248         break;
11249     }
11250
11251   if (key == (u8) ~ 0)
11252     {
11253       errmsg ("l2tp session lookup key unset");
11254       return -99;
11255     }
11256
11257   M (L2TPV3_SET_LOOKUP_KEY, mp);
11258
11259   mp->key = key;
11260
11261   S (mp);
11262   W (ret);
11263   return ret;
11264 }
11265
11266 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11267   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11268 {
11269   vat_main_t *vam = &vat_main;
11270
11271   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11272          format_ip6_address, mp->our_address,
11273          format_ip6_address, mp->client_address,
11274          clib_net_to_host_u32 (mp->sw_if_index));
11275
11276   print (vam->ofp,
11277          "   local cookies %016llx %016llx remote cookie %016llx",
11278          clib_net_to_host_u64 (mp->local_cookie[0]),
11279          clib_net_to_host_u64 (mp->local_cookie[1]),
11280          clib_net_to_host_u64 (mp->remote_cookie));
11281
11282   print (vam->ofp, "   local session-id %d remote session-id %d",
11283          clib_net_to_host_u32 (mp->local_session_id),
11284          clib_net_to_host_u32 (mp->remote_session_id));
11285
11286   print (vam->ofp, "   l2 specific sublayer %s\n",
11287          mp->l2_sublayer_present ? "preset" : "absent");
11288
11289 }
11290
11291 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11292   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11293 {
11294   vat_main_t *vam = &vat_main;
11295   vat_json_node_t *node = NULL;
11296   struct in6_addr addr;
11297
11298   if (VAT_JSON_ARRAY != vam->json_tree.type)
11299     {
11300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11301       vat_json_init_array (&vam->json_tree);
11302     }
11303   node = vat_json_array_add (&vam->json_tree);
11304
11305   vat_json_init_object (node);
11306
11307   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11308   vat_json_object_add_ip6 (node, "our_address", addr);
11309   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11310   vat_json_object_add_ip6 (node, "client_address", addr);
11311
11312   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11313   vat_json_init_array (lc);
11314   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11315   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11316   vat_json_object_add_uint (node, "remote_cookie",
11317                             clib_net_to_host_u64 (mp->remote_cookie));
11318
11319   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11320   vat_json_object_add_uint (node, "local_session_id",
11321                             clib_net_to_host_u32 (mp->local_session_id));
11322   vat_json_object_add_uint (node, "remote_session_id",
11323                             clib_net_to_host_u32 (mp->remote_session_id));
11324   vat_json_object_add_string_copy (node, "l2_sublayer",
11325                                    mp->l2_sublayer_present ? (u8 *) "present"
11326                                    : (u8 *) "absent");
11327 }
11328
11329 static int
11330 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11331 {
11332   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11333   vl_api_control_ping_t *mp_ping;
11334   int ret;
11335
11336   /* Get list of l2tpv3-tunnel interfaces */
11337   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11338   S (mp);
11339
11340   /* Use a control ping for synchronization */
11341   MPING (CONTROL_PING, mp_ping);
11342   S (mp_ping);
11343
11344   W (ret);
11345   return ret;
11346 }
11347
11348
11349 static void vl_api_sw_interface_tap_v2_details_t_handler
11350   (vl_api_sw_interface_tap_v2_details_t * mp)
11351 {
11352   vat_main_t *vam = &vat_main;
11353
11354   u8 *ip4 =
11355     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11356             mp->host_ip4_prefix.len);
11357   u8 *ip6 =
11358     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11359             mp->host_ip6_prefix.len);
11360
11361   print (vam->ofp,
11362          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11363          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11364          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11365          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11366          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11367
11368   vec_free (ip4);
11369   vec_free (ip6);
11370 }
11371
11372 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11373   (vl_api_sw_interface_tap_v2_details_t * mp)
11374 {
11375   vat_main_t *vam = &vat_main;
11376   vat_json_node_t *node = NULL;
11377
11378   if (VAT_JSON_ARRAY != vam->json_tree.type)
11379     {
11380       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11381       vat_json_init_array (&vam->json_tree);
11382     }
11383   node = vat_json_array_add (&vam->json_tree);
11384
11385   vat_json_init_object (node);
11386   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11387   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11388   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11389   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11390   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11391   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11392   vat_json_object_add_string_copy (node, "host_mac_addr",
11393                                    format (0, "%U", format_ethernet_address,
11394                                            &mp->host_mac_addr));
11395   vat_json_object_add_string_copy (node, "host_namespace",
11396                                    mp->host_namespace);
11397   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11398   vat_json_object_add_string_copy (node, "host_ip4_addr",
11399                                    format (0, "%U/%d", format_ip4_address,
11400                                            mp->host_ip4_prefix.address,
11401                                            mp->host_ip4_prefix.len));
11402   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11403                                    format (0, "%U/%d", format_ip6_address,
11404                                            mp->host_ip6_prefix.address,
11405                                            mp->host_ip6_prefix.len));
11406
11407 }
11408
11409 static int
11410 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11411 {
11412   vl_api_sw_interface_tap_v2_dump_t *mp;
11413   vl_api_control_ping_t *mp_ping;
11414   int ret;
11415
11416   print (vam->ofp,
11417          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11418          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11419          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11420          "host_ip6_addr");
11421
11422   /* Get list of tap interfaces */
11423   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11424   S (mp);
11425
11426   /* Use a control ping for synchronization */
11427   MPING (CONTROL_PING, mp_ping);
11428   S (mp_ping);
11429
11430   W (ret);
11431   return ret;
11432 }
11433
11434 static void vl_api_sw_interface_virtio_pci_details_t_handler
11435   (vl_api_sw_interface_virtio_pci_details_t * mp)
11436 {
11437   vat_main_t *vam = &vat_main;
11438
11439   typedef union
11440   {
11441     struct
11442     {
11443       u16 domain;
11444       u8 bus;
11445       u8 slot:5;
11446       u8 function:3;
11447     };
11448     u32 as_u32;
11449   } pci_addr_t;
11450   pci_addr_t addr;
11451
11452   addr.domain = ntohs (mp->pci_addr.domain);
11453   addr.bus = mp->pci_addr.bus;
11454   addr.slot = mp->pci_addr.slot;
11455   addr.function = mp->pci_addr.function;
11456
11457   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11458                          addr.slot, addr.function);
11459
11460   print (vam->ofp,
11461          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11462          pci_addr, ntohl (mp->sw_if_index),
11463          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11464          format_ethernet_address, mp->mac_addr,
11465          clib_net_to_host_u64 (mp->features));
11466   vec_free (pci_addr);
11467 }
11468
11469 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11470   (vl_api_sw_interface_virtio_pci_details_t * mp)
11471 {
11472   vat_main_t *vam = &vat_main;
11473   vat_json_node_t *node = NULL;
11474   vlib_pci_addr_t pci_addr;
11475
11476   if (VAT_JSON_ARRAY != vam->json_tree.type)
11477     {
11478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11479       vat_json_init_array (&vam->json_tree);
11480     }
11481   node = vat_json_array_add (&vam->json_tree);
11482
11483   pci_addr.domain = ntohs (mp->pci_addr.domain);
11484   pci_addr.bus = mp->pci_addr.bus;
11485   pci_addr.slot = mp->pci_addr.slot;
11486   pci_addr.function = mp->pci_addr.function;
11487
11488   vat_json_init_object (node);
11489   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11491   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11492   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11493   vat_json_object_add_uint (node, "features",
11494                             clib_net_to_host_u64 (mp->features));
11495   vat_json_object_add_string_copy (node, "mac_addr",
11496                                    format (0, "%U", format_ethernet_address,
11497                                            &mp->mac_addr));
11498 }
11499
11500 static int
11501 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11502 {
11503   vl_api_sw_interface_virtio_pci_dump_t *mp;
11504   vl_api_control_ping_t *mp_ping;
11505   int ret;
11506
11507   print (vam->ofp,
11508          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11509          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11510          "mac_addr", "features");
11511
11512   /* Get list of tap interfaces */
11513   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11514   S (mp);
11515
11516   /* Use a control ping for synchronization */
11517   MPING (CONTROL_PING, mp_ping);
11518   S (mp_ping);
11519
11520   W (ret);
11521   return ret;
11522 }
11523
11524 static int
11525 api_vxlan_offload_rx (vat_main_t * vam)
11526 {
11527   unformat_input_t *line_input = vam->input;
11528   vl_api_vxlan_offload_rx_t *mp;
11529   u32 hw_if_index = ~0, rx_if_index = ~0;
11530   u8 is_add = 1;
11531   int ret;
11532
11533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (line_input, "del"))
11536         is_add = 0;
11537       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11538                          &hw_if_index))
11539         ;
11540       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11541         ;
11542       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11543                          &rx_if_index))
11544         ;
11545       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11546         ;
11547       else
11548         {
11549           errmsg ("parse error '%U'", format_unformat_error, line_input);
11550           return -99;
11551         }
11552     }
11553
11554   if (hw_if_index == ~0)
11555     {
11556       errmsg ("no hw interface");
11557       return -99;
11558     }
11559
11560   if (rx_if_index == ~0)
11561     {
11562       errmsg ("no rx tunnel");
11563       return -99;
11564     }
11565
11566   M (VXLAN_OFFLOAD_RX, mp);
11567
11568   mp->hw_if_index = ntohl (hw_if_index);
11569   mp->sw_if_index = ntohl (rx_if_index);
11570   mp->enable = is_add;
11571
11572   S (mp);
11573   W (ret);
11574   return ret;
11575 }
11576
11577 static uword unformat_vxlan_decap_next
11578   (unformat_input_t * input, va_list * args)
11579 {
11580   u32 *result = va_arg (*args, u32 *);
11581   u32 tmp;
11582
11583   if (unformat (input, "l2"))
11584     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11585   else if (unformat (input, "%d", &tmp))
11586     *result = tmp;
11587   else
11588     return 0;
11589   return 1;
11590 }
11591
11592 static int
11593 api_vxlan_add_del_tunnel (vat_main_t * vam)
11594 {
11595   unformat_input_t *line_input = vam->input;
11596   vl_api_vxlan_add_del_tunnel_t *mp;
11597   ip46_address_t src, dst;
11598   u8 is_add = 1;
11599   u8 ipv4_set = 0, ipv6_set = 0;
11600   u8 src_set = 0;
11601   u8 dst_set = 0;
11602   u8 grp_set = 0;
11603   u32 instance = ~0;
11604   u32 mcast_sw_if_index = ~0;
11605   u32 encap_vrf_id = 0;
11606   u32 decap_next_index = ~0;
11607   u32 vni = 0;
11608   int ret;
11609
11610   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11611   clib_memset (&src, 0, sizeof src);
11612   clib_memset (&dst, 0, sizeof dst);
11613
11614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11615     {
11616       if (unformat (line_input, "del"))
11617         is_add = 0;
11618       else if (unformat (line_input, "instance %d", &instance))
11619         ;
11620       else
11621         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11622         {
11623           ipv4_set = 1;
11624           src_set = 1;
11625         }
11626       else
11627         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11628         {
11629           ipv4_set = 1;
11630           dst_set = 1;
11631         }
11632       else
11633         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11634         {
11635           ipv6_set = 1;
11636           src_set = 1;
11637         }
11638       else
11639         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11640         {
11641           ipv6_set = 1;
11642           dst_set = 1;
11643         }
11644       else if (unformat (line_input, "group %U %U",
11645                          unformat_ip4_address, &dst.ip4,
11646                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11647         {
11648           grp_set = dst_set = 1;
11649           ipv4_set = 1;
11650         }
11651       else if (unformat (line_input, "group %U",
11652                          unformat_ip4_address, &dst.ip4))
11653         {
11654           grp_set = dst_set = 1;
11655           ipv4_set = 1;
11656         }
11657       else if (unformat (line_input, "group %U %U",
11658                          unformat_ip6_address, &dst.ip6,
11659                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11660         {
11661           grp_set = dst_set = 1;
11662           ipv6_set = 1;
11663         }
11664       else if (unformat (line_input, "group %U",
11665                          unformat_ip6_address, &dst.ip6))
11666         {
11667           grp_set = dst_set = 1;
11668           ipv6_set = 1;
11669         }
11670       else
11671         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11672         ;
11673       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11674         ;
11675       else if (unformat (line_input, "decap-next %U",
11676                          unformat_vxlan_decap_next, &decap_next_index))
11677         ;
11678       else if (unformat (line_input, "vni %d", &vni))
11679         ;
11680       else
11681         {
11682           errmsg ("parse error '%U'", format_unformat_error, line_input);
11683           return -99;
11684         }
11685     }
11686
11687   if (src_set == 0)
11688     {
11689       errmsg ("tunnel src address not specified");
11690       return -99;
11691     }
11692   if (dst_set == 0)
11693     {
11694       errmsg ("tunnel dst address not specified");
11695       return -99;
11696     }
11697
11698   if (grp_set && !ip46_address_is_multicast (&dst))
11699     {
11700       errmsg ("tunnel group address not multicast");
11701       return -99;
11702     }
11703   if (grp_set && mcast_sw_if_index == ~0)
11704     {
11705       errmsg ("tunnel nonexistent multicast device");
11706       return -99;
11707     }
11708   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11709     {
11710       errmsg ("tunnel dst address must be unicast");
11711       return -99;
11712     }
11713
11714
11715   if (ipv4_set && ipv6_set)
11716     {
11717       errmsg ("both IPv4 and IPv6 addresses specified");
11718       return -99;
11719     }
11720
11721   if ((vni == 0) || (vni >> 24))
11722     {
11723       errmsg ("vni not specified or out of range");
11724       return -99;
11725     }
11726
11727   M (VXLAN_ADD_DEL_TUNNEL, mp);
11728
11729   if (ipv6_set)
11730     {
11731       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11732       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11733     }
11734   else
11735     {
11736       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11737       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11738     }
11739   mp->src_address.af = ipv6_set;
11740   mp->dst_address.af = ipv6_set;
11741
11742   mp->instance = htonl (instance);
11743   mp->encap_vrf_id = ntohl (encap_vrf_id);
11744   mp->decap_next_index = ntohl (decap_next_index);
11745   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11746   mp->vni = ntohl (vni);
11747   mp->is_add = is_add;
11748
11749   S (mp);
11750   W (ret);
11751   return ret;
11752 }
11753
11754 static void vl_api_vxlan_tunnel_details_t_handler
11755   (vl_api_vxlan_tunnel_details_t * mp)
11756 {
11757   vat_main_t *vam = &vat_main;
11758   ip46_address_t src =
11759     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11760   ip46_address_t dst =
11761     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11762
11763   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11764          ntohl (mp->sw_if_index),
11765          ntohl (mp->instance),
11766          format_ip46_address, &src, IP46_TYPE_ANY,
11767          format_ip46_address, &dst, IP46_TYPE_ANY,
11768          ntohl (mp->encap_vrf_id),
11769          ntohl (mp->decap_next_index), ntohl (mp->vni),
11770          ntohl (mp->mcast_sw_if_index));
11771 }
11772
11773 static void vl_api_vxlan_tunnel_details_t_handler_json
11774   (vl_api_vxlan_tunnel_details_t * mp)
11775 {
11776   vat_main_t *vam = &vat_main;
11777   vat_json_node_t *node = NULL;
11778
11779   if (VAT_JSON_ARRAY != vam->json_tree.type)
11780     {
11781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11782       vat_json_init_array (&vam->json_tree);
11783     }
11784   node = vat_json_array_add (&vam->json_tree);
11785
11786   vat_json_init_object (node);
11787   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11788
11789   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11790
11791   if (mp->src_address.af)
11792     {
11793       struct in6_addr ip6;
11794
11795       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11796       vat_json_object_add_ip6 (node, "src_address", ip6);
11797       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11798       vat_json_object_add_ip6 (node, "dst_address", ip6);
11799     }
11800   else
11801     {
11802       struct in_addr ip4;
11803
11804       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11805       vat_json_object_add_ip4 (node, "src_address", ip4);
11806       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11807       vat_json_object_add_ip4 (node, "dst_address", ip4);
11808     }
11809   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11810   vat_json_object_add_uint (node, "decap_next_index",
11811                             ntohl (mp->decap_next_index));
11812   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11813   vat_json_object_add_uint (node, "mcast_sw_if_index",
11814                             ntohl (mp->mcast_sw_if_index));
11815 }
11816
11817 static int
11818 api_vxlan_tunnel_dump (vat_main_t * vam)
11819 {
11820   unformat_input_t *i = vam->input;
11821   vl_api_vxlan_tunnel_dump_t *mp;
11822   vl_api_control_ping_t *mp_ping;
11823   u32 sw_if_index;
11824   u8 sw_if_index_set = 0;
11825   int ret;
11826
11827   /* Parse args required to build the message */
11828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11829     {
11830       if (unformat (i, "sw_if_index %d", &sw_if_index))
11831         sw_if_index_set = 1;
11832       else
11833         break;
11834     }
11835
11836   if (sw_if_index_set == 0)
11837     {
11838       sw_if_index = ~0;
11839     }
11840
11841   if (!vam->json_output)
11842     {
11843       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11844              "sw_if_index", "instance", "src_address", "dst_address",
11845              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11846     }
11847
11848   /* Get list of vxlan-tunnel interfaces */
11849   M (VXLAN_TUNNEL_DUMP, mp);
11850
11851   mp->sw_if_index = htonl (sw_if_index);
11852
11853   S (mp);
11854
11855   /* Use a control ping for synchronization */
11856   MPING (CONTROL_PING, mp_ping);
11857   S (mp_ping);
11858
11859   W (ret);
11860   return ret;
11861 }
11862
11863 static uword unformat_geneve_decap_next
11864   (unformat_input_t * input, va_list * args)
11865 {
11866   u32 *result = va_arg (*args, u32 *);
11867   u32 tmp;
11868
11869   if (unformat (input, "l2"))
11870     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11871   else if (unformat (input, "%d", &tmp))
11872     *result = tmp;
11873   else
11874     return 0;
11875   return 1;
11876 }
11877
11878 static int
11879 api_geneve_add_del_tunnel (vat_main_t * vam)
11880 {
11881   unformat_input_t *line_input = vam->input;
11882   vl_api_geneve_add_del_tunnel_t *mp;
11883   ip46_address_t src, dst;
11884   u8 is_add = 1;
11885   u8 ipv4_set = 0, ipv6_set = 0;
11886   u8 src_set = 0;
11887   u8 dst_set = 0;
11888   u8 grp_set = 0;
11889   u32 mcast_sw_if_index = ~0;
11890   u32 encap_vrf_id = 0;
11891   u32 decap_next_index = ~0;
11892   u32 vni = 0;
11893   int ret;
11894
11895   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11896   clib_memset (&src, 0, sizeof src);
11897   clib_memset (&dst, 0, sizeof dst);
11898
11899   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11900     {
11901       if (unformat (line_input, "del"))
11902         is_add = 0;
11903       else
11904         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11905         {
11906           ipv4_set = 1;
11907           src_set = 1;
11908         }
11909       else
11910         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11911         {
11912           ipv4_set = 1;
11913           dst_set = 1;
11914         }
11915       else
11916         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11917         {
11918           ipv6_set = 1;
11919           src_set = 1;
11920         }
11921       else
11922         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11923         {
11924           ipv6_set = 1;
11925           dst_set = 1;
11926         }
11927       else if (unformat (line_input, "group %U %U",
11928                          unformat_ip4_address, &dst.ip4,
11929                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11930         {
11931           grp_set = dst_set = 1;
11932           ipv4_set = 1;
11933         }
11934       else if (unformat (line_input, "group %U",
11935                          unformat_ip4_address, &dst.ip4))
11936         {
11937           grp_set = dst_set = 1;
11938           ipv4_set = 1;
11939         }
11940       else if (unformat (line_input, "group %U %U",
11941                          unformat_ip6_address, &dst.ip6,
11942                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11943         {
11944           grp_set = dst_set = 1;
11945           ipv6_set = 1;
11946         }
11947       else if (unformat (line_input, "group %U",
11948                          unformat_ip6_address, &dst.ip6))
11949         {
11950           grp_set = dst_set = 1;
11951           ipv6_set = 1;
11952         }
11953       else
11954         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11955         ;
11956       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11957         ;
11958       else if (unformat (line_input, "decap-next %U",
11959                          unformat_geneve_decap_next, &decap_next_index))
11960         ;
11961       else if (unformat (line_input, "vni %d", &vni))
11962         ;
11963       else
11964         {
11965           errmsg ("parse error '%U'", format_unformat_error, line_input);
11966           return -99;
11967         }
11968     }
11969
11970   if (src_set == 0)
11971     {
11972       errmsg ("tunnel src address not specified");
11973       return -99;
11974     }
11975   if (dst_set == 0)
11976     {
11977       errmsg ("tunnel dst address not specified");
11978       return -99;
11979     }
11980
11981   if (grp_set && !ip46_address_is_multicast (&dst))
11982     {
11983       errmsg ("tunnel group address not multicast");
11984       return -99;
11985     }
11986   if (grp_set && mcast_sw_if_index == ~0)
11987     {
11988       errmsg ("tunnel nonexistent multicast device");
11989       return -99;
11990     }
11991   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11992     {
11993       errmsg ("tunnel dst address must be unicast");
11994       return -99;
11995     }
11996
11997
11998   if (ipv4_set && ipv6_set)
11999     {
12000       errmsg ("both IPv4 and IPv6 addresses specified");
12001       return -99;
12002     }
12003
12004   if ((vni == 0) || (vni >> 24))
12005     {
12006       errmsg ("vni not specified or out of range");
12007       return -99;
12008     }
12009
12010   M (GENEVE_ADD_DEL_TUNNEL, mp);
12011
12012   if (ipv6_set)
12013     {
12014       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12015       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12016     }
12017   else
12018     {
12019       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12020       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12021     }
12022   mp->encap_vrf_id = ntohl (encap_vrf_id);
12023   mp->decap_next_index = ntohl (decap_next_index);
12024   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12025   mp->vni = ntohl (vni);
12026   mp->is_add = is_add;
12027
12028   S (mp);
12029   W (ret);
12030   return ret;
12031 }
12032
12033 static void vl_api_geneve_tunnel_details_t_handler
12034   (vl_api_geneve_tunnel_details_t * mp)
12035 {
12036   vat_main_t *vam = &vat_main;
12037   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12038   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12039
12040   if (mp->src_address.af == ADDRESS_IP6)
12041     {
12042       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12043       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12044     }
12045   else
12046     {
12047       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12048       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12049     }
12050
12051   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12052          ntohl (mp->sw_if_index),
12053          format_ip46_address, &src, IP46_TYPE_ANY,
12054          format_ip46_address, &dst, IP46_TYPE_ANY,
12055          ntohl (mp->encap_vrf_id),
12056          ntohl (mp->decap_next_index), ntohl (mp->vni),
12057          ntohl (mp->mcast_sw_if_index));
12058 }
12059
12060 static void vl_api_geneve_tunnel_details_t_handler_json
12061   (vl_api_geneve_tunnel_details_t * mp)
12062 {
12063   vat_main_t *vam = &vat_main;
12064   vat_json_node_t *node = NULL;
12065   bool is_ipv6;
12066
12067   if (VAT_JSON_ARRAY != vam->json_tree.type)
12068     {
12069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12070       vat_json_init_array (&vam->json_tree);
12071     }
12072   node = vat_json_array_add (&vam->json_tree);
12073
12074   vat_json_init_object (node);
12075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12076   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12077   if (is_ipv6)
12078     {
12079       struct in6_addr ip6;
12080
12081       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12082       vat_json_object_add_ip6 (node, "src_address", ip6);
12083       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12084       vat_json_object_add_ip6 (node, "dst_address", ip6);
12085     }
12086   else
12087     {
12088       struct in_addr ip4;
12089
12090       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12091       vat_json_object_add_ip4 (node, "src_address", ip4);
12092       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12093       vat_json_object_add_ip4 (node, "dst_address", ip4);
12094     }
12095   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12096   vat_json_object_add_uint (node, "decap_next_index",
12097                             ntohl (mp->decap_next_index));
12098   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12099   vat_json_object_add_uint (node, "mcast_sw_if_index",
12100                             ntohl (mp->mcast_sw_if_index));
12101 }
12102
12103 static int
12104 api_geneve_tunnel_dump (vat_main_t * vam)
12105 {
12106   unformat_input_t *i = vam->input;
12107   vl_api_geneve_tunnel_dump_t *mp;
12108   vl_api_control_ping_t *mp_ping;
12109   u32 sw_if_index;
12110   u8 sw_if_index_set = 0;
12111   int ret;
12112
12113   /* Parse args required to build the message */
12114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12115     {
12116       if (unformat (i, "sw_if_index %d", &sw_if_index))
12117         sw_if_index_set = 1;
12118       else
12119         break;
12120     }
12121
12122   if (sw_if_index_set == 0)
12123     {
12124       sw_if_index = ~0;
12125     }
12126
12127   if (!vam->json_output)
12128     {
12129       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12130              "sw_if_index", "local_address", "remote_address",
12131              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12132     }
12133
12134   /* Get list of geneve-tunnel interfaces */
12135   M (GENEVE_TUNNEL_DUMP, mp);
12136
12137   mp->sw_if_index = htonl (sw_if_index);
12138
12139   S (mp);
12140
12141   /* Use a control ping for synchronization */
12142   M (CONTROL_PING, mp_ping);
12143   S (mp_ping);
12144
12145   W (ret);
12146   return ret;
12147 }
12148
12149 static int
12150 api_gre_tunnel_add_del (vat_main_t * vam)
12151 {
12152   unformat_input_t *line_input = vam->input;
12153   vl_api_address_t src = { }, dst =
12154   {
12155   };
12156   vl_api_gre_tunnel_add_del_t *mp;
12157   vl_api_gre_tunnel_type_t t_type;
12158   u8 is_add = 1;
12159   u8 src_set = 0;
12160   u8 dst_set = 0;
12161   u32 outer_table_id = 0;
12162   u32 session_id = 0;
12163   u32 instance = ~0;
12164   int ret;
12165
12166   t_type = GRE_API_TUNNEL_TYPE_L3;
12167
12168   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12169     {
12170       if (unformat (line_input, "del"))
12171         is_add = 0;
12172       else if (unformat (line_input, "instance %d", &instance))
12173         ;
12174       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12175         {
12176           src_set = 1;
12177         }
12178       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12179         {
12180           dst_set = 1;
12181         }
12182       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12183         ;
12184       else if (unformat (line_input, "teb"))
12185         t_type = GRE_API_TUNNEL_TYPE_TEB;
12186       else if (unformat (line_input, "erspan %d", &session_id))
12187         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12188       else
12189         {
12190           errmsg ("parse error '%U'", format_unformat_error, line_input);
12191           return -99;
12192         }
12193     }
12194
12195   if (src_set == 0)
12196     {
12197       errmsg ("tunnel src address not specified");
12198       return -99;
12199     }
12200   if (dst_set == 0)
12201     {
12202       errmsg ("tunnel dst address not specified");
12203       return -99;
12204     }
12205
12206   M (GRE_TUNNEL_ADD_DEL, mp);
12207
12208   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12209   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12210
12211   mp->tunnel.instance = htonl (instance);
12212   mp->tunnel.outer_table_id = htonl (outer_table_id);
12213   mp->is_add = is_add;
12214   mp->tunnel.session_id = htons ((u16) session_id);
12215   mp->tunnel.type = htonl (t_type);
12216
12217   S (mp);
12218   W (ret);
12219   return ret;
12220 }
12221
12222 static void vl_api_gre_tunnel_details_t_handler
12223   (vl_api_gre_tunnel_details_t * mp)
12224 {
12225   vat_main_t *vam = &vat_main;
12226
12227   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12228          ntohl (mp->tunnel.sw_if_index),
12229          ntohl (mp->tunnel.instance),
12230          format_vl_api_address, &mp->tunnel.src,
12231          format_vl_api_address, &mp->tunnel.dst,
12232          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12233          ntohl (mp->tunnel.session_id));
12234 }
12235
12236 static void vl_api_gre_tunnel_details_t_handler_json
12237   (vl_api_gre_tunnel_details_t * mp)
12238 {
12239   vat_main_t *vam = &vat_main;
12240   vat_json_node_t *node = NULL;
12241
12242   if (VAT_JSON_ARRAY != vam->json_tree.type)
12243     {
12244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12245       vat_json_init_array (&vam->json_tree);
12246     }
12247   node = vat_json_array_add (&vam->json_tree);
12248
12249   vat_json_init_object (node);
12250   vat_json_object_add_uint (node, "sw_if_index",
12251                             ntohl (mp->tunnel.sw_if_index));
12252   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12253
12254   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12255   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12256   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12257   vat_json_object_add_uint (node, "outer_table_id",
12258                             ntohl (mp->tunnel.outer_table_id));
12259   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12260 }
12261
12262 static int
12263 api_gre_tunnel_dump (vat_main_t * vam)
12264 {
12265   unformat_input_t *i = vam->input;
12266   vl_api_gre_tunnel_dump_t *mp;
12267   vl_api_control_ping_t *mp_ping;
12268   u32 sw_if_index;
12269   u8 sw_if_index_set = 0;
12270   int ret;
12271
12272   /* Parse args required to build the message */
12273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12274     {
12275       if (unformat (i, "sw_if_index %d", &sw_if_index))
12276         sw_if_index_set = 1;
12277       else
12278         break;
12279     }
12280
12281   if (sw_if_index_set == 0)
12282     {
12283       sw_if_index = ~0;
12284     }
12285
12286   if (!vam->json_output)
12287     {
12288       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12289              "sw_if_index", "instance", "src_address", "dst_address",
12290              "tunnel_type", "outer_fib_id", "session_id");
12291     }
12292
12293   /* Get list of gre-tunnel interfaces */
12294   M (GRE_TUNNEL_DUMP, mp);
12295
12296   mp->sw_if_index = htonl (sw_if_index);
12297
12298   S (mp);
12299
12300   /* Use a control ping for synchronization */
12301   MPING (CONTROL_PING, mp_ping);
12302   S (mp_ping);
12303
12304   W (ret);
12305   return ret;
12306 }
12307
12308 static int
12309 api_l2_fib_clear_table (vat_main_t * vam)
12310 {
12311 //  unformat_input_t * i = vam->input;
12312   vl_api_l2_fib_clear_table_t *mp;
12313   int ret;
12314
12315   M (L2_FIB_CLEAR_TABLE, mp);
12316
12317   S (mp);
12318   W (ret);
12319   return ret;
12320 }
12321
12322 static int
12323 api_l2_interface_efp_filter (vat_main_t * vam)
12324 {
12325   unformat_input_t *i = vam->input;
12326   vl_api_l2_interface_efp_filter_t *mp;
12327   u32 sw_if_index;
12328   u8 enable = 1;
12329   u8 sw_if_index_set = 0;
12330   int ret;
12331
12332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12333     {
12334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12335         sw_if_index_set = 1;
12336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12337         sw_if_index_set = 1;
12338       else if (unformat (i, "enable"))
12339         enable = 1;
12340       else if (unformat (i, "disable"))
12341         enable = 0;
12342       else
12343         {
12344           clib_warning ("parse error '%U'", format_unformat_error, i);
12345           return -99;
12346         }
12347     }
12348
12349   if (sw_if_index_set == 0)
12350     {
12351       errmsg ("missing sw_if_index");
12352       return -99;
12353     }
12354
12355   M (L2_INTERFACE_EFP_FILTER, mp);
12356
12357   mp->sw_if_index = ntohl (sw_if_index);
12358   mp->enable_disable = enable;
12359
12360   S (mp);
12361   W (ret);
12362   return ret;
12363 }
12364
12365 #define foreach_vtr_op                          \
12366 _("disable",  L2_VTR_DISABLED)                  \
12367 _("push-1",  L2_VTR_PUSH_1)                     \
12368 _("push-2",  L2_VTR_PUSH_2)                     \
12369 _("pop-1",  L2_VTR_POP_1)                       \
12370 _("pop-2",  L2_VTR_POP_2)                       \
12371 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12372 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12373 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12374 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12375
12376 static int
12377 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12378 {
12379   unformat_input_t *i = vam->input;
12380   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12381   u32 sw_if_index;
12382   u8 sw_if_index_set = 0;
12383   u8 vtr_op_set = 0;
12384   u32 vtr_op = 0;
12385   u32 push_dot1q = 1;
12386   u32 tag1 = ~0;
12387   u32 tag2 = ~0;
12388   int ret;
12389
12390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12391     {
12392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12393         sw_if_index_set = 1;
12394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12395         sw_if_index_set = 1;
12396       else if (unformat (i, "vtr_op %d", &vtr_op))
12397         vtr_op_set = 1;
12398 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12399       foreach_vtr_op
12400 #undef _
12401         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12402         ;
12403       else if (unformat (i, "tag1 %d", &tag1))
12404         ;
12405       else if (unformat (i, "tag2 %d", &tag2))
12406         ;
12407       else
12408         {
12409           clib_warning ("parse error '%U'", format_unformat_error, i);
12410           return -99;
12411         }
12412     }
12413
12414   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12415     {
12416       errmsg ("missing vtr operation or sw_if_index");
12417       return -99;
12418     }
12419
12420   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12421   mp->sw_if_index = ntohl (sw_if_index);
12422   mp->vtr_op = ntohl (vtr_op);
12423   mp->push_dot1q = ntohl (push_dot1q);
12424   mp->tag1 = ntohl (tag1);
12425   mp->tag2 = ntohl (tag2);
12426
12427   S (mp);
12428   W (ret);
12429   return ret;
12430 }
12431
12432 static int
12433 api_create_vhost_user_if (vat_main_t * vam)
12434 {
12435   unformat_input_t *i = vam->input;
12436   vl_api_create_vhost_user_if_t *mp;
12437   u8 *file_name;
12438   u8 is_server = 0;
12439   u8 file_name_set = 0;
12440   u32 custom_dev_instance = ~0;
12441   u8 hwaddr[6];
12442   u8 use_custom_mac = 0;
12443   u8 disable_mrg_rxbuf = 0;
12444   u8 disable_indirect_desc = 0;
12445   u8 *tag = 0;
12446   u8 enable_gso = 0;
12447   int ret;
12448
12449   /* Shut up coverity */
12450   clib_memset (hwaddr, 0, sizeof (hwaddr));
12451
12452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12453     {
12454       if (unformat (i, "socket %s", &file_name))
12455         {
12456           file_name_set = 1;
12457         }
12458       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12459         ;
12460       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12461         use_custom_mac = 1;
12462       else if (unformat (i, "server"))
12463         is_server = 1;
12464       else if (unformat (i, "disable_mrg_rxbuf"))
12465         disable_mrg_rxbuf = 1;
12466       else if (unformat (i, "disable_indirect_desc"))
12467         disable_indirect_desc = 1;
12468       else if (unformat (i, "gso"))
12469         enable_gso = 1;
12470       else if (unformat (i, "tag %s", &tag))
12471         ;
12472       else
12473         break;
12474     }
12475
12476   if (file_name_set == 0)
12477     {
12478       errmsg ("missing socket file name");
12479       return -99;
12480     }
12481
12482   if (vec_len (file_name) > 255)
12483     {
12484       errmsg ("socket file name too long");
12485       return -99;
12486     }
12487   vec_add1 (file_name, 0);
12488
12489   M (CREATE_VHOST_USER_IF, mp);
12490
12491   mp->is_server = is_server;
12492   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12493   mp->disable_indirect_desc = disable_indirect_desc;
12494   mp->enable_gso = enable_gso;
12495   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12496   vec_free (file_name);
12497   if (custom_dev_instance != ~0)
12498     {
12499       mp->renumber = 1;
12500       mp->custom_dev_instance = ntohl (custom_dev_instance);
12501     }
12502
12503   mp->use_custom_mac = use_custom_mac;
12504   clib_memcpy (mp->mac_address, hwaddr, 6);
12505   if (tag)
12506     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12507   vec_free (tag);
12508
12509   S (mp);
12510   W (ret);
12511   return ret;
12512 }
12513
12514 static int
12515 api_modify_vhost_user_if (vat_main_t * vam)
12516 {
12517   unformat_input_t *i = vam->input;
12518   vl_api_modify_vhost_user_if_t *mp;
12519   u8 *file_name;
12520   u8 is_server = 0;
12521   u8 file_name_set = 0;
12522   u32 custom_dev_instance = ~0;
12523   u8 sw_if_index_set = 0;
12524   u32 sw_if_index = (u32) ~ 0;
12525   u8 enable_gso = 0;
12526   int ret;
12527
12528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12529     {
12530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12531         sw_if_index_set = 1;
12532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12533         sw_if_index_set = 1;
12534       else if (unformat (i, "socket %s", &file_name))
12535         {
12536           file_name_set = 1;
12537         }
12538       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12539         ;
12540       else if (unformat (i, "server"))
12541         is_server = 1;
12542       else if (unformat (i, "gso"))
12543         enable_gso = 1;
12544       else
12545         break;
12546     }
12547
12548   if (sw_if_index_set == 0)
12549     {
12550       errmsg ("missing sw_if_index or interface name");
12551       return -99;
12552     }
12553
12554   if (file_name_set == 0)
12555     {
12556       errmsg ("missing socket file name");
12557       return -99;
12558     }
12559
12560   if (vec_len (file_name) > 255)
12561     {
12562       errmsg ("socket file name too long");
12563       return -99;
12564     }
12565   vec_add1 (file_name, 0);
12566
12567   M (MODIFY_VHOST_USER_IF, mp);
12568
12569   mp->sw_if_index = ntohl (sw_if_index);
12570   mp->is_server = is_server;
12571   mp->enable_gso = enable_gso;
12572   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12573   vec_free (file_name);
12574   if (custom_dev_instance != ~0)
12575     {
12576       mp->renumber = 1;
12577       mp->custom_dev_instance = ntohl (custom_dev_instance);
12578     }
12579
12580   S (mp);
12581   W (ret);
12582   return ret;
12583 }
12584
12585 static int
12586 api_delete_vhost_user_if (vat_main_t * vam)
12587 {
12588   unformat_input_t *i = vam->input;
12589   vl_api_delete_vhost_user_if_t *mp;
12590   u32 sw_if_index = ~0;
12591   u8 sw_if_index_set = 0;
12592   int ret;
12593
12594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12595     {
12596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12597         sw_if_index_set = 1;
12598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12599         sw_if_index_set = 1;
12600       else
12601         break;
12602     }
12603
12604   if (sw_if_index_set == 0)
12605     {
12606       errmsg ("missing sw_if_index or interface name");
12607       return -99;
12608     }
12609
12610
12611   M (DELETE_VHOST_USER_IF, mp);
12612
12613   mp->sw_if_index = ntohl (sw_if_index);
12614
12615   S (mp);
12616   W (ret);
12617   return ret;
12618 }
12619
12620 static void vl_api_sw_interface_vhost_user_details_t_handler
12621   (vl_api_sw_interface_vhost_user_details_t * mp)
12622 {
12623   vat_main_t *vam = &vat_main;
12624   u64 features;
12625
12626   features =
12627     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12628                                                     clib_net_to_host_u32
12629                                                     (mp->features_last_32) <<
12630                                                     32);
12631
12632   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12633          (char *) mp->interface_name,
12634          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12635          features, mp->is_server,
12636          ntohl (mp->num_regions), (char *) mp->sock_filename);
12637   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12638 }
12639
12640 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12641   (vl_api_sw_interface_vhost_user_details_t * mp)
12642 {
12643   vat_main_t *vam = &vat_main;
12644   vat_json_node_t *node = NULL;
12645
12646   if (VAT_JSON_ARRAY != vam->json_tree.type)
12647     {
12648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12649       vat_json_init_array (&vam->json_tree);
12650     }
12651   node = vat_json_array_add (&vam->json_tree);
12652
12653   vat_json_init_object (node);
12654   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12655   vat_json_object_add_string_copy (node, "interface_name",
12656                                    mp->interface_name);
12657   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12658                             ntohl (mp->virtio_net_hdr_sz));
12659   vat_json_object_add_uint (node, "features_first_32",
12660                             clib_net_to_host_u32 (mp->features_first_32));
12661   vat_json_object_add_uint (node, "features_last_32",
12662                             clib_net_to_host_u32 (mp->features_last_32));
12663   vat_json_object_add_uint (node, "is_server", mp->is_server);
12664   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12665   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12666   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12667 }
12668
12669 static int
12670 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12671 {
12672   vl_api_sw_interface_vhost_user_dump_t *mp;
12673   vl_api_control_ping_t *mp_ping;
12674   int ret;
12675   print (vam->ofp,
12676          "Interface name            idx hdr_sz features server regions filename");
12677
12678   /* Get list of vhost-user interfaces */
12679   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12680   mp->sw_if_index = ntohl (~0);
12681   S (mp);
12682
12683   /* Use a control ping for synchronization */
12684   MPING (CONTROL_PING, mp_ping);
12685   S (mp_ping);
12686
12687   W (ret);
12688   return ret;
12689 }
12690
12691 static int
12692 api_show_version (vat_main_t * vam)
12693 {
12694   vl_api_show_version_t *mp;
12695   int ret;
12696
12697   M (SHOW_VERSION, mp);
12698
12699   S (mp);
12700   W (ret);
12701   return ret;
12702 }
12703
12704
12705 static int
12706 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12707 {
12708   unformat_input_t *line_input = vam->input;
12709   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12710   ip46_address_t local, remote;
12711   u8 is_add = 1;
12712   u8 local_set = 0;
12713   u8 remote_set = 0;
12714   u8 grp_set = 0;
12715   u32 mcast_sw_if_index = ~0;
12716   u32 encap_vrf_id = 0;
12717   u32 decap_vrf_id = 0;
12718   u8 protocol = ~0;
12719   u32 vni;
12720   u8 vni_set = 0;
12721   int ret;
12722
12723   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12724     {
12725       if (unformat (line_input, "del"))
12726         is_add = 0;
12727       else if (unformat (line_input, "local %U",
12728                          unformat_ip46_address, &local))
12729         {
12730           local_set = 1;
12731         }
12732       else if (unformat (line_input, "remote %U",
12733                          unformat_ip46_address, &remote))
12734         {
12735           remote_set = 1;
12736         }
12737       else if (unformat (line_input, "group %U %U",
12738                          unformat_ip46_address, &remote,
12739                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12740         {
12741           grp_set = remote_set = 1;
12742         }
12743       else if (unformat (line_input, "group %U",
12744                          unformat_ip46_address, &remote))
12745         {
12746           grp_set = remote_set = 1;
12747         }
12748       else
12749         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12750         ;
12751       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12752         ;
12753       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12754         ;
12755       else if (unformat (line_input, "vni %d", &vni))
12756         vni_set = 1;
12757       else if (unformat (line_input, "next-ip4"))
12758         protocol = 1;
12759       else if (unformat (line_input, "next-ip6"))
12760         protocol = 2;
12761       else if (unformat (line_input, "next-ethernet"))
12762         protocol = 3;
12763       else if (unformat (line_input, "next-nsh"))
12764         protocol = 4;
12765       else
12766         {
12767           errmsg ("parse error '%U'", format_unformat_error, line_input);
12768           return -99;
12769         }
12770     }
12771
12772   if (local_set == 0)
12773     {
12774       errmsg ("tunnel local address not specified");
12775       return -99;
12776     }
12777   if (remote_set == 0)
12778     {
12779       errmsg ("tunnel remote address not specified");
12780       return -99;
12781     }
12782   if (grp_set && mcast_sw_if_index == ~0)
12783     {
12784       errmsg ("tunnel nonexistent multicast device");
12785       return -99;
12786     }
12787   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12788     {
12789       errmsg ("both IPv4 and IPv6 addresses specified");
12790       return -99;
12791     }
12792
12793   if (vni_set == 0)
12794     {
12795       errmsg ("vni not specified");
12796       return -99;
12797     }
12798
12799   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12800
12801   ip_address_encode (&local,
12802                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12803                      IP46_TYPE_IP6, &mp->local);
12804   ip_address_encode (&remote,
12805                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12806                      IP46_TYPE_IP6, &mp->remote);
12807
12808   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12809   mp->encap_vrf_id = ntohl (encap_vrf_id);
12810   mp->decap_vrf_id = ntohl (decap_vrf_id);
12811   mp->protocol = protocol;
12812   mp->vni = ntohl (vni);
12813   mp->is_add = is_add;
12814
12815   S (mp);
12816   W (ret);
12817   return ret;
12818 }
12819
12820 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12821   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12822 {
12823   vat_main_t *vam = &vat_main;
12824   ip46_address_t local, remote;
12825
12826   ip_address_decode (&mp->local, &local);
12827   ip_address_decode (&mp->remote, &remote);
12828
12829   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12830          ntohl (mp->sw_if_index),
12831          format_ip46_address, &local, IP46_TYPE_ANY,
12832          format_ip46_address, &remote, IP46_TYPE_ANY,
12833          ntohl (mp->vni), mp->protocol,
12834          ntohl (mp->mcast_sw_if_index),
12835          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12836 }
12837
12838
12839 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12840   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12841 {
12842   vat_main_t *vam = &vat_main;
12843   vat_json_node_t *node = NULL;
12844   struct in_addr ip4;
12845   struct in6_addr ip6;
12846   ip46_address_t local, remote;
12847
12848   ip_address_decode (&mp->local, &local);
12849   ip_address_decode (&mp->remote, &remote);
12850
12851   if (VAT_JSON_ARRAY != vam->json_tree.type)
12852     {
12853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12854       vat_json_init_array (&vam->json_tree);
12855     }
12856   node = vat_json_array_add (&vam->json_tree);
12857
12858   vat_json_init_object (node);
12859   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12860   if (ip46_address_is_ip4 (&local))
12861     {
12862       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12863       vat_json_object_add_ip4 (node, "local", ip4);
12864       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12865       vat_json_object_add_ip4 (node, "remote", ip4);
12866     }
12867   else
12868     {
12869       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12870       vat_json_object_add_ip6 (node, "local", ip6);
12871       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12872       vat_json_object_add_ip6 (node, "remote", ip6);
12873     }
12874   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12875   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12876   vat_json_object_add_uint (node, "mcast_sw_if_index",
12877                             ntohl (mp->mcast_sw_if_index));
12878   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12879   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12880   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12881 }
12882
12883 static int
12884 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12885 {
12886   unformat_input_t *i = vam->input;
12887   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12888   vl_api_control_ping_t *mp_ping;
12889   u32 sw_if_index;
12890   u8 sw_if_index_set = 0;
12891   int ret;
12892
12893   /* Parse args required to build the message */
12894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (i, "sw_if_index %d", &sw_if_index))
12897         sw_if_index_set = 1;
12898       else
12899         break;
12900     }
12901
12902   if (sw_if_index_set == 0)
12903     {
12904       sw_if_index = ~0;
12905     }
12906
12907   if (!vam->json_output)
12908     {
12909       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12910              "sw_if_index", "local", "remote", "vni",
12911              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12912     }
12913
12914   /* Get list of vxlan-tunnel interfaces */
12915   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12916
12917   mp->sw_if_index = htonl (sw_if_index);
12918
12919   S (mp);
12920
12921   /* Use a control ping for synchronization */
12922   MPING (CONTROL_PING, mp_ping);
12923   S (mp_ping);
12924
12925   W (ret);
12926   return ret;
12927 }
12928
12929 static void vl_api_l2_fib_table_details_t_handler
12930   (vl_api_l2_fib_table_details_t * mp)
12931 {
12932   vat_main_t *vam = &vat_main;
12933
12934   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12935          "       %d       %d     %d",
12936          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12937          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12938          mp->bvi_mac);
12939 }
12940
12941 static void vl_api_l2_fib_table_details_t_handler_json
12942   (vl_api_l2_fib_table_details_t * mp)
12943 {
12944   vat_main_t *vam = &vat_main;
12945   vat_json_node_t *node = NULL;
12946
12947   if (VAT_JSON_ARRAY != vam->json_tree.type)
12948     {
12949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12950       vat_json_init_array (&vam->json_tree);
12951     }
12952   node = vat_json_array_add (&vam->json_tree);
12953
12954   vat_json_init_object (node);
12955   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12956   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12957   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12958   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12959   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12960   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12961 }
12962
12963 static int
12964 api_l2_fib_table_dump (vat_main_t * vam)
12965 {
12966   unformat_input_t *i = vam->input;
12967   vl_api_l2_fib_table_dump_t *mp;
12968   vl_api_control_ping_t *mp_ping;
12969   u32 bd_id;
12970   u8 bd_id_set = 0;
12971   int ret;
12972
12973   /* Parse args required to build the message */
12974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12975     {
12976       if (unformat (i, "bd_id %d", &bd_id))
12977         bd_id_set = 1;
12978       else
12979         break;
12980     }
12981
12982   if (bd_id_set == 0)
12983     {
12984       errmsg ("missing bridge domain");
12985       return -99;
12986     }
12987
12988   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12989
12990   /* Get list of l2 fib entries */
12991   M (L2_FIB_TABLE_DUMP, mp);
12992
12993   mp->bd_id = ntohl (bd_id);
12994   S (mp);
12995
12996   /* Use a control ping for synchronization */
12997   MPING (CONTROL_PING, mp_ping);
12998   S (mp_ping);
12999
13000   W (ret);
13001   return ret;
13002 }
13003
13004
13005 static int
13006 api_interface_name_renumber (vat_main_t * vam)
13007 {
13008   unformat_input_t *line_input = vam->input;
13009   vl_api_interface_name_renumber_t *mp;
13010   u32 sw_if_index = ~0;
13011   u32 new_show_dev_instance = ~0;
13012   int ret;
13013
13014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13015     {
13016       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13017                     &sw_if_index))
13018         ;
13019       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13020         ;
13021       else if (unformat (line_input, "new_show_dev_instance %d",
13022                          &new_show_dev_instance))
13023         ;
13024       else
13025         break;
13026     }
13027
13028   if (sw_if_index == ~0)
13029     {
13030       errmsg ("missing interface name or sw_if_index");
13031       return -99;
13032     }
13033
13034   if (new_show_dev_instance == ~0)
13035     {
13036       errmsg ("missing new_show_dev_instance");
13037       return -99;
13038     }
13039
13040   M (INTERFACE_NAME_RENUMBER, mp);
13041
13042   mp->sw_if_index = ntohl (sw_if_index);
13043   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13044
13045   S (mp);
13046   W (ret);
13047   return ret;
13048 }
13049
13050 static int
13051 api_want_l2_macs_events (vat_main_t * vam)
13052 {
13053   unformat_input_t *line_input = vam->input;
13054   vl_api_want_l2_macs_events_t *mp;
13055   u8 enable_disable = 1;
13056   u32 scan_delay = 0;
13057   u32 max_macs_in_event = 0;
13058   u32 learn_limit = 0;
13059   int ret;
13060
13061   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13062     {
13063       if (unformat (line_input, "learn-limit %d", &learn_limit))
13064         ;
13065       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13066         ;
13067       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13068         ;
13069       else if (unformat (line_input, "disable"))
13070         enable_disable = 0;
13071       else
13072         break;
13073     }
13074
13075   M (WANT_L2_MACS_EVENTS, mp);
13076   mp->enable_disable = enable_disable;
13077   mp->pid = htonl (getpid ());
13078   mp->learn_limit = htonl (learn_limit);
13079   mp->scan_delay = (u8) scan_delay;
13080   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13081   S (mp);
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static int
13087 api_input_acl_set_interface (vat_main_t * vam)
13088 {
13089   unformat_input_t *i = vam->input;
13090   vl_api_input_acl_set_interface_t *mp;
13091   u32 sw_if_index;
13092   int sw_if_index_set;
13093   u32 ip4_table_index = ~0;
13094   u32 ip6_table_index = ~0;
13095   u32 l2_table_index = ~0;
13096   u8 is_add = 1;
13097   int ret;
13098
13099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13100     {
13101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13102         sw_if_index_set = 1;
13103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13104         sw_if_index_set = 1;
13105       else if (unformat (i, "del"))
13106         is_add = 0;
13107       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13108         ;
13109       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13110         ;
13111       else if (unformat (i, "l2-table %d", &l2_table_index))
13112         ;
13113       else
13114         {
13115           clib_warning ("parse error '%U'", format_unformat_error, i);
13116           return -99;
13117         }
13118     }
13119
13120   if (sw_if_index_set == 0)
13121     {
13122       errmsg ("missing interface name or sw_if_index");
13123       return -99;
13124     }
13125
13126   M (INPUT_ACL_SET_INTERFACE, mp);
13127
13128   mp->sw_if_index = ntohl (sw_if_index);
13129   mp->ip4_table_index = ntohl (ip4_table_index);
13130   mp->ip6_table_index = ntohl (ip6_table_index);
13131   mp->l2_table_index = ntohl (l2_table_index);
13132   mp->is_add = is_add;
13133
13134   S (mp);
13135   W (ret);
13136   return ret;
13137 }
13138
13139 static int
13140 api_output_acl_set_interface (vat_main_t * vam)
13141 {
13142   unformat_input_t *i = vam->input;
13143   vl_api_output_acl_set_interface_t *mp;
13144   u32 sw_if_index;
13145   int sw_if_index_set;
13146   u32 ip4_table_index = ~0;
13147   u32 ip6_table_index = ~0;
13148   u32 l2_table_index = ~0;
13149   u8 is_add = 1;
13150   int ret;
13151
13152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13153     {
13154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13155         sw_if_index_set = 1;
13156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13157         sw_if_index_set = 1;
13158       else if (unformat (i, "del"))
13159         is_add = 0;
13160       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13161         ;
13162       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13163         ;
13164       else if (unformat (i, "l2-table %d", &l2_table_index))
13165         ;
13166       else
13167         {
13168           clib_warning ("parse error '%U'", format_unformat_error, i);
13169           return -99;
13170         }
13171     }
13172
13173   if (sw_if_index_set == 0)
13174     {
13175       errmsg ("missing interface name or sw_if_index");
13176       return -99;
13177     }
13178
13179   M (OUTPUT_ACL_SET_INTERFACE, mp);
13180
13181   mp->sw_if_index = ntohl (sw_if_index);
13182   mp->ip4_table_index = ntohl (ip4_table_index);
13183   mp->ip6_table_index = ntohl (ip6_table_index);
13184   mp->l2_table_index = ntohl (l2_table_index);
13185   mp->is_add = is_add;
13186
13187   S (mp);
13188   W (ret);
13189   return ret;
13190 }
13191
13192 static int
13193 api_ip_address_dump (vat_main_t * vam)
13194 {
13195   unformat_input_t *i = vam->input;
13196   vl_api_ip_address_dump_t *mp;
13197   vl_api_control_ping_t *mp_ping;
13198   u32 sw_if_index = ~0;
13199   u8 sw_if_index_set = 0;
13200   u8 ipv4_set = 0;
13201   u8 ipv6_set = 0;
13202   int ret;
13203
13204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13205     {
13206       if (unformat (i, "sw_if_index %d", &sw_if_index))
13207         sw_if_index_set = 1;
13208       else
13209         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13210         sw_if_index_set = 1;
13211       else if (unformat (i, "ipv4"))
13212         ipv4_set = 1;
13213       else if (unformat (i, "ipv6"))
13214         ipv6_set = 1;
13215       else
13216         break;
13217     }
13218
13219   if (ipv4_set && ipv6_set)
13220     {
13221       errmsg ("ipv4 and ipv6 flags cannot be both set");
13222       return -99;
13223     }
13224
13225   if ((!ipv4_set) && (!ipv6_set))
13226     {
13227       errmsg ("no ipv4 nor ipv6 flag set");
13228       return -99;
13229     }
13230
13231   if (sw_if_index_set == 0)
13232     {
13233       errmsg ("missing interface name or sw_if_index");
13234       return -99;
13235     }
13236
13237   vam->current_sw_if_index = sw_if_index;
13238   vam->is_ipv6 = ipv6_set;
13239
13240   M (IP_ADDRESS_DUMP, mp);
13241   mp->sw_if_index = ntohl (sw_if_index);
13242   mp->is_ipv6 = ipv6_set;
13243   S (mp);
13244
13245   /* Use a control ping for synchronization */
13246   MPING (CONTROL_PING, mp_ping);
13247   S (mp_ping);
13248
13249   W (ret);
13250   return ret;
13251 }
13252
13253 static int
13254 api_ip_dump (vat_main_t * vam)
13255 {
13256   vl_api_ip_dump_t *mp;
13257   vl_api_control_ping_t *mp_ping;
13258   unformat_input_t *in = vam->input;
13259   int ipv4_set = 0;
13260   int ipv6_set = 0;
13261   int is_ipv6;
13262   int i;
13263   int ret;
13264
13265   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13266     {
13267       if (unformat (in, "ipv4"))
13268         ipv4_set = 1;
13269       else if (unformat (in, "ipv6"))
13270         ipv6_set = 1;
13271       else
13272         break;
13273     }
13274
13275   if (ipv4_set && ipv6_set)
13276     {
13277       errmsg ("ipv4 and ipv6 flags cannot be both set");
13278       return -99;
13279     }
13280
13281   if ((!ipv4_set) && (!ipv6_set))
13282     {
13283       errmsg ("no ipv4 nor ipv6 flag set");
13284       return -99;
13285     }
13286
13287   is_ipv6 = ipv6_set;
13288   vam->is_ipv6 = is_ipv6;
13289
13290   /* free old data */
13291   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13292     {
13293       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13294     }
13295   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13296
13297   M (IP_DUMP, mp);
13298   mp->is_ipv6 = ipv6_set;
13299   S (mp);
13300
13301   /* Use a control ping for synchronization */
13302   MPING (CONTROL_PING, mp_ping);
13303   S (mp_ping);
13304
13305   W (ret);
13306   return ret;
13307 }
13308
13309 static int
13310 api_ipsec_spd_add_del (vat_main_t * vam)
13311 {
13312   unformat_input_t *i = vam->input;
13313   vl_api_ipsec_spd_add_del_t *mp;
13314   u32 spd_id = ~0;
13315   u8 is_add = 1;
13316   int ret;
13317
13318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13319     {
13320       if (unformat (i, "spd_id %d", &spd_id))
13321         ;
13322       else if (unformat (i, "del"))
13323         is_add = 0;
13324       else
13325         {
13326           clib_warning ("parse error '%U'", format_unformat_error, i);
13327           return -99;
13328         }
13329     }
13330   if (spd_id == ~0)
13331     {
13332       errmsg ("spd_id must be set");
13333       return -99;
13334     }
13335
13336   M (IPSEC_SPD_ADD_DEL, mp);
13337
13338   mp->spd_id = ntohl (spd_id);
13339   mp->is_add = is_add;
13340
13341   S (mp);
13342   W (ret);
13343   return ret;
13344 }
13345
13346 static int
13347 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13348 {
13349   unformat_input_t *i = vam->input;
13350   vl_api_ipsec_interface_add_del_spd_t *mp;
13351   u32 sw_if_index;
13352   u8 sw_if_index_set = 0;
13353   u32 spd_id = (u32) ~ 0;
13354   u8 is_add = 1;
13355   int ret;
13356
13357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13358     {
13359       if (unformat (i, "del"))
13360         is_add = 0;
13361       else if (unformat (i, "spd_id %d", &spd_id))
13362         ;
13363       else
13364         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13365         sw_if_index_set = 1;
13366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13367         sw_if_index_set = 1;
13368       else
13369         {
13370           clib_warning ("parse error '%U'", format_unformat_error, i);
13371           return -99;
13372         }
13373
13374     }
13375
13376   if (spd_id == (u32) ~ 0)
13377     {
13378       errmsg ("spd_id must be set");
13379       return -99;
13380     }
13381
13382   if (sw_if_index_set == 0)
13383     {
13384       errmsg ("missing interface name or sw_if_index");
13385       return -99;
13386     }
13387
13388   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13389
13390   mp->spd_id = ntohl (spd_id);
13391   mp->sw_if_index = ntohl (sw_if_index);
13392   mp->is_add = is_add;
13393
13394   S (mp);
13395   W (ret);
13396   return ret;
13397 }
13398
13399 static int
13400 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13401 {
13402   unformat_input_t *i = vam->input;
13403   vl_api_ipsec_spd_entry_add_del_t *mp;
13404   u8 is_add = 1, is_outbound = 0;
13405   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13406   i32 priority = 0;
13407   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13408   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13409   vl_api_address_t laddr_start = { }, laddr_stop =
13410   {
13411   }, raddr_start =
13412   {
13413   }, raddr_stop =
13414   {
13415   };
13416   int ret;
13417
13418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13419     {
13420       if (unformat (i, "del"))
13421         is_add = 0;
13422       if (unformat (i, "outbound"))
13423         is_outbound = 1;
13424       if (unformat (i, "inbound"))
13425         is_outbound = 0;
13426       else if (unformat (i, "spd_id %d", &spd_id))
13427         ;
13428       else if (unformat (i, "sa_id %d", &sa_id))
13429         ;
13430       else if (unformat (i, "priority %d", &priority))
13431         ;
13432       else if (unformat (i, "protocol %d", &protocol))
13433         ;
13434       else if (unformat (i, "lport_start %d", &lport_start))
13435         ;
13436       else if (unformat (i, "lport_stop %d", &lport_stop))
13437         ;
13438       else if (unformat (i, "rport_start %d", &rport_start))
13439         ;
13440       else if (unformat (i, "rport_stop %d", &rport_stop))
13441         ;
13442       else if (unformat (i, "laddr_start %U",
13443                          unformat_vl_api_address, &laddr_start))
13444         ;
13445       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13446                          &laddr_stop))
13447         ;
13448       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13449                          &raddr_start))
13450         ;
13451       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13452                          &raddr_stop))
13453         ;
13454       else
13455         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13456         {
13457           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13458             {
13459               clib_warning ("unsupported action: 'resolve'");
13460               return -99;
13461             }
13462         }
13463       else
13464         {
13465           clib_warning ("parse error '%U'", format_unformat_error, i);
13466           return -99;
13467         }
13468
13469     }
13470
13471   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13472
13473   mp->is_add = is_add;
13474
13475   mp->entry.spd_id = ntohl (spd_id);
13476   mp->entry.priority = ntohl (priority);
13477   mp->entry.is_outbound = is_outbound;
13478
13479   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13480                sizeof (vl_api_address_t));
13481   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13482                sizeof (vl_api_address_t));
13483   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13484                sizeof (vl_api_address_t));
13485   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13486                sizeof (vl_api_address_t));
13487
13488   mp->entry.protocol = (u8) protocol;
13489   mp->entry.local_port_start = ntohs ((u16) lport_start);
13490   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13491   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13492   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13493   mp->entry.policy = (u8) policy;
13494   mp->entry.sa_id = ntohl (sa_id);
13495
13496   S (mp);
13497   W (ret);
13498   return ret;
13499 }
13500
13501 static int
13502 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13503 {
13504   unformat_input_t *i = vam->input;
13505   vl_api_ipsec_sad_entry_add_del_t *mp;
13506   u32 sad_id = 0, spi = 0;
13507   u8 *ck = 0, *ik = 0;
13508   u8 is_add = 1;
13509
13510   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13511   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13512   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13513   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13514   vl_api_address_t tun_src, tun_dst;
13515   int ret;
13516
13517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13518     {
13519       if (unformat (i, "del"))
13520         is_add = 0;
13521       else if (unformat (i, "sad_id %d", &sad_id))
13522         ;
13523       else if (unformat (i, "spi %d", &spi))
13524         ;
13525       else if (unformat (i, "esp"))
13526         protocol = IPSEC_API_PROTO_ESP;
13527       else
13528         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13529         {
13530           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13531           if (ADDRESS_IP6 == tun_src.af)
13532             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13533         }
13534       else
13535         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13536         {
13537           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13538           if (ADDRESS_IP6 == tun_src.af)
13539             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13540         }
13541       else
13542         if (unformat (i, "crypto_alg %U",
13543                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13544         ;
13545       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13546         ;
13547       else if (unformat (i, "integ_alg %U",
13548                          unformat_ipsec_api_integ_alg, &integ_alg))
13549         ;
13550       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13551         ;
13552       else
13553         {
13554           clib_warning ("parse error '%U'", format_unformat_error, i);
13555           return -99;
13556         }
13557
13558     }
13559
13560   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13561
13562   mp->is_add = is_add;
13563   mp->entry.sad_id = ntohl (sad_id);
13564   mp->entry.protocol = protocol;
13565   mp->entry.spi = ntohl (spi);
13566   mp->entry.flags = flags;
13567
13568   mp->entry.crypto_algorithm = crypto_alg;
13569   mp->entry.integrity_algorithm = integ_alg;
13570   mp->entry.crypto_key.length = vec_len (ck);
13571   mp->entry.integrity_key.length = vec_len (ik);
13572
13573   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13574     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13575
13576   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13577     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13578
13579   if (ck)
13580     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13581   if (ik)
13582     clib_memcpy (mp->entry.integrity_key.data, ik,
13583                  mp->entry.integrity_key.length);
13584
13585   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13586     {
13587       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13588                    sizeof (mp->entry.tunnel_src));
13589       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13590                    sizeof (mp->entry.tunnel_dst));
13591     }
13592
13593   S (mp);
13594   W (ret);
13595   return ret;
13596 }
13597
13598 static int
13599 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13600 {
13601   unformat_input_t *i = vam->input;
13602   vl_api_ipsec_tunnel_if_add_del_t *mp;
13603   u32 local_spi = 0, remote_spi = 0;
13604   u32 crypto_alg = 0, integ_alg = 0;
13605   u8 *lck = NULL, *rck = NULL;
13606   u8 *lik = NULL, *rik = NULL;
13607   vl_api_address_t local_ip = { 0 };
13608   vl_api_address_t remote_ip = { 0 };
13609   f64 before = 0;
13610   u8 is_add = 1;
13611   u8 esn = 0;
13612   u8 anti_replay = 0;
13613   u8 renumber = 0;
13614   u32 instance = ~0;
13615   u32 count = 1, jj;
13616   int ret = -1;
13617
13618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13619     {
13620       if (unformat (i, "del"))
13621         is_add = 0;
13622       else if (unformat (i, "esn"))
13623         esn = 1;
13624       else if (unformat (i, "anti-replay"))
13625         anti_replay = 1;
13626       else if (unformat (i, "count %d", &count))
13627         ;
13628       else if (unformat (i, "local_spi %d", &local_spi))
13629         ;
13630       else if (unformat (i, "remote_spi %d", &remote_spi))
13631         ;
13632       else
13633         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13634         ;
13635       else
13636         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13637         ;
13638       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13639         ;
13640       else
13641         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13642         ;
13643       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13644         ;
13645       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13646         ;
13647       else
13648         if (unformat
13649             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13650         {
13651           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13652             {
13653               errmsg ("unsupported crypto-alg: '%U'\n",
13654                       format_ipsec_crypto_alg, crypto_alg);
13655               return -99;
13656             }
13657         }
13658       else
13659         if (unformat
13660             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13661         {
13662           if (integ_alg >= IPSEC_INTEG_N_ALG)
13663             {
13664               errmsg ("unsupported integ-alg: '%U'\n",
13665                       format_ipsec_integ_alg, integ_alg);
13666               return -99;
13667             }
13668         }
13669       else if (unformat (i, "instance %u", &instance))
13670         renumber = 1;
13671       else
13672         {
13673           errmsg ("parse error '%U'\n", format_unformat_error, i);
13674           return -99;
13675         }
13676     }
13677
13678   if (count > 1)
13679     {
13680       /* Turn on async mode */
13681       vam->async_mode = 1;
13682       vam->async_errors = 0;
13683       before = vat_time_now (vam);
13684     }
13685
13686   for (jj = 0; jj < count; jj++)
13687     {
13688       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13689
13690       mp->is_add = is_add;
13691       mp->esn = esn;
13692       mp->anti_replay = anti_replay;
13693
13694       if (jj > 0)
13695         increment_address (&remote_ip);
13696
13697       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13698       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13699
13700       mp->local_spi = htonl (local_spi + jj);
13701       mp->remote_spi = htonl (remote_spi + jj);
13702       mp->crypto_alg = (u8) crypto_alg;
13703
13704       mp->local_crypto_key_len = 0;
13705       if (lck)
13706         {
13707           mp->local_crypto_key_len = vec_len (lck);
13708           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13709             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13710           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13711         }
13712
13713       mp->remote_crypto_key_len = 0;
13714       if (rck)
13715         {
13716           mp->remote_crypto_key_len = vec_len (rck);
13717           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13718             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13719           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13720         }
13721
13722       mp->integ_alg = (u8) integ_alg;
13723
13724       mp->local_integ_key_len = 0;
13725       if (lik)
13726         {
13727           mp->local_integ_key_len = vec_len (lik);
13728           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13729             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13730           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13731         }
13732
13733       mp->remote_integ_key_len = 0;
13734       if (rik)
13735         {
13736           mp->remote_integ_key_len = vec_len (rik);
13737           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13738             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13739           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13740         }
13741
13742       if (renumber)
13743         {
13744           mp->renumber = renumber;
13745           mp->show_instance = ntohl (instance);
13746         }
13747       S (mp);
13748     }
13749
13750   /* When testing multiple add/del ops, use a control-ping to sync */
13751   if (count > 1)
13752     {
13753       vl_api_control_ping_t *mp_ping;
13754       f64 after;
13755       f64 timeout;
13756
13757       /* Shut off async mode */
13758       vam->async_mode = 0;
13759
13760       MPING (CONTROL_PING, mp_ping);
13761       S (mp_ping);
13762
13763       timeout = vat_time_now (vam) + 1.0;
13764       while (vat_time_now (vam) < timeout)
13765         if (vam->result_ready == 1)
13766           goto out;
13767       vam->retval = -99;
13768
13769     out:
13770       if (vam->retval == -99)
13771         errmsg ("timeout");
13772
13773       if (vam->async_errors > 0)
13774         {
13775           errmsg ("%d asynchronous errors", vam->async_errors);
13776           vam->retval = -98;
13777         }
13778       vam->async_errors = 0;
13779       after = vat_time_now (vam);
13780
13781       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13782       if (jj > 0)
13783         count = jj;
13784
13785       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13786              count, after - before, count / (after - before));
13787     }
13788   else
13789     {
13790       /* Wait for a reply... */
13791       W (ret);
13792       return ret;
13793     }
13794
13795   return ret;
13796 }
13797
13798 static void
13799 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13800 {
13801   vat_main_t *vam = &vat_main;
13802
13803   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13804          "crypto_key %U integ_alg %u integ_key %U flags %x "
13805          "tunnel_src_addr %U tunnel_dst_addr %U "
13806          "salt %u seq_outbound %lu last_seq_inbound %lu "
13807          "replay_window %lu\n",
13808          ntohl (mp->entry.sad_id),
13809          ntohl (mp->sw_if_index),
13810          ntohl (mp->entry.spi),
13811          ntohl (mp->entry.protocol),
13812          ntohl (mp->entry.crypto_algorithm),
13813          format_hex_bytes, mp->entry.crypto_key.data,
13814          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13815          format_hex_bytes, mp->entry.integrity_key.data,
13816          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13817          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13818          &mp->entry.tunnel_dst, ntohl (mp->salt),
13819          clib_net_to_host_u64 (mp->seq_outbound),
13820          clib_net_to_host_u64 (mp->last_seq_inbound),
13821          clib_net_to_host_u64 (mp->replay_window));
13822 }
13823
13824 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13825 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13826
13827 static void vl_api_ipsec_sa_details_t_handler_json
13828   (vl_api_ipsec_sa_details_t * mp)
13829 {
13830   vat_main_t *vam = &vat_main;
13831   vat_json_node_t *node = NULL;
13832   vl_api_ipsec_sad_flags_t flags;
13833
13834   if (VAT_JSON_ARRAY != vam->json_tree.type)
13835     {
13836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13837       vat_json_init_array (&vam->json_tree);
13838     }
13839   node = vat_json_array_add (&vam->json_tree);
13840
13841   vat_json_init_object (node);
13842   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13843   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13844   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13845   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13846   vat_json_object_add_uint (node, "crypto_alg",
13847                             ntohl (mp->entry.crypto_algorithm));
13848   vat_json_object_add_uint (node, "integ_alg",
13849                             ntohl (mp->entry.integrity_algorithm));
13850   flags = ntohl (mp->entry.flags);
13851   vat_json_object_add_uint (node, "use_esn",
13852                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13853   vat_json_object_add_uint (node, "use_anti_replay",
13854                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13855   vat_json_object_add_uint (node, "is_tunnel",
13856                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13857   vat_json_object_add_uint (node, "is_tunnel_ip6",
13858                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13859   vat_json_object_add_uint (node, "udp_encap",
13860                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13861   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13862                              mp->entry.crypto_key.length);
13863   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13864                              mp->entry.integrity_key.length);
13865   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13866   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13867   vat_json_object_add_uint (node, "replay_window",
13868                             clib_net_to_host_u64 (mp->replay_window));
13869 }
13870
13871 static int
13872 api_ipsec_sa_dump (vat_main_t * vam)
13873 {
13874   unformat_input_t *i = vam->input;
13875   vl_api_ipsec_sa_dump_t *mp;
13876   vl_api_control_ping_t *mp_ping;
13877   u32 sa_id = ~0;
13878   int ret;
13879
13880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (i, "sa_id %d", &sa_id))
13883         ;
13884       else
13885         {
13886           clib_warning ("parse error '%U'", format_unformat_error, i);
13887           return -99;
13888         }
13889     }
13890
13891   M (IPSEC_SA_DUMP, mp);
13892
13893   mp->sa_id = ntohl (sa_id);
13894
13895   S (mp);
13896
13897   /* Use a control ping for synchronization */
13898   M (CONTROL_PING, mp_ping);
13899   S (mp_ping);
13900
13901   W (ret);
13902   return ret;
13903 }
13904
13905 static int
13906 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13907 {
13908   unformat_input_t *i = vam->input;
13909   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13910   u32 sw_if_index = ~0;
13911   u32 sa_id = ~0;
13912   u8 is_outbound = (u8) ~ 0;
13913   int ret;
13914
13915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13918         ;
13919       else if (unformat (i, "sa_id %d", &sa_id))
13920         ;
13921       else if (unformat (i, "outbound"))
13922         is_outbound = 1;
13923       else if (unformat (i, "inbound"))
13924         is_outbound = 0;
13925       else
13926         {
13927           clib_warning ("parse error '%U'", format_unformat_error, i);
13928           return -99;
13929         }
13930     }
13931
13932   if (sw_if_index == ~0)
13933     {
13934       errmsg ("interface must be specified");
13935       return -99;
13936     }
13937
13938   if (sa_id == ~0)
13939     {
13940       errmsg ("SA ID must be specified");
13941       return -99;
13942     }
13943
13944   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13945
13946   mp->sw_if_index = htonl (sw_if_index);
13947   mp->sa_id = htonl (sa_id);
13948   mp->is_outbound = is_outbound;
13949
13950   S (mp);
13951   W (ret);
13952
13953   return ret;
13954 }
13955
13956 static int
13957 api_get_first_msg_id (vat_main_t * vam)
13958 {
13959   vl_api_get_first_msg_id_t *mp;
13960   unformat_input_t *i = vam->input;
13961   u8 *name;
13962   u8 name_set = 0;
13963   int ret;
13964
13965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (i, "client %s", &name))
13968         name_set = 1;
13969       else
13970         break;
13971     }
13972
13973   if (name_set == 0)
13974     {
13975       errmsg ("missing client name");
13976       return -99;
13977     }
13978   vec_add1 (name, 0);
13979
13980   if (vec_len (name) > 63)
13981     {
13982       errmsg ("client name too long");
13983       return -99;
13984     }
13985
13986   M (GET_FIRST_MSG_ID, mp);
13987   clib_memcpy (mp->name, name, vec_len (name));
13988   S (mp);
13989   W (ret);
13990   return ret;
13991 }
13992
13993 static int
13994 api_cop_interface_enable_disable (vat_main_t * vam)
13995 {
13996   unformat_input_t *line_input = vam->input;
13997   vl_api_cop_interface_enable_disable_t *mp;
13998   u32 sw_if_index = ~0;
13999   u8 enable_disable = 1;
14000   int ret;
14001
14002   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (line_input, "disable"))
14005         enable_disable = 0;
14006       if (unformat (line_input, "enable"))
14007         enable_disable = 1;
14008       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14009                          vam, &sw_if_index))
14010         ;
14011       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14012         ;
14013       else
14014         break;
14015     }
14016
14017   if (sw_if_index == ~0)
14018     {
14019       errmsg ("missing interface name or sw_if_index");
14020       return -99;
14021     }
14022
14023   /* Construct the API message */
14024   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14025   mp->sw_if_index = ntohl (sw_if_index);
14026   mp->enable_disable = enable_disable;
14027
14028   /* send it... */
14029   S (mp);
14030   /* Wait for the reply */
14031   W (ret);
14032   return ret;
14033 }
14034
14035 static int
14036 api_cop_whitelist_enable_disable (vat_main_t * vam)
14037 {
14038   unformat_input_t *line_input = vam->input;
14039   vl_api_cop_whitelist_enable_disable_t *mp;
14040   u32 sw_if_index = ~0;
14041   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14042   u32 fib_id = 0;
14043   int ret;
14044
14045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14046     {
14047       if (unformat (line_input, "ip4"))
14048         ip4 = 1;
14049       else if (unformat (line_input, "ip6"))
14050         ip6 = 1;
14051       else if (unformat (line_input, "default"))
14052         default_cop = 1;
14053       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14054                          vam, &sw_if_index))
14055         ;
14056       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14057         ;
14058       else if (unformat (line_input, "fib-id %d", &fib_id))
14059         ;
14060       else
14061         break;
14062     }
14063
14064   if (sw_if_index == ~0)
14065     {
14066       errmsg ("missing interface name or sw_if_index");
14067       return -99;
14068     }
14069
14070   /* Construct the API message */
14071   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14072   mp->sw_if_index = ntohl (sw_if_index);
14073   mp->fib_id = ntohl (fib_id);
14074   mp->ip4 = ip4;
14075   mp->ip6 = ip6;
14076   mp->default_cop = default_cop;
14077
14078   /* send it... */
14079   S (mp);
14080   /* Wait for the reply */
14081   W (ret);
14082   return ret;
14083 }
14084
14085 static int
14086 api_get_node_graph (vat_main_t * vam)
14087 {
14088   vl_api_get_node_graph_t *mp;
14089   int ret;
14090
14091   M (GET_NODE_GRAPH, mp);
14092
14093   /* send it... */
14094   S (mp);
14095   /* Wait for the reply */
14096   W (ret);
14097   return ret;
14098 }
14099
14100 /* *INDENT-OFF* */
14101 /** Used for parsing LISP eids */
14102 typedef CLIB_PACKED(struct{
14103   u8 addr[16];   /**< eid address */
14104   u32 len;       /**< prefix length if IP */
14105   u8 type;      /**< type of eid */
14106 }) lisp_eid_vat_t;
14107 /* *INDENT-ON* */
14108
14109 static uword
14110 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14111 {
14112   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14113
14114   clib_memset (a, 0, sizeof (a[0]));
14115
14116   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14117     {
14118       a->type = 0;              /* ipv4 type */
14119     }
14120   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14121     {
14122       a->type = 1;              /* ipv6 type */
14123     }
14124   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14125     {
14126       a->type = 2;              /* mac type */
14127     }
14128   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14129     {
14130       a->type = 3;              /* NSH type */
14131       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14132       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14133     }
14134   else
14135     {
14136       return 0;
14137     }
14138
14139   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14140     {
14141       return 0;
14142     }
14143
14144   return 1;
14145 }
14146
14147 static int
14148 lisp_eid_size_vat (u8 type)
14149 {
14150   switch (type)
14151     {
14152     case 0:
14153       return 4;
14154     case 1:
14155       return 16;
14156     case 2:
14157       return 6;
14158     case 3:
14159       return 5;
14160     }
14161   return 0;
14162 }
14163
14164 static void
14165 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14166 {
14167   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14168 }
14169
14170 static int
14171 api_one_add_del_locator_set (vat_main_t * vam)
14172 {
14173   unformat_input_t *input = vam->input;
14174   vl_api_one_add_del_locator_set_t *mp;
14175   u8 is_add = 1;
14176   u8 *locator_set_name = NULL;
14177   u8 locator_set_name_set = 0;
14178   vl_api_local_locator_t locator, *locators = 0;
14179   u32 sw_if_index, priority, weight;
14180   u32 data_len = 0;
14181
14182   int ret;
14183   /* Parse args required to build the message */
14184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14185     {
14186       if (unformat (input, "del"))
14187         {
14188           is_add = 0;
14189         }
14190       else if (unformat (input, "locator-set %s", &locator_set_name))
14191         {
14192           locator_set_name_set = 1;
14193         }
14194       else if (unformat (input, "sw_if_index %u p %u w %u",
14195                          &sw_if_index, &priority, &weight))
14196         {
14197           locator.sw_if_index = htonl (sw_if_index);
14198           locator.priority = priority;
14199           locator.weight = weight;
14200           vec_add1 (locators, locator);
14201         }
14202       else
14203         if (unformat
14204             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14205              &sw_if_index, &priority, &weight))
14206         {
14207           locator.sw_if_index = htonl (sw_if_index);
14208           locator.priority = priority;
14209           locator.weight = weight;
14210           vec_add1 (locators, locator);
14211         }
14212       else
14213         break;
14214     }
14215
14216   if (locator_set_name_set == 0)
14217     {
14218       errmsg ("missing locator-set name");
14219       vec_free (locators);
14220       return -99;
14221     }
14222
14223   if (vec_len (locator_set_name) > 64)
14224     {
14225       errmsg ("locator-set name too long");
14226       vec_free (locator_set_name);
14227       vec_free (locators);
14228       return -99;
14229     }
14230   vec_add1 (locator_set_name, 0);
14231
14232   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14233
14234   /* Construct the API message */
14235   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14236
14237   mp->is_add = is_add;
14238   clib_memcpy (mp->locator_set_name, locator_set_name,
14239                vec_len (locator_set_name));
14240   vec_free (locator_set_name);
14241
14242   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14243   if (locators)
14244     clib_memcpy (mp->locators, locators, data_len);
14245   vec_free (locators);
14246
14247   /* send it... */
14248   S (mp);
14249
14250   /* Wait for a reply... */
14251   W (ret);
14252   return ret;
14253 }
14254
14255 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14256
14257 static int
14258 api_one_add_del_locator (vat_main_t * vam)
14259 {
14260   unformat_input_t *input = vam->input;
14261   vl_api_one_add_del_locator_t *mp;
14262   u32 tmp_if_index = ~0;
14263   u32 sw_if_index = ~0;
14264   u8 sw_if_index_set = 0;
14265   u8 sw_if_index_if_name_set = 0;
14266   u32 priority = ~0;
14267   u8 priority_set = 0;
14268   u32 weight = ~0;
14269   u8 weight_set = 0;
14270   u8 is_add = 1;
14271   u8 *locator_set_name = NULL;
14272   u8 locator_set_name_set = 0;
14273   int ret;
14274
14275   /* Parse args required to build the message */
14276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14277     {
14278       if (unformat (input, "del"))
14279         {
14280           is_add = 0;
14281         }
14282       else if (unformat (input, "locator-set %s", &locator_set_name))
14283         {
14284           locator_set_name_set = 1;
14285         }
14286       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14287                          &tmp_if_index))
14288         {
14289           sw_if_index_if_name_set = 1;
14290           sw_if_index = tmp_if_index;
14291         }
14292       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14293         {
14294           sw_if_index_set = 1;
14295           sw_if_index = tmp_if_index;
14296         }
14297       else if (unformat (input, "p %d", &priority))
14298         {
14299           priority_set = 1;
14300         }
14301       else if (unformat (input, "w %d", &weight))
14302         {
14303           weight_set = 1;
14304         }
14305       else
14306         break;
14307     }
14308
14309   if (locator_set_name_set == 0)
14310     {
14311       errmsg ("missing locator-set name");
14312       return -99;
14313     }
14314
14315   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14316     {
14317       errmsg ("missing sw_if_index");
14318       vec_free (locator_set_name);
14319       return -99;
14320     }
14321
14322   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14323     {
14324       errmsg ("cannot use both params interface name and sw_if_index");
14325       vec_free (locator_set_name);
14326       return -99;
14327     }
14328
14329   if (priority_set == 0)
14330     {
14331       errmsg ("missing locator-set priority");
14332       vec_free (locator_set_name);
14333       return -99;
14334     }
14335
14336   if (weight_set == 0)
14337     {
14338       errmsg ("missing locator-set weight");
14339       vec_free (locator_set_name);
14340       return -99;
14341     }
14342
14343   if (vec_len (locator_set_name) > 64)
14344     {
14345       errmsg ("locator-set name too long");
14346       vec_free (locator_set_name);
14347       return -99;
14348     }
14349   vec_add1 (locator_set_name, 0);
14350
14351   /* Construct the API message */
14352   M (ONE_ADD_DEL_LOCATOR, mp);
14353
14354   mp->is_add = is_add;
14355   mp->sw_if_index = ntohl (sw_if_index);
14356   mp->priority = priority;
14357   mp->weight = weight;
14358   clib_memcpy (mp->locator_set_name, locator_set_name,
14359                vec_len (locator_set_name));
14360   vec_free (locator_set_name);
14361
14362   /* send it... */
14363   S (mp);
14364
14365   /* Wait for a reply... */
14366   W (ret);
14367   return ret;
14368 }
14369
14370 #define api_lisp_add_del_locator api_one_add_del_locator
14371
14372 uword
14373 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14374 {
14375   u32 *key_id = va_arg (*args, u32 *);
14376   u8 *s = 0;
14377
14378   if (unformat (input, "%s", &s))
14379     {
14380       if (!strcmp ((char *) s, "sha1"))
14381         key_id[0] = HMAC_SHA_1_96;
14382       else if (!strcmp ((char *) s, "sha256"))
14383         key_id[0] = HMAC_SHA_256_128;
14384       else
14385         {
14386           clib_warning ("invalid key_id: '%s'", s);
14387           key_id[0] = HMAC_NO_KEY;
14388         }
14389     }
14390   else
14391     return 0;
14392
14393   vec_free (s);
14394   return 1;
14395 }
14396
14397 static int
14398 api_one_add_del_local_eid (vat_main_t * vam)
14399 {
14400   unformat_input_t *input = vam->input;
14401   vl_api_one_add_del_local_eid_t *mp;
14402   u8 is_add = 1;
14403   u8 eid_set = 0;
14404   lisp_eid_vat_t _eid, *eid = &_eid;
14405   u8 *locator_set_name = 0;
14406   u8 locator_set_name_set = 0;
14407   u32 vni = 0;
14408   u16 key_id = 0;
14409   u8 *key = 0;
14410   int ret;
14411
14412   /* Parse args required to build the message */
14413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14414     {
14415       if (unformat (input, "del"))
14416         {
14417           is_add = 0;
14418         }
14419       else if (unformat (input, "vni %d", &vni))
14420         {
14421           ;
14422         }
14423       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14424         {
14425           eid_set = 1;
14426         }
14427       else if (unformat (input, "locator-set %s", &locator_set_name))
14428         {
14429           locator_set_name_set = 1;
14430         }
14431       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14432         ;
14433       else if (unformat (input, "secret-key %_%v%_", &key))
14434         ;
14435       else
14436         break;
14437     }
14438
14439   if (locator_set_name_set == 0)
14440     {
14441       errmsg ("missing locator-set name");
14442       return -99;
14443     }
14444
14445   if (0 == eid_set)
14446     {
14447       errmsg ("EID address not set!");
14448       vec_free (locator_set_name);
14449       return -99;
14450     }
14451
14452   if (key && (0 == key_id))
14453     {
14454       errmsg ("invalid key_id!");
14455       return -99;
14456     }
14457
14458   if (vec_len (key) > 64)
14459     {
14460       errmsg ("key too long");
14461       vec_free (key);
14462       return -99;
14463     }
14464
14465   if (vec_len (locator_set_name) > 64)
14466     {
14467       errmsg ("locator-set name too long");
14468       vec_free (locator_set_name);
14469       return -99;
14470     }
14471   vec_add1 (locator_set_name, 0);
14472
14473   /* Construct the API message */
14474   M (ONE_ADD_DEL_LOCAL_EID, mp);
14475
14476   mp->is_add = is_add;
14477   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14478   mp->eid_type = eid->type;
14479   mp->prefix_len = eid->len;
14480   mp->vni = clib_host_to_net_u32 (vni);
14481   mp->key_id = clib_host_to_net_u16 (key_id);
14482   clib_memcpy (mp->locator_set_name, locator_set_name,
14483                vec_len (locator_set_name));
14484   clib_memcpy (mp->key, key, vec_len (key));
14485
14486   vec_free (locator_set_name);
14487   vec_free (key);
14488
14489   /* send it... */
14490   S (mp);
14491
14492   /* Wait for a reply... */
14493   W (ret);
14494   return ret;
14495 }
14496
14497 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14498
14499 static int
14500 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14501 {
14502   u32 dp_table = 0, vni = 0;;
14503   unformat_input_t *input = vam->input;
14504   vl_api_gpe_add_del_fwd_entry_t *mp;
14505   u8 is_add = 1;
14506   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14507   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14508   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14509   u32 action = ~0, w;
14510   ip4_address_t rmt_rloc4, lcl_rloc4;
14511   ip6_address_t rmt_rloc6, lcl_rloc6;
14512   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14513   int ret;
14514
14515   clib_memset (&rloc, 0, sizeof (rloc));
14516
14517   /* Parse args required to build the message */
14518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14519     {
14520       if (unformat (input, "del"))
14521         is_add = 0;
14522       else if (unformat (input, "add"))
14523         is_add = 1;
14524       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14525         {
14526           rmt_eid_set = 1;
14527         }
14528       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14529         {
14530           lcl_eid_set = 1;
14531         }
14532       else if (unformat (input, "vrf %d", &dp_table))
14533         ;
14534       else if (unformat (input, "bd %d", &dp_table))
14535         ;
14536       else if (unformat (input, "vni %d", &vni))
14537         ;
14538       else if (unformat (input, "w %d", &w))
14539         {
14540           if (!curr_rloc)
14541             {
14542               errmsg ("No RLOC configured for setting priority/weight!");
14543               return -99;
14544             }
14545           curr_rloc->weight = w;
14546         }
14547       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14548                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14549         {
14550           rloc.is_ip4 = 1;
14551
14552           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14553           rloc.weight = 0;
14554           vec_add1 (lcl_locs, rloc);
14555
14556           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14557           vec_add1 (rmt_locs, rloc);
14558           /* weight saved in rmt loc */
14559           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14560         }
14561       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14562                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14563         {
14564           rloc.is_ip4 = 0;
14565           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14566           rloc.weight = 0;
14567           vec_add1 (lcl_locs, rloc);
14568
14569           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14570           vec_add1 (rmt_locs, rloc);
14571           /* weight saved in rmt loc */
14572           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14573         }
14574       else if (unformat (input, "action %d", &action))
14575         {
14576           ;
14577         }
14578       else
14579         {
14580           clib_warning ("parse error '%U'", format_unformat_error, input);
14581           return -99;
14582         }
14583     }
14584
14585   if (!rmt_eid_set)
14586     {
14587       errmsg ("remote eid addresses not set");
14588       return -99;
14589     }
14590
14591   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14592     {
14593       errmsg ("eid types don't match");
14594       return -99;
14595     }
14596
14597   if (0 == rmt_locs && (u32) ~ 0 == action)
14598     {
14599       errmsg ("action not set for negative mapping");
14600       return -99;
14601     }
14602
14603   /* Construct the API message */
14604   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14605       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14606
14607   mp->is_add = is_add;
14608   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14609   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14610   mp->eid_type = rmt_eid->type;
14611   mp->dp_table = clib_host_to_net_u32 (dp_table);
14612   mp->vni = clib_host_to_net_u32 (vni);
14613   mp->rmt_len = rmt_eid->len;
14614   mp->lcl_len = lcl_eid->len;
14615   mp->action = action;
14616
14617   if (0 != rmt_locs && 0 != lcl_locs)
14618     {
14619       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14620       clib_memcpy (mp->locs, lcl_locs,
14621                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14622
14623       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14624       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14625                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14626     }
14627   vec_free (lcl_locs);
14628   vec_free (rmt_locs);
14629
14630   /* send it... */
14631   S (mp);
14632
14633   /* Wait for a reply... */
14634   W (ret);
14635   return ret;
14636 }
14637
14638 static int
14639 api_one_add_del_map_server (vat_main_t * vam)
14640 {
14641   unformat_input_t *input = vam->input;
14642   vl_api_one_add_del_map_server_t *mp;
14643   u8 is_add = 1;
14644   u8 ipv4_set = 0;
14645   u8 ipv6_set = 0;
14646   ip4_address_t ipv4;
14647   ip6_address_t ipv6;
14648   int ret;
14649
14650   /* Parse args required to build the message */
14651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (input, "del"))
14654         {
14655           is_add = 0;
14656         }
14657       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14658         {
14659           ipv4_set = 1;
14660         }
14661       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14662         {
14663           ipv6_set = 1;
14664         }
14665       else
14666         break;
14667     }
14668
14669   if (ipv4_set && ipv6_set)
14670     {
14671       errmsg ("both eid v4 and v6 addresses set");
14672       return -99;
14673     }
14674
14675   if (!ipv4_set && !ipv6_set)
14676     {
14677       errmsg ("eid addresses not set");
14678       return -99;
14679     }
14680
14681   /* Construct the API message */
14682   M (ONE_ADD_DEL_MAP_SERVER, mp);
14683
14684   mp->is_add = is_add;
14685   if (ipv6_set)
14686     {
14687       mp->is_ipv6 = 1;
14688       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14689     }
14690   else
14691     {
14692       mp->is_ipv6 = 0;
14693       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14694     }
14695
14696   /* send it... */
14697   S (mp);
14698
14699   /* Wait for a reply... */
14700   W (ret);
14701   return ret;
14702 }
14703
14704 #define api_lisp_add_del_map_server api_one_add_del_map_server
14705
14706 static int
14707 api_one_add_del_map_resolver (vat_main_t * vam)
14708 {
14709   unformat_input_t *input = vam->input;
14710   vl_api_one_add_del_map_resolver_t *mp;
14711   u8 is_add = 1;
14712   u8 ipv4_set = 0;
14713   u8 ipv6_set = 0;
14714   ip4_address_t ipv4;
14715   ip6_address_t ipv6;
14716   int ret;
14717
14718   /* Parse args required to build the message */
14719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (unformat (input, "del"))
14722         {
14723           is_add = 0;
14724         }
14725       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14726         {
14727           ipv4_set = 1;
14728         }
14729       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14730         {
14731           ipv6_set = 1;
14732         }
14733       else
14734         break;
14735     }
14736
14737   if (ipv4_set && ipv6_set)
14738     {
14739       errmsg ("both eid v4 and v6 addresses set");
14740       return -99;
14741     }
14742
14743   if (!ipv4_set && !ipv6_set)
14744     {
14745       errmsg ("eid addresses not set");
14746       return -99;
14747     }
14748
14749   /* Construct the API message */
14750   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14751
14752   mp->is_add = is_add;
14753   if (ipv6_set)
14754     {
14755       mp->is_ipv6 = 1;
14756       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14757     }
14758   else
14759     {
14760       mp->is_ipv6 = 0;
14761       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14762     }
14763
14764   /* send it... */
14765   S (mp);
14766
14767   /* Wait for a reply... */
14768   W (ret);
14769   return ret;
14770 }
14771
14772 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14773
14774 static int
14775 api_lisp_gpe_enable_disable (vat_main_t * vam)
14776 {
14777   unformat_input_t *input = vam->input;
14778   vl_api_gpe_enable_disable_t *mp;
14779   u8 is_set = 0;
14780   u8 is_en = 1;
14781   int ret;
14782
14783   /* Parse args required to build the message */
14784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (input, "enable"))
14787         {
14788           is_set = 1;
14789           is_en = 1;
14790         }
14791       else if (unformat (input, "disable"))
14792         {
14793           is_set = 1;
14794           is_en = 0;
14795         }
14796       else
14797         break;
14798     }
14799
14800   if (is_set == 0)
14801     {
14802       errmsg ("Value not set");
14803       return -99;
14804     }
14805
14806   /* Construct the API message */
14807   M (GPE_ENABLE_DISABLE, mp);
14808
14809   mp->is_en = is_en;
14810
14811   /* send it... */
14812   S (mp);
14813
14814   /* Wait for a reply... */
14815   W (ret);
14816   return ret;
14817 }
14818
14819 static int
14820 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14821 {
14822   unformat_input_t *input = vam->input;
14823   vl_api_one_rloc_probe_enable_disable_t *mp;
14824   u8 is_set = 0;
14825   u8 is_en = 0;
14826   int ret;
14827
14828   /* Parse args required to build the message */
14829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14830     {
14831       if (unformat (input, "enable"))
14832         {
14833           is_set = 1;
14834           is_en = 1;
14835         }
14836       else if (unformat (input, "disable"))
14837         is_set = 1;
14838       else
14839         break;
14840     }
14841
14842   if (!is_set)
14843     {
14844       errmsg ("Value not set");
14845       return -99;
14846     }
14847
14848   /* Construct the API message */
14849   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14850
14851   mp->is_enabled = is_en;
14852
14853   /* send it... */
14854   S (mp);
14855
14856   /* Wait for a reply... */
14857   W (ret);
14858   return ret;
14859 }
14860
14861 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14862
14863 static int
14864 api_one_map_register_enable_disable (vat_main_t * vam)
14865 {
14866   unformat_input_t *input = vam->input;
14867   vl_api_one_map_register_enable_disable_t *mp;
14868   u8 is_set = 0;
14869   u8 is_en = 0;
14870   int ret;
14871
14872   /* Parse args required to build the message */
14873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (input, "enable"))
14876         {
14877           is_set = 1;
14878           is_en = 1;
14879         }
14880       else if (unformat (input, "disable"))
14881         is_set = 1;
14882       else
14883         break;
14884     }
14885
14886   if (!is_set)
14887     {
14888       errmsg ("Value not set");
14889       return -99;
14890     }
14891
14892   /* Construct the API message */
14893   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14894
14895   mp->is_enabled = is_en;
14896
14897   /* send it... */
14898   S (mp);
14899
14900   /* Wait for a reply... */
14901   W (ret);
14902   return ret;
14903 }
14904
14905 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14906
14907 static int
14908 api_one_enable_disable (vat_main_t * vam)
14909 {
14910   unformat_input_t *input = vam->input;
14911   vl_api_one_enable_disable_t *mp;
14912   u8 is_set = 0;
14913   u8 is_en = 0;
14914   int ret;
14915
14916   /* Parse args required to build the message */
14917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (input, "enable"))
14920         {
14921           is_set = 1;
14922           is_en = 1;
14923         }
14924       else if (unformat (input, "disable"))
14925         {
14926           is_set = 1;
14927         }
14928       else
14929         break;
14930     }
14931
14932   if (!is_set)
14933     {
14934       errmsg ("Value not set");
14935       return -99;
14936     }
14937
14938   /* Construct the API message */
14939   M (ONE_ENABLE_DISABLE, mp);
14940
14941   mp->is_en = is_en;
14942
14943   /* send it... */
14944   S (mp);
14945
14946   /* Wait for a reply... */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 #define api_lisp_enable_disable api_one_enable_disable
14952
14953 static int
14954 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14955 {
14956   unformat_input_t *input = vam->input;
14957   vl_api_one_enable_disable_xtr_mode_t *mp;
14958   u8 is_set = 0;
14959   u8 is_en = 0;
14960   int ret;
14961
14962   /* Parse args required to build the message */
14963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (input, "enable"))
14966         {
14967           is_set = 1;
14968           is_en = 1;
14969         }
14970       else if (unformat (input, "disable"))
14971         {
14972           is_set = 1;
14973         }
14974       else
14975         break;
14976     }
14977
14978   if (!is_set)
14979     {
14980       errmsg ("Value not set");
14981       return -99;
14982     }
14983
14984   /* Construct the API message */
14985   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14986
14987   mp->is_en = is_en;
14988
14989   /* send it... */
14990   S (mp);
14991
14992   /* Wait for a reply... */
14993   W (ret);
14994   return ret;
14995 }
14996
14997 static int
14998 api_one_show_xtr_mode (vat_main_t * vam)
14999 {
15000   vl_api_one_show_xtr_mode_t *mp;
15001   int ret;
15002
15003   /* Construct the API message */
15004   M (ONE_SHOW_XTR_MODE, mp);
15005
15006   /* send it... */
15007   S (mp);
15008
15009   /* Wait for a reply... */
15010   W (ret);
15011   return ret;
15012 }
15013
15014 static int
15015 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15016 {
15017   unformat_input_t *input = vam->input;
15018   vl_api_one_enable_disable_pitr_mode_t *mp;
15019   u8 is_set = 0;
15020   u8 is_en = 0;
15021   int ret;
15022
15023   /* Parse args required to build the message */
15024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15025     {
15026       if (unformat (input, "enable"))
15027         {
15028           is_set = 1;
15029           is_en = 1;
15030         }
15031       else if (unformat (input, "disable"))
15032         {
15033           is_set = 1;
15034         }
15035       else
15036         break;
15037     }
15038
15039   if (!is_set)
15040     {
15041       errmsg ("Value not set");
15042       return -99;
15043     }
15044
15045   /* Construct the API message */
15046   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15047
15048   mp->is_en = is_en;
15049
15050   /* send it... */
15051   S (mp);
15052
15053   /* Wait for a reply... */
15054   W (ret);
15055   return ret;
15056 }
15057
15058 static int
15059 api_one_show_pitr_mode (vat_main_t * vam)
15060 {
15061   vl_api_one_show_pitr_mode_t *mp;
15062   int ret;
15063
15064   /* Construct the API message */
15065   M (ONE_SHOW_PITR_MODE, mp);
15066
15067   /* send it... */
15068   S (mp);
15069
15070   /* Wait for a reply... */
15071   W (ret);
15072   return ret;
15073 }
15074
15075 static int
15076 api_one_enable_disable_petr_mode (vat_main_t * vam)
15077 {
15078   unformat_input_t *input = vam->input;
15079   vl_api_one_enable_disable_petr_mode_t *mp;
15080   u8 is_set = 0;
15081   u8 is_en = 0;
15082   int ret;
15083
15084   /* Parse args required to build the message */
15085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15086     {
15087       if (unformat (input, "enable"))
15088         {
15089           is_set = 1;
15090           is_en = 1;
15091         }
15092       else if (unformat (input, "disable"))
15093         {
15094           is_set = 1;
15095         }
15096       else
15097         break;
15098     }
15099
15100   if (!is_set)
15101     {
15102       errmsg ("Value not set");
15103       return -99;
15104     }
15105
15106   /* Construct the API message */
15107   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15108
15109   mp->is_en = is_en;
15110
15111   /* send it... */
15112   S (mp);
15113
15114   /* Wait for a reply... */
15115   W (ret);
15116   return ret;
15117 }
15118
15119 static int
15120 api_one_show_petr_mode (vat_main_t * vam)
15121 {
15122   vl_api_one_show_petr_mode_t *mp;
15123   int ret;
15124
15125   /* Construct the API message */
15126   M (ONE_SHOW_PETR_MODE, mp);
15127
15128   /* send it... */
15129   S (mp);
15130
15131   /* Wait for a reply... */
15132   W (ret);
15133   return ret;
15134 }
15135
15136 static int
15137 api_show_one_map_register_state (vat_main_t * vam)
15138 {
15139   vl_api_show_one_map_register_state_t *mp;
15140   int ret;
15141
15142   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15143
15144   /* send */
15145   S (mp);
15146
15147   /* wait for reply */
15148   W (ret);
15149   return ret;
15150 }
15151
15152 #define api_show_lisp_map_register_state api_show_one_map_register_state
15153
15154 static int
15155 api_show_one_rloc_probe_state (vat_main_t * vam)
15156 {
15157   vl_api_show_one_rloc_probe_state_t *mp;
15158   int ret;
15159
15160   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15161
15162   /* send */
15163   S (mp);
15164
15165   /* wait for reply */
15166   W (ret);
15167   return ret;
15168 }
15169
15170 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15171
15172 static int
15173 api_one_add_del_ndp_entry (vat_main_t * vam)
15174 {
15175   vl_api_one_add_del_ndp_entry_t *mp;
15176   unformat_input_t *input = vam->input;
15177   u8 is_add = 1;
15178   u8 mac_set = 0;
15179   u8 bd_set = 0;
15180   u8 ip_set = 0;
15181   u8 mac[6] = { 0, };
15182   u8 ip6[16] = { 0, };
15183   u32 bd = ~0;
15184   int ret;
15185
15186   /* Parse args required to build the message */
15187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15188     {
15189       if (unformat (input, "del"))
15190         is_add = 0;
15191       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15192         mac_set = 1;
15193       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15194         ip_set = 1;
15195       else if (unformat (input, "bd %d", &bd))
15196         bd_set = 1;
15197       else
15198         {
15199           errmsg ("parse error '%U'", format_unformat_error, input);
15200           return -99;
15201         }
15202     }
15203
15204   if (!bd_set || !ip_set || (!mac_set && is_add))
15205     {
15206       errmsg ("Missing BD, IP or MAC!");
15207       return -99;
15208     }
15209
15210   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15211   mp->is_add = is_add;
15212   clib_memcpy (mp->mac, mac, 6);
15213   mp->bd = clib_host_to_net_u32 (bd);
15214   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15215
15216   /* send */
15217   S (mp);
15218
15219   /* wait for reply */
15220   W (ret);
15221   return ret;
15222 }
15223
15224 static int
15225 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15226 {
15227   vl_api_one_add_del_l2_arp_entry_t *mp;
15228   unformat_input_t *input = vam->input;
15229   u8 is_add = 1;
15230   u8 mac_set = 0;
15231   u8 bd_set = 0;
15232   u8 ip_set = 0;
15233   u8 mac[6] = { 0, };
15234   u32 ip4 = 0, bd = ~0;
15235   int ret;
15236
15237   /* Parse args required to build the message */
15238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15239     {
15240       if (unformat (input, "del"))
15241         is_add = 0;
15242       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15243         mac_set = 1;
15244       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15245         ip_set = 1;
15246       else if (unformat (input, "bd %d", &bd))
15247         bd_set = 1;
15248       else
15249         {
15250           errmsg ("parse error '%U'", format_unformat_error, input);
15251           return -99;
15252         }
15253     }
15254
15255   if (!bd_set || !ip_set || (!mac_set && is_add))
15256     {
15257       errmsg ("Missing BD, IP or MAC!");
15258       return -99;
15259     }
15260
15261   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15262   mp->is_add = is_add;
15263   clib_memcpy (mp->mac, mac, 6);
15264   mp->bd = clib_host_to_net_u32 (bd);
15265   mp->ip4 = ip4;
15266
15267   /* send */
15268   S (mp);
15269
15270   /* wait for reply */
15271   W (ret);
15272   return ret;
15273 }
15274
15275 static int
15276 api_one_ndp_bd_get (vat_main_t * vam)
15277 {
15278   vl_api_one_ndp_bd_get_t *mp;
15279   int ret;
15280
15281   M (ONE_NDP_BD_GET, mp);
15282
15283   /* send */
15284   S (mp);
15285
15286   /* wait for reply */
15287   W (ret);
15288   return ret;
15289 }
15290
15291 static int
15292 api_one_ndp_entries_get (vat_main_t * vam)
15293 {
15294   vl_api_one_ndp_entries_get_t *mp;
15295   unformat_input_t *input = vam->input;
15296   u8 bd_set = 0;
15297   u32 bd = ~0;
15298   int ret;
15299
15300   /* Parse args required to build the message */
15301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15302     {
15303       if (unformat (input, "bd %d", &bd))
15304         bd_set = 1;
15305       else
15306         {
15307           errmsg ("parse error '%U'", format_unformat_error, input);
15308           return -99;
15309         }
15310     }
15311
15312   if (!bd_set)
15313     {
15314       errmsg ("Expected bridge domain!");
15315       return -99;
15316     }
15317
15318   M (ONE_NDP_ENTRIES_GET, mp);
15319   mp->bd = clib_host_to_net_u32 (bd);
15320
15321   /* send */
15322   S (mp);
15323
15324   /* wait for reply */
15325   W (ret);
15326   return ret;
15327 }
15328
15329 static int
15330 api_one_l2_arp_bd_get (vat_main_t * vam)
15331 {
15332   vl_api_one_l2_arp_bd_get_t *mp;
15333   int ret;
15334
15335   M (ONE_L2_ARP_BD_GET, mp);
15336
15337   /* send */
15338   S (mp);
15339
15340   /* wait for reply */
15341   W (ret);
15342   return ret;
15343 }
15344
15345 static int
15346 api_one_l2_arp_entries_get (vat_main_t * vam)
15347 {
15348   vl_api_one_l2_arp_entries_get_t *mp;
15349   unformat_input_t *input = vam->input;
15350   u8 bd_set = 0;
15351   u32 bd = ~0;
15352   int ret;
15353
15354   /* Parse args required to build the message */
15355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat (input, "bd %d", &bd))
15358         bd_set = 1;
15359       else
15360         {
15361           errmsg ("parse error '%U'", format_unformat_error, input);
15362           return -99;
15363         }
15364     }
15365
15366   if (!bd_set)
15367     {
15368       errmsg ("Expected bridge domain!");
15369       return -99;
15370     }
15371
15372   M (ONE_L2_ARP_ENTRIES_GET, mp);
15373   mp->bd = clib_host_to_net_u32 (bd);
15374
15375   /* send */
15376   S (mp);
15377
15378   /* wait for reply */
15379   W (ret);
15380   return ret;
15381 }
15382
15383 static int
15384 api_one_stats_enable_disable (vat_main_t * vam)
15385 {
15386   vl_api_one_stats_enable_disable_t *mp;
15387   unformat_input_t *input = vam->input;
15388   u8 is_set = 0;
15389   u8 is_en = 0;
15390   int ret;
15391
15392   /* Parse args required to build the message */
15393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15394     {
15395       if (unformat (input, "enable"))
15396         {
15397           is_set = 1;
15398           is_en = 1;
15399         }
15400       else if (unformat (input, "disable"))
15401         {
15402           is_set = 1;
15403         }
15404       else
15405         break;
15406     }
15407
15408   if (!is_set)
15409     {
15410       errmsg ("Value not set");
15411       return -99;
15412     }
15413
15414   M (ONE_STATS_ENABLE_DISABLE, mp);
15415   mp->is_en = is_en;
15416
15417   /* send */
15418   S (mp);
15419
15420   /* wait for reply */
15421   W (ret);
15422   return ret;
15423 }
15424
15425 static int
15426 api_show_one_stats_enable_disable (vat_main_t * vam)
15427 {
15428   vl_api_show_one_stats_enable_disable_t *mp;
15429   int ret;
15430
15431   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15432
15433   /* send */
15434   S (mp);
15435
15436   /* wait for reply */
15437   W (ret);
15438   return ret;
15439 }
15440
15441 static int
15442 api_show_one_map_request_mode (vat_main_t * vam)
15443 {
15444   vl_api_show_one_map_request_mode_t *mp;
15445   int ret;
15446
15447   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15448
15449   /* send */
15450   S (mp);
15451
15452   /* wait for reply */
15453   W (ret);
15454   return ret;
15455 }
15456
15457 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15458
15459 static int
15460 api_one_map_request_mode (vat_main_t * vam)
15461 {
15462   unformat_input_t *input = vam->input;
15463   vl_api_one_map_request_mode_t *mp;
15464   u8 mode = 0;
15465   int ret;
15466
15467   /* Parse args required to build the message */
15468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15469     {
15470       if (unformat (input, "dst-only"))
15471         mode = 0;
15472       else if (unformat (input, "src-dst"))
15473         mode = 1;
15474       else
15475         {
15476           errmsg ("parse error '%U'", format_unformat_error, input);
15477           return -99;
15478         }
15479     }
15480
15481   M (ONE_MAP_REQUEST_MODE, mp);
15482
15483   mp->mode = mode;
15484
15485   /* send */
15486   S (mp);
15487
15488   /* wait for reply */
15489   W (ret);
15490   return ret;
15491 }
15492
15493 #define api_lisp_map_request_mode api_one_map_request_mode
15494
15495 /**
15496  * Enable/disable ONE proxy ITR.
15497  *
15498  * @param vam vpp API test context
15499  * @return return code
15500  */
15501 static int
15502 api_one_pitr_set_locator_set (vat_main_t * vam)
15503 {
15504   u8 ls_name_set = 0;
15505   unformat_input_t *input = vam->input;
15506   vl_api_one_pitr_set_locator_set_t *mp;
15507   u8 is_add = 1;
15508   u8 *ls_name = 0;
15509   int ret;
15510
15511   /* Parse args required to build the message */
15512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (input, "del"))
15515         is_add = 0;
15516       else if (unformat (input, "locator-set %s", &ls_name))
15517         ls_name_set = 1;
15518       else
15519         {
15520           errmsg ("parse error '%U'", format_unformat_error, input);
15521           return -99;
15522         }
15523     }
15524
15525   if (!ls_name_set)
15526     {
15527       errmsg ("locator-set name not set!");
15528       return -99;
15529     }
15530
15531   M (ONE_PITR_SET_LOCATOR_SET, mp);
15532
15533   mp->is_add = is_add;
15534   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15535   vec_free (ls_name);
15536
15537   /* send */
15538   S (mp);
15539
15540   /* wait for reply */
15541   W (ret);
15542   return ret;
15543 }
15544
15545 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15546
15547 static int
15548 api_one_nsh_set_locator_set (vat_main_t * vam)
15549 {
15550   u8 ls_name_set = 0;
15551   unformat_input_t *input = vam->input;
15552   vl_api_one_nsh_set_locator_set_t *mp;
15553   u8 is_add = 1;
15554   u8 *ls_name = 0;
15555   int ret;
15556
15557   /* Parse args required to build the message */
15558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15559     {
15560       if (unformat (input, "del"))
15561         is_add = 0;
15562       else if (unformat (input, "ls %s", &ls_name))
15563         ls_name_set = 1;
15564       else
15565         {
15566           errmsg ("parse error '%U'", format_unformat_error, input);
15567           return -99;
15568         }
15569     }
15570
15571   if (!ls_name_set && is_add)
15572     {
15573       errmsg ("locator-set name not set!");
15574       return -99;
15575     }
15576
15577   M (ONE_NSH_SET_LOCATOR_SET, mp);
15578
15579   mp->is_add = is_add;
15580   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15581   vec_free (ls_name);
15582
15583   /* send */
15584   S (mp);
15585
15586   /* wait for reply */
15587   W (ret);
15588   return ret;
15589 }
15590
15591 static int
15592 api_show_one_pitr (vat_main_t * vam)
15593 {
15594   vl_api_show_one_pitr_t *mp;
15595   int ret;
15596
15597   if (!vam->json_output)
15598     {
15599       print (vam->ofp, "%=20s", "lisp status:");
15600     }
15601
15602   M (SHOW_ONE_PITR, mp);
15603   /* send it... */
15604   S (mp);
15605
15606   /* Wait for a reply... */
15607   W (ret);
15608   return ret;
15609 }
15610
15611 #define api_show_lisp_pitr api_show_one_pitr
15612
15613 static int
15614 api_one_use_petr (vat_main_t * vam)
15615 {
15616   unformat_input_t *input = vam->input;
15617   vl_api_one_use_petr_t *mp;
15618   u8 is_add = 0;
15619   ip_address_t ip;
15620   int ret;
15621
15622   clib_memset (&ip, 0, sizeof (ip));
15623
15624   /* Parse args required to build the message */
15625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15626     {
15627       if (unformat (input, "disable"))
15628         is_add = 0;
15629       else
15630         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15631         {
15632           is_add = 1;
15633           ip_addr_version (&ip) = AF_IP4;
15634         }
15635       else
15636         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15637         {
15638           is_add = 1;
15639           ip_addr_version (&ip) = AF_IP6;
15640         }
15641       else
15642         {
15643           errmsg ("parse error '%U'", format_unformat_error, input);
15644           return -99;
15645         }
15646     }
15647
15648   M (ONE_USE_PETR, mp);
15649
15650   mp->is_add = is_add;
15651   if (is_add)
15652     {
15653       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15654       if (mp->is_ip4)
15655         clib_memcpy (mp->address, &ip, 4);
15656       else
15657         clib_memcpy (mp->address, &ip, 16);
15658     }
15659
15660   /* send */
15661   S (mp);
15662
15663   /* wait for reply */
15664   W (ret);
15665   return ret;
15666 }
15667
15668 #define api_lisp_use_petr api_one_use_petr
15669
15670 static int
15671 api_show_one_nsh_mapping (vat_main_t * vam)
15672 {
15673   vl_api_show_one_use_petr_t *mp;
15674   int ret;
15675
15676   if (!vam->json_output)
15677     {
15678       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15679     }
15680
15681   M (SHOW_ONE_NSH_MAPPING, mp);
15682   /* send it... */
15683   S (mp);
15684
15685   /* Wait for a reply... */
15686   W (ret);
15687   return ret;
15688 }
15689
15690 static int
15691 api_show_one_use_petr (vat_main_t * vam)
15692 {
15693   vl_api_show_one_use_petr_t *mp;
15694   int ret;
15695
15696   if (!vam->json_output)
15697     {
15698       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15699     }
15700
15701   M (SHOW_ONE_USE_PETR, mp);
15702   /* send it... */
15703   S (mp);
15704
15705   /* Wait for a reply... */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 #define api_show_lisp_use_petr api_show_one_use_petr
15711
15712 /**
15713  * Add/delete mapping between vni and vrf
15714  */
15715 static int
15716 api_one_eid_table_add_del_map (vat_main_t * vam)
15717 {
15718   unformat_input_t *input = vam->input;
15719   vl_api_one_eid_table_add_del_map_t *mp;
15720   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15721   u32 vni, vrf, bd_index;
15722   int ret;
15723
15724   /* Parse args required to build the message */
15725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15726     {
15727       if (unformat (input, "del"))
15728         is_add = 0;
15729       else if (unformat (input, "vrf %d", &vrf))
15730         vrf_set = 1;
15731       else if (unformat (input, "bd_index %d", &bd_index))
15732         bd_index_set = 1;
15733       else if (unformat (input, "vni %d", &vni))
15734         vni_set = 1;
15735       else
15736         break;
15737     }
15738
15739   if (!vni_set || (!vrf_set && !bd_index_set))
15740     {
15741       errmsg ("missing arguments!");
15742       return -99;
15743     }
15744
15745   if (vrf_set && bd_index_set)
15746     {
15747       errmsg ("error: both vrf and bd entered!");
15748       return -99;
15749     }
15750
15751   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15752
15753   mp->is_add = is_add;
15754   mp->vni = htonl (vni);
15755   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15756   mp->is_l2 = bd_index_set;
15757
15758   /* send */
15759   S (mp);
15760
15761   /* wait for reply */
15762   W (ret);
15763   return ret;
15764 }
15765
15766 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15767
15768 uword
15769 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15770 {
15771   u32 *action = va_arg (*args, u32 *);
15772   u8 *s = 0;
15773
15774   if (unformat (input, "%s", &s))
15775     {
15776       if (!strcmp ((char *) s, "no-action"))
15777         action[0] = 0;
15778       else if (!strcmp ((char *) s, "natively-forward"))
15779         action[0] = 1;
15780       else if (!strcmp ((char *) s, "send-map-request"))
15781         action[0] = 2;
15782       else if (!strcmp ((char *) s, "drop"))
15783         action[0] = 3;
15784       else
15785         {
15786           clib_warning ("invalid action: '%s'", s);
15787           action[0] = 3;
15788         }
15789     }
15790   else
15791     return 0;
15792
15793   vec_free (s);
15794   return 1;
15795 }
15796
15797 /**
15798  * Add/del remote mapping to/from ONE control plane
15799  *
15800  * @param vam vpp API test context
15801  * @return return code
15802  */
15803 static int
15804 api_one_add_del_remote_mapping (vat_main_t * vam)
15805 {
15806   unformat_input_t *input = vam->input;
15807   vl_api_one_add_del_remote_mapping_t *mp;
15808   u32 vni = 0;
15809   lisp_eid_vat_t _eid, *eid = &_eid;
15810   lisp_eid_vat_t _seid, *seid = &_seid;
15811   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15812   u32 action = ~0, p, w, data_len;
15813   ip4_address_t rloc4;
15814   ip6_address_t rloc6;
15815   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15816   int ret;
15817
15818   clib_memset (&rloc, 0, sizeof (rloc));
15819
15820   /* Parse args required to build the message */
15821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15822     {
15823       if (unformat (input, "del-all"))
15824         {
15825           del_all = 1;
15826         }
15827       else if (unformat (input, "del"))
15828         {
15829           is_add = 0;
15830         }
15831       else if (unformat (input, "add"))
15832         {
15833           is_add = 1;
15834         }
15835       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15836         {
15837           eid_set = 1;
15838         }
15839       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15840         {
15841           seid_set = 1;
15842         }
15843       else if (unformat (input, "vni %d", &vni))
15844         {
15845           ;
15846         }
15847       else if (unformat (input, "p %d w %d", &p, &w))
15848         {
15849           if (!curr_rloc)
15850             {
15851               errmsg ("No RLOC configured for setting priority/weight!");
15852               return -99;
15853             }
15854           curr_rloc->priority = p;
15855           curr_rloc->weight = w;
15856         }
15857       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15858         {
15859           rloc.is_ip4 = 1;
15860           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15861           vec_add1 (rlocs, rloc);
15862           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15863         }
15864       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15865         {
15866           rloc.is_ip4 = 0;
15867           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15868           vec_add1 (rlocs, rloc);
15869           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15870         }
15871       else if (unformat (input, "action %U",
15872                          unformat_negative_mapping_action, &action))
15873         {
15874           ;
15875         }
15876       else
15877         {
15878           clib_warning ("parse error '%U'", format_unformat_error, input);
15879           return -99;
15880         }
15881     }
15882
15883   if (0 == eid_set)
15884     {
15885       errmsg ("missing params!");
15886       return -99;
15887     }
15888
15889   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15890     {
15891       errmsg ("no action set for negative map-reply!");
15892       return -99;
15893     }
15894
15895   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15896
15897   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15898   mp->is_add = is_add;
15899   mp->vni = htonl (vni);
15900   mp->action = (u8) action;
15901   mp->is_src_dst = seid_set;
15902   mp->eid_len = eid->len;
15903   mp->seid_len = seid->len;
15904   mp->del_all = del_all;
15905   mp->eid_type = eid->type;
15906   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15907   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15908
15909   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15910   clib_memcpy (mp->rlocs, rlocs, data_len);
15911   vec_free (rlocs);
15912
15913   /* send it... */
15914   S (mp);
15915
15916   /* Wait for a reply... */
15917   W (ret);
15918   return ret;
15919 }
15920
15921 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15922
15923 /**
15924  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15925  * forwarding entries in data-plane accordingly.
15926  *
15927  * @param vam vpp API test context
15928  * @return return code
15929  */
15930 static int
15931 api_one_add_del_adjacency (vat_main_t * vam)
15932 {
15933   unformat_input_t *input = vam->input;
15934   vl_api_one_add_del_adjacency_t *mp;
15935   u32 vni = 0;
15936   ip4_address_t leid4, reid4;
15937   ip6_address_t leid6, reid6;
15938   u8 reid_mac[6] = { 0 };
15939   u8 leid_mac[6] = { 0 };
15940   u8 reid_type, leid_type;
15941   u32 leid_len = 0, reid_len = 0, len;
15942   u8 is_add = 1;
15943   int ret;
15944
15945   leid_type = reid_type = (u8) ~ 0;
15946
15947   /* Parse args required to build the message */
15948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat (input, "del"))
15951         {
15952           is_add = 0;
15953         }
15954       else if (unformat (input, "add"))
15955         {
15956           is_add = 1;
15957         }
15958       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15959                          &reid4, &len))
15960         {
15961           reid_type = 0;        /* ipv4 */
15962           reid_len = len;
15963         }
15964       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15965                          &reid6, &len))
15966         {
15967           reid_type = 1;        /* ipv6 */
15968           reid_len = len;
15969         }
15970       else if (unformat (input, "reid %U", unformat_ethernet_address,
15971                          reid_mac))
15972         {
15973           reid_type = 2;        /* mac */
15974         }
15975       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15976                          &leid4, &len))
15977         {
15978           leid_type = 0;        /* ipv4 */
15979           leid_len = len;
15980         }
15981       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15982                          &leid6, &len))
15983         {
15984           leid_type = 1;        /* ipv6 */
15985           leid_len = len;
15986         }
15987       else if (unformat (input, "leid %U", unformat_ethernet_address,
15988                          leid_mac))
15989         {
15990           leid_type = 2;        /* mac */
15991         }
15992       else if (unformat (input, "vni %d", &vni))
15993         {
15994           ;
15995         }
15996       else
15997         {
15998           errmsg ("parse error '%U'", format_unformat_error, input);
15999           return -99;
16000         }
16001     }
16002
16003   if ((u8) ~ 0 == reid_type)
16004     {
16005       errmsg ("missing params!");
16006       return -99;
16007     }
16008
16009   if (leid_type != reid_type)
16010     {
16011       errmsg ("remote and local EIDs are of different types!");
16012       return -99;
16013     }
16014
16015   M (ONE_ADD_DEL_ADJACENCY, mp);
16016   mp->is_add = is_add;
16017   mp->vni = htonl (vni);
16018   mp->leid_len = leid_len;
16019   mp->reid_len = reid_len;
16020   mp->eid_type = reid_type;
16021
16022   switch (mp->eid_type)
16023     {
16024     case 0:
16025       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16026       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16027       break;
16028     case 1:
16029       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16030       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16031       break;
16032     case 2:
16033       clib_memcpy (mp->leid, leid_mac, 6);
16034       clib_memcpy (mp->reid, reid_mac, 6);
16035       break;
16036     default:
16037       errmsg ("unknown EID type %d!", mp->eid_type);
16038       return 0;
16039     }
16040
16041   /* send it... */
16042   S (mp);
16043
16044   /* Wait for a reply... */
16045   W (ret);
16046   return ret;
16047 }
16048
16049 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16050
16051 uword
16052 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16053 {
16054   u32 *mode = va_arg (*args, u32 *);
16055
16056   if (unformat (input, "lisp"))
16057     *mode = 0;
16058   else if (unformat (input, "vxlan"))
16059     *mode = 1;
16060   else
16061     return 0;
16062
16063   return 1;
16064 }
16065
16066 static int
16067 api_gpe_get_encap_mode (vat_main_t * vam)
16068 {
16069   vl_api_gpe_get_encap_mode_t *mp;
16070   int ret;
16071
16072   /* Construct the API message */
16073   M (GPE_GET_ENCAP_MODE, mp);
16074
16075   /* send it... */
16076   S (mp);
16077
16078   /* Wait for a reply... */
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_gpe_set_encap_mode (vat_main_t * vam)
16085 {
16086   unformat_input_t *input = vam->input;
16087   vl_api_gpe_set_encap_mode_t *mp;
16088   int ret;
16089   u32 mode = 0;
16090
16091   /* Parse args required to build the message */
16092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16095         ;
16096       else
16097         break;
16098     }
16099
16100   /* Construct the API message */
16101   M (GPE_SET_ENCAP_MODE, mp);
16102
16103   mp->mode = mode;
16104
16105   /* send it... */
16106   S (mp);
16107
16108   /* Wait for a reply... */
16109   W (ret);
16110   return ret;
16111 }
16112
16113 static int
16114 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16115 {
16116   unformat_input_t *input = vam->input;
16117   vl_api_gpe_add_del_iface_t *mp;
16118   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16119   u32 dp_table = 0, vni = 0;
16120   int ret;
16121
16122   /* Parse args required to build the message */
16123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16124     {
16125       if (unformat (input, "up"))
16126         {
16127           action_set = 1;
16128           is_add = 1;
16129         }
16130       else if (unformat (input, "down"))
16131         {
16132           action_set = 1;
16133           is_add = 0;
16134         }
16135       else if (unformat (input, "table_id %d", &dp_table))
16136         {
16137           dp_table_set = 1;
16138         }
16139       else if (unformat (input, "bd_id %d", &dp_table))
16140         {
16141           dp_table_set = 1;
16142           is_l2 = 1;
16143         }
16144       else if (unformat (input, "vni %d", &vni))
16145         {
16146           vni_set = 1;
16147         }
16148       else
16149         break;
16150     }
16151
16152   if (action_set == 0)
16153     {
16154       errmsg ("Action not set");
16155       return -99;
16156     }
16157   if (dp_table_set == 0 || vni_set == 0)
16158     {
16159       errmsg ("vni and dp_table must be set");
16160       return -99;
16161     }
16162
16163   /* Construct the API message */
16164   M (GPE_ADD_DEL_IFACE, mp);
16165
16166   mp->is_add = is_add;
16167   mp->dp_table = clib_host_to_net_u32 (dp_table);
16168   mp->is_l2 = is_l2;
16169   mp->vni = clib_host_to_net_u32 (vni);
16170
16171   /* send it... */
16172   S (mp);
16173
16174   /* Wait for a reply... */
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_one_map_register_fallback_threshold (vat_main_t * vam)
16181 {
16182   unformat_input_t *input = vam->input;
16183   vl_api_one_map_register_fallback_threshold_t *mp;
16184   u32 value = 0;
16185   u8 is_set = 0;
16186   int ret;
16187
16188   /* Parse args required to build the message */
16189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (input, "%u", &value))
16192         is_set = 1;
16193       else
16194         {
16195           clib_warning ("parse error '%U'", format_unformat_error, input);
16196           return -99;
16197         }
16198     }
16199
16200   if (!is_set)
16201     {
16202       errmsg ("fallback threshold value is missing!");
16203       return -99;
16204     }
16205
16206   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16207   mp->value = clib_host_to_net_u32 (value);
16208
16209   /* send it... */
16210   S (mp);
16211
16212   /* Wait for a reply... */
16213   W (ret);
16214   return ret;
16215 }
16216
16217 static int
16218 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16219 {
16220   vl_api_show_one_map_register_fallback_threshold_t *mp;
16221   int ret;
16222
16223   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16224
16225   /* send it... */
16226   S (mp);
16227
16228   /* Wait for a reply... */
16229   W (ret);
16230   return ret;
16231 }
16232
16233 uword
16234 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16235 {
16236   u32 *proto = va_arg (*args, u32 *);
16237
16238   if (unformat (input, "udp"))
16239     *proto = 1;
16240   else if (unformat (input, "api"))
16241     *proto = 2;
16242   else
16243     return 0;
16244
16245   return 1;
16246 }
16247
16248 static int
16249 api_one_set_transport_protocol (vat_main_t * vam)
16250 {
16251   unformat_input_t *input = vam->input;
16252   vl_api_one_set_transport_protocol_t *mp;
16253   u8 is_set = 0;
16254   u32 protocol = 0;
16255   int ret;
16256
16257   /* Parse args required to build the message */
16258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16259     {
16260       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16261         is_set = 1;
16262       else
16263         {
16264           clib_warning ("parse error '%U'", format_unformat_error, input);
16265           return -99;
16266         }
16267     }
16268
16269   if (!is_set)
16270     {
16271       errmsg ("Transport protocol missing!");
16272       return -99;
16273     }
16274
16275   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16276   mp->protocol = (u8) protocol;
16277
16278   /* send it... */
16279   S (mp);
16280
16281   /* Wait for a reply... */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 static int
16287 api_one_get_transport_protocol (vat_main_t * vam)
16288 {
16289   vl_api_one_get_transport_protocol_t *mp;
16290   int ret;
16291
16292   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16293
16294   /* send it... */
16295   S (mp);
16296
16297   /* Wait for a reply... */
16298   W (ret);
16299   return ret;
16300 }
16301
16302 static int
16303 api_one_map_register_set_ttl (vat_main_t * vam)
16304 {
16305   unformat_input_t *input = vam->input;
16306   vl_api_one_map_register_set_ttl_t *mp;
16307   u32 ttl = 0;
16308   u8 is_set = 0;
16309   int ret;
16310
16311   /* Parse args required to build the message */
16312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16313     {
16314       if (unformat (input, "%u", &ttl))
16315         is_set = 1;
16316       else
16317         {
16318           clib_warning ("parse error '%U'", format_unformat_error, input);
16319           return -99;
16320         }
16321     }
16322
16323   if (!is_set)
16324     {
16325       errmsg ("TTL value missing!");
16326       return -99;
16327     }
16328
16329   M (ONE_MAP_REGISTER_SET_TTL, mp);
16330   mp->ttl = clib_host_to_net_u32 (ttl);
16331
16332   /* send it... */
16333   S (mp);
16334
16335   /* Wait for a reply... */
16336   W (ret);
16337   return ret;
16338 }
16339
16340 static int
16341 api_show_one_map_register_ttl (vat_main_t * vam)
16342 {
16343   vl_api_show_one_map_register_ttl_t *mp;
16344   int ret;
16345
16346   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16347
16348   /* send it... */
16349   S (mp);
16350
16351   /* Wait for a reply... */
16352   W (ret);
16353   return ret;
16354 }
16355
16356 /**
16357  * Add/del map request itr rlocs from ONE control plane and updates
16358  *
16359  * @param vam vpp API test context
16360  * @return return code
16361  */
16362 static int
16363 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16364 {
16365   unformat_input_t *input = vam->input;
16366   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16367   u8 *locator_set_name = 0;
16368   u8 locator_set_name_set = 0;
16369   u8 is_add = 1;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "del"))
16376         {
16377           is_add = 0;
16378         }
16379       else if (unformat (input, "%_%v%_", &locator_set_name))
16380         {
16381           locator_set_name_set = 1;
16382         }
16383       else
16384         {
16385           clib_warning ("parse error '%U'", format_unformat_error, input);
16386           return -99;
16387         }
16388     }
16389
16390   if (is_add && !locator_set_name_set)
16391     {
16392       errmsg ("itr-rloc is not set!");
16393       return -99;
16394     }
16395
16396   if (is_add && vec_len (locator_set_name) > 64)
16397     {
16398       errmsg ("itr-rloc locator-set name too long");
16399       vec_free (locator_set_name);
16400       return -99;
16401     }
16402
16403   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16404   mp->is_add = is_add;
16405   if (is_add)
16406     {
16407       clib_memcpy (mp->locator_set_name, locator_set_name,
16408                    vec_len (locator_set_name));
16409     }
16410   else
16411     {
16412       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16413     }
16414   vec_free (locator_set_name);
16415
16416   /* send it... */
16417   S (mp);
16418
16419   /* Wait for a reply... */
16420   W (ret);
16421   return ret;
16422 }
16423
16424 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16425
16426 static int
16427 api_one_locator_dump (vat_main_t * vam)
16428 {
16429   unformat_input_t *input = vam->input;
16430   vl_api_one_locator_dump_t *mp;
16431   vl_api_control_ping_t *mp_ping;
16432   u8 is_index_set = 0, is_name_set = 0;
16433   u8 *ls_name = 0;
16434   u32 ls_index = ~0;
16435   int ret;
16436
16437   /* Parse args required to build the message */
16438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16439     {
16440       if (unformat (input, "ls_name %_%v%_", &ls_name))
16441         {
16442           is_name_set = 1;
16443         }
16444       else if (unformat (input, "ls_index %d", &ls_index))
16445         {
16446           is_index_set = 1;
16447         }
16448       else
16449         {
16450           errmsg ("parse error '%U'", format_unformat_error, input);
16451           return -99;
16452         }
16453     }
16454
16455   if (!is_index_set && !is_name_set)
16456     {
16457       errmsg ("error: expected one of index or name!");
16458       return -99;
16459     }
16460
16461   if (is_index_set && is_name_set)
16462     {
16463       errmsg ("error: only one param expected!");
16464       return -99;
16465     }
16466
16467   if (vec_len (ls_name) > 62)
16468     {
16469       errmsg ("error: locator set name too long!");
16470       return -99;
16471     }
16472
16473   if (!vam->json_output)
16474     {
16475       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16476     }
16477
16478   M (ONE_LOCATOR_DUMP, mp);
16479   mp->is_index_set = is_index_set;
16480
16481   if (is_index_set)
16482     mp->ls_index = clib_host_to_net_u32 (ls_index);
16483   else
16484     {
16485       vec_add1 (ls_name, 0);
16486       strncpy ((char *) mp->ls_name, (char *) ls_name,
16487                sizeof (mp->ls_name) - 1);
16488     }
16489
16490   /* send it... */
16491   S (mp);
16492
16493   /* Use a control ping for synchronization */
16494   MPING (CONTROL_PING, mp_ping);
16495   S (mp_ping);
16496
16497   /* Wait for a reply... */
16498   W (ret);
16499   return ret;
16500 }
16501
16502 #define api_lisp_locator_dump api_one_locator_dump
16503
16504 static int
16505 api_one_locator_set_dump (vat_main_t * vam)
16506 {
16507   vl_api_one_locator_set_dump_t *mp;
16508   vl_api_control_ping_t *mp_ping;
16509   unformat_input_t *input = vam->input;
16510   u8 filter = 0;
16511   int ret;
16512
16513   /* Parse args required to build the message */
16514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16515     {
16516       if (unformat (input, "local"))
16517         {
16518           filter = 1;
16519         }
16520       else if (unformat (input, "remote"))
16521         {
16522           filter = 2;
16523         }
16524       else
16525         {
16526           errmsg ("parse error '%U'", format_unformat_error, input);
16527           return -99;
16528         }
16529     }
16530
16531   if (!vam->json_output)
16532     {
16533       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16534     }
16535
16536   M (ONE_LOCATOR_SET_DUMP, mp);
16537
16538   mp->filter = filter;
16539
16540   /* send it... */
16541   S (mp);
16542
16543   /* Use a control ping for synchronization */
16544   MPING (CONTROL_PING, mp_ping);
16545   S (mp_ping);
16546
16547   /* Wait for a reply... */
16548   W (ret);
16549   return ret;
16550 }
16551
16552 #define api_lisp_locator_set_dump api_one_locator_set_dump
16553
16554 static int
16555 api_one_eid_table_map_dump (vat_main_t * vam)
16556 {
16557   u8 is_l2 = 0;
16558   u8 mode_set = 0;
16559   unformat_input_t *input = vam->input;
16560   vl_api_one_eid_table_map_dump_t *mp;
16561   vl_api_control_ping_t *mp_ping;
16562   int ret;
16563
16564   /* Parse args required to build the message */
16565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16566     {
16567       if (unformat (input, "l2"))
16568         {
16569           is_l2 = 1;
16570           mode_set = 1;
16571         }
16572       else if (unformat (input, "l3"))
16573         {
16574           is_l2 = 0;
16575           mode_set = 1;
16576         }
16577       else
16578         {
16579           errmsg ("parse error '%U'", format_unformat_error, input);
16580           return -99;
16581         }
16582     }
16583
16584   if (!mode_set)
16585     {
16586       errmsg ("expected one of 'l2' or 'l3' parameter!");
16587       return -99;
16588     }
16589
16590   if (!vam->json_output)
16591     {
16592       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16593     }
16594
16595   M (ONE_EID_TABLE_MAP_DUMP, mp);
16596   mp->is_l2 = is_l2;
16597
16598   /* send it... */
16599   S (mp);
16600
16601   /* Use a control ping for synchronization */
16602   MPING (CONTROL_PING, mp_ping);
16603   S (mp_ping);
16604
16605   /* Wait for a reply... */
16606   W (ret);
16607   return ret;
16608 }
16609
16610 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16611
16612 static int
16613 api_one_eid_table_vni_dump (vat_main_t * vam)
16614 {
16615   vl_api_one_eid_table_vni_dump_t *mp;
16616   vl_api_control_ping_t *mp_ping;
16617   int ret;
16618
16619   if (!vam->json_output)
16620     {
16621       print (vam->ofp, "VNI");
16622     }
16623
16624   M (ONE_EID_TABLE_VNI_DUMP, mp);
16625
16626   /* send it... */
16627   S (mp);
16628
16629   /* Use a control ping for synchronization */
16630   MPING (CONTROL_PING, mp_ping);
16631   S (mp_ping);
16632
16633   /* Wait for a reply... */
16634   W (ret);
16635   return ret;
16636 }
16637
16638 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16639
16640 static int
16641 api_one_eid_table_dump (vat_main_t * vam)
16642 {
16643   unformat_input_t *i = vam->input;
16644   vl_api_one_eid_table_dump_t *mp;
16645   vl_api_control_ping_t *mp_ping;
16646   struct in_addr ip4;
16647   struct in6_addr ip6;
16648   u8 mac[6];
16649   u8 eid_type = ~0, eid_set = 0;
16650   u32 prefix_length = ~0, t, vni = 0;
16651   u8 filter = 0;
16652   int ret;
16653   lisp_nsh_api_t nsh;
16654
16655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16656     {
16657       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16658         {
16659           eid_set = 1;
16660           eid_type = 0;
16661           prefix_length = t;
16662         }
16663       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16664         {
16665           eid_set = 1;
16666           eid_type = 1;
16667           prefix_length = t;
16668         }
16669       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16670         {
16671           eid_set = 1;
16672           eid_type = 2;
16673         }
16674       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16675         {
16676           eid_set = 1;
16677           eid_type = 3;
16678         }
16679       else if (unformat (i, "vni %d", &t))
16680         {
16681           vni = t;
16682         }
16683       else if (unformat (i, "local"))
16684         {
16685           filter = 1;
16686         }
16687       else if (unformat (i, "remote"))
16688         {
16689           filter = 2;
16690         }
16691       else
16692         {
16693           errmsg ("parse error '%U'", format_unformat_error, i);
16694           return -99;
16695         }
16696     }
16697
16698   if (!vam->json_output)
16699     {
16700       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16701              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16702     }
16703
16704   M (ONE_EID_TABLE_DUMP, mp);
16705
16706   mp->filter = filter;
16707   if (eid_set)
16708     {
16709       mp->eid_set = 1;
16710       mp->vni = htonl (vni);
16711       mp->eid_type = eid_type;
16712       switch (eid_type)
16713         {
16714         case 0:
16715           mp->prefix_length = prefix_length;
16716           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16717           break;
16718         case 1:
16719           mp->prefix_length = prefix_length;
16720           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16721           break;
16722         case 2:
16723           clib_memcpy (mp->eid, mac, sizeof (mac));
16724           break;
16725         case 3:
16726           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16727           break;
16728         default:
16729           errmsg ("unknown EID type %d!", eid_type);
16730           return -99;
16731         }
16732     }
16733
16734   /* send it... */
16735   S (mp);
16736
16737   /* Use a control ping for synchronization */
16738   MPING (CONTROL_PING, mp_ping);
16739   S (mp_ping);
16740
16741   /* Wait for a reply... */
16742   W (ret);
16743   return ret;
16744 }
16745
16746 #define api_lisp_eid_table_dump api_one_eid_table_dump
16747
16748 static int
16749 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16750 {
16751   unformat_input_t *i = vam->input;
16752   vl_api_gpe_fwd_entries_get_t *mp;
16753   u8 vni_set = 0;
16754   u32 vni = ~0;
16755   int ret;
16756
16757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16758     {
16759       if (unformat (i, "vni %d", &vni))
16760         {
16761           vni_set = 1;
16762         }
16763       else
16764         {
16765           errmsg ("parse error '%U'", format_unformat_error, i);
16766           return -99;
16767         }
16768     }
16769
16770   if (!vni_set)
16771     {
16772       errmsg ("vni not set!");
16773       return -99;
16774     }
16775
16776   if (!vam->json_output)
16777     {
16778       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16779              "leid", "reid");
16780     }
16781
16782   M (GPE_FWD_ENTRIES_GET, mp);
16783   mp->vni = clib_host_to_net_u32 (vni);
16784
16785   /* send it... */
16786   S (mp);
16787
16788   /* Wait for a reply... */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16794 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16795 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16796 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16797 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16798 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16799 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16800 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16801
16802 static int
16803 api_one_adjacencies_get (vat_main_t * vam)
16804 {
16805   unformat_input_t *i = vam->input;
16806   vl_api_one_adjacencies_get_t *mp;
16807   u8 vni_set = 0;
16808   u32 vni = ~0;
16809   int ret;
16810
16811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (i, "vni %d", &vni))
16814         {
16815           vni_set = 1;
16816         }
16817       else
16818         {
16819           errmsg ("parse error '%U'", format_unformat_error, i);
16820           return -99;
16821         }
16822     }
16823
16824   if (!vni_set)
16825     {
16826       errmsg ("vni not set!");
16827       return -99;
16828     }
16829
16830   if (!vam->json_output)
16831     {
16832       print (vam->ofp, "%s %40s", "leid", "reid");
16833     }
16834
16835   M (ONE_ADJACENCIES_GET, mp);
16836   mp->vni = clib_host_to_net_u32 (vni);
16837
16838   /* send it... */
16839   S (mp);
16840
16841   /* Wait for a reply... */
16842   W (ret);
16843   return ret;
16844 }
16845
16846 #define api_lisp_adjacencies_get api_one_adjacencies_get
16847
16848 static int
16849 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16850 {
16851   unformat_input_t *i = vam->input;
16852   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16853   int ret;
16854   u8 ip_family_set = 0, is_ip4 = 1;
16855
16856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16857     {
16858       if (unformat (i, "ip4"))
16859         {
16860           ip_family_set = 1;
16861           is_ip4 = 1;
16862         }
16863       else if (unformat (i, "ip6"))
16864         {
16865           ip_family_set = 1;
16866           is_ip4 = 0;
16867         }
16868       else
16869         {
16870           errmsg ("parse error '%U'", format_unformat_error, i);
16871           return -99;
16872         }
16873     }
16874
16875   if (!ip_family_set)
16876     {
16877       errmsg ("ip family not set!");
16878       return -99;
16879     }
16880
16881   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16882   mp->is_ip4 = is_ip4;
16883
16884   /* send it... */
16885   S (mp);
16886
16887   /* Wait for a reply... */
16888   W (ret);
16889   return ret;
16890 }
16891
16892 static int
16893 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16894 {
16895   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16896   int ret;
16897
16898   if (!vam->json_output)
16899     {
16900       print (vam->ofp, "VNIs");
16901     }
16902
16903   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16904
16905   /* send it... */
16906   S (mp);
16907
16908   /* Wait for a reply... */
16909   W (ret);
16910   return ret;
16911 }
16912
16913 static int
16914 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16915 {
16916   unformat_input_t *i = vam->input;
16917   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16918   int ret = 0;
16919   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16920   struct in_addr ip4;
16921   struct in6_addr ip6;
16922   u32 table_id = 0, nh_sw_if_index = ~0;
16923
16924   clib_memset (&ip4, 0, sizeof (ip4));
16925   clib_memset (&ip6, 0, sizeof (ip6));
16926
16927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16928     {
16929       if (unformat (i, "del"))
16930         is_add = 0;
16931       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16932                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16933         {
16934           ip_set = 1;
16935           is_ip4 = 1;
16936         }
16937       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16938                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16939         {
16940           ip_set = 1;
16941           is_ip4 = 0;
16942         }
16943       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16944         {
16945           ip_set = 1;
16946           is_ip4 = 1;
16947           nh_sw_if_index = ~0;
16948         }
16949       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16950         {
16951           ip_set = 1;
16952           is_ip4 = 0;
16953           nh_sw_if_index = ~0;
16954         }
16955       else if (unformat (i, "table %d", &table_id))
16956         ;
16957       else
16958         {
16959           errmsg ("parse error '%U'", format_unformat_error, i);
16960           return -99;
16961         }
16962     }
16963
16964   if (!ip_set)
16965     {
16966       errmsg ("nh addr not set!");
16967       return -99;
16968     }
16969
16970   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16971   mp->is_add = is_add;
16972   mp->table_id = clib_host_to_net_u32 (table_id);
16973   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16974   mp->is_ip4 = is_ip4;
16975   if (is_ip4)
16976     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16977   else
16978     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16979
16980   /* send it... */
16981   S (mp);
16982
16983   /* Wait for a reply... */
16984   W (ret);
16985   return ret;
16986 }
16987
16988 static int
16989 api_one_map_server_dump (vat_main_t * vam)
16990 {
16991   vl_api_one_map_server_dump_t *mp;
16992   vl_api_control_ping_t *mp_ping;
16993   int ret;
16994
16995   if (!vam->json_output)
16996     {
16997       print (vam->ofp, "%=20s", "Map server");
16998     }
16999
17000   M (ONE_MAP_SERVER_DUMP, mp);
17001   /* send it... */
17002   S (mp);
17003
17004   /* Use a control ping for synchronization */
17005   MPING (CONTROL_PING, mp_ping);
17006   S (mp_ping);
17007
17008   /* Wait for a reply... */
17009   W (ret);
17010   return ret;
17011 }
17012
17013 #define api_lisp_map_server_dump api_one_map_server_dump
17014
17015 static int
17016 api_one_map_resolver_dump (vat_main_t * vam)
17017 {
17018   vl_api_one_map_resolver_dump_t *mp;
17019   vl_api_control_ping_t *mp_ping;
17020   int ret;
17021
17022   if (!vam->json_output)
17023     {
17024       print (vam->ofp, "%=20s", "Map resolver");
17025     }
17026
17027   M (ONE_MAP_RESOLVER_DUMP, mp);
17028   /* send it... */
17029   S (mp);
17030
17031   /* Use a control ping for synchronization */
17032   MPING (CONTROL_PING, mp_ping);
17033   S (mp_ping);
17034
17035   /* Wait for a reply... */
17036   W (ret);
17037   return ret;
17038 }
17039
17040 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17041
17042 static int
17043 api_one_stats_flush (vat_main_t * vam)
17044 {
17045   vl_api_one_stats_flush_t *mp;
17046   int ret = 0;
17047
17048   M (ONE_STATS_FLUSH, mp);
17049   S (mp);
17050   W (ret);
17051   return ret;
17052 }
17053
17054 static int
17055 api_one_stats_dump (vat_main_t * vam)
17056 {
17057   vl_api_one_stats_dump_t *mp;
17058   vl_api_control_ping_t *mp_ping;
17059   int ret;
17060
17061   M (ONE_STATS_DUMP, mp);
17062   /* send it... */
17063   S (mp);
17064
17065   /* Use a control ping for synchronization */
17066   MPING (CONTROL_PING, mp_ping);
17067   S (mp_ping);
17068
17069   /* Wait for a reply... */
17070   W (ret);
17071   return ret;
17072 }
17073
17074 static int
17075 api_show_one_status (vat_main_t * vam)
17076 {
17077   vl_api_show_one_status_t *mp;
17078   int ret;
17079
17080   if (!vam->json_output)
17081     {
17082       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17083     }
17084
17085   M (SHOW_ONE_STATUS, mp);
17086   /* send it... */
17087   S (mp);
17088   /* Wait for a reply... */
17089   W (ret);
17090   return ret;
17091 }
17092
17093 #define api_show_lisp_status api_show_one_status
17094
17095 static int
17096 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17097 {
17098   vl_api_gpe_fwd_entry_path_dump_t *mp;
17099   vl_api_control_ping_t *mp_ping;
17100   unformat_input_t *i = vam->input;
17101   u32 fwd_entry_index = ~0;
17102   int ret;
17103
17104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17105     {
17106       if (unformat (i, "index %d", &fwd_entry_index))
17107         ;
17108       else
17109         break;
17110     }
17111
17112   if (~0 == fwd_entry_index)
17113     {
17114       errmsg ("no index specified!");
17115       return -99;
17116     }
17117
17118   if (!vam->json_output)
17119     {
17120       print (vam->ofp, "first line");
17121     }
17122
17123   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17124
17125   /* send it... */
17126   S (mp);
17127   /* Use a control ping for synchronization */
17128   MPING (CONTROL_PING, mp_ping);
17129   S (mp_ping);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 static int
17137 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17138 {
17139   vl_api_one_get_map_request_itr_rlocs_t *mp;
17140   int ret;
17141
17142   if (!vam->json_output)
17143     {
17144       print (vam->ofp, "%=20s", "itr-rlocs:");
17145     }
17146
17147   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17148   /* send it... */
17149   S (mp);
17150   /* Wait for a reply... */
17151   W (ret);
17152   return ret;
17153 }
17154
17155 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17156
17157 static int
17158 api_af_packet_create (vat_main_t * vam)
17159 {
17160   unformat_input_t *i = vam->input;
17161   vl_api_af_packet_create_t *mp;
17162   u8 *host_if_name = 0;
17163   u8 hw_addr[6];
17164   u8 random_hw_addr = 1;
17165   int ret;
17166
17167   clib_memset (hw_addr, 0, sizeof (hw_addr));
17168
17169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17170     {
17171       if (unformat (i, "name %s", &host_if_name))
17172         vec_add1 (host_if_name, 0);
17173       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17174         random_hw_addr = 0;
17175       else
17176         break;
17177     }
17178
17179   if (!vec_len (host_if_name))
17180     {
17181       errmsg ("host-interface name must be specified");
17182       return -99;
17183     }
17184
17185   if (vec_len (host_if_name) > 64)
17186     {
17187       errmsg ("host-interface name too long");
17188       return -99;
17189     }
17190
17191   M (AF_PACKET_CREATE, mp);
17192
17193   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17194   clib_memcpy (mp->hw_addr, hw_addr, 6);
17195   mp->use_random_hw_addr = random_hw_addr;
17196   vec_free (host_if_name);
17197
17198   S (mp);
17199
17200   /* *INDENT-OFF* */
17201   W2 (ret,
17202       ({
17203         if (ret == 0)
17204           fprintf (vam->ofp ? vam->ofp : stderr,
17205                    " new sw_if_index = %d\n", vam->sw_if_index);
17206       }));
17207   /* *INDENT-ON* */
17208   return ret;
17209 }
17210
17211 static int
17212 api_af_packet_delete (vat_main_t * vam)
17213 {
17214   unformat_input_t *i = vam->input;
17215   vl_api_af_packet_delete_t *mp;
17216   u8 *host_if_name = 0;
17217   int ret;
17218
17219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17220     {
17221       if (unformat (i, "name %s", &host_if_name))
17222         vec_add1 (host_if_name, 0);
17223       else
17224         break;
17225     }
17226
17227   if (!vec_len (host_if_name))
17228     {
17229       errmsg ("host-interface name must be specified");
17230       return -99;
17231     }
17232
17233   if (vec_len (host_if_name) > 64)
17234     {
17235       errmsg ("host-interface name too long");
17236       return -99;
17237     }
17238
17239   M (AF_PACKET_DELETE, mp);
17240
17241   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17242   vec_free (host_if_name);
17243
17244   S (mp);
17245   W (ret);
17246   return ret;
17247 }
17248
17249 static void vl_api_af_packet_details_t_handler
17250   (vl_api_af_packet_details_t * mp)
17251 {
17252   vat_main_t *vam = &vat_main;
17253
17254   print (vam->ofp, "%-16s %d",
17255          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17256 }
17257
17258 static void vl_api_af_packet_details_t_handler_json
17259   (vl_api_af_packet_details_t * mp)
17260 {
17261   vat_main_t *vam = &vat_main;
17262   vat_json_node_t *node = NULL;
17263
17264   if (VAT_JSON_ARRAY != vam->json_tree.type)
17265     {
17266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17267       vat_json_init_array (&vam->json_tree);
17268     }
17269   node = vat_json_array_add (&vam->json_tree);
17270
17271   vat_json_init_object (node);
17272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17273   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17274 }
17275
17276 static int
17277 api_af_packet_dump (vat_main_t * vam)
17278 {
17279   vl_api_af_packet_dump_t *mp;
17280   vl_api_control_ping_t *mp_ping;
17281   int ret;
17282
17283   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17284   /* Get list of tap interfaces */
17285   M (AF_PACKET_DUMP, mp);
17286   S (mp);
17287
17288   /* Use a control ping for synchronization */
17289   MPING (CONTROL_PING, mp_ping);
17290   S (mp_ping);
17291
17292   W (ret);
17293   return ret;
17294 }
17295
17296 static int
17297 api_policer_add_del (vat_main_t * vam)
17298 {
17299   unformat_input_t *i = vam->input;
17300   vl_api_policer_add_del_t *mp;
17301   u8 is_add = 1;
17302   u8 *name = 0;
17303   u32 cir = 0;
17304   u32 eir = 0;
17305   u64 cb = 0;
17306   u64 eb = 0;
17307   u8 rate_type = 0;
17308   u8 round_type = 0;
17309   u8 type = 0;
17310   u8 color_aware = 0;
17311   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17312   int ret;
17313
17314   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17315   conform_action.dscp = 0;
17316   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17317   exceed_action.dscp = 0;
17318   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17319   violate_action.dscp = 0;
17320
17321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17322     {
17323       if (unformat (i, "del"))
17324         is_add = 0;
17325       else if (unformat (i, "name %s", &name))
17326         vec_add1 (name, 0);
17327       else if (unformat (i, "cir %u", &cir))
17328         ;
17329       else if (unformat (i, "eir %u", &eir))
17330         ;
17331       else if (unformat (i, "cb %u", &cb))
17332         ;
17333       else if (unformat (i, "eb %u", &eb))
17334         ;
17335       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17336                          &rate_type))
17337         ;
17338       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17339                          &round_type))
17340         ;
17341       else if (unformat (i, "type %U", unformat_policer_type, &type))
17342         ;
17343       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17344                          &conform_action))
17345         ;
17346       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17347                          &exceed_action))
17348         ;
17349       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17350                          &violate_action))
17351         ;
17352       else if (unformat (i, "color-aware"))
17353         color_aware = 1;
17354       else
17355         break;
17356     }
17357
17358   if (!vec_len (name))
17359     {
17360       errmsg ("policer name must be specified");
17361       return -99;
17362     }
17363
17364   if (vec_len (name) > 64)
17365     {
17366       errmsg ("policer name too long");
17367       return -99;
17368     }
17369
17370   M (POLICER_ADD_DEL, mp);
17371
17372   clib_memcpy (mp->name, name, vec_len (name));
17373   vec_free (name);
17374   mp->is_add = is_add;
17375   mp->cir = ntohl (cir);
17376   mp->eir = ntohl (eir);
17377   mp->cb = clib_net_to_host_u64 (cb);
17378   mp->eb = clib_net_to_host_u64 (eb);
17379   mp->rate_type = rate_type;
17380   mp->round_type = round_type;
17381   mp->type = type;
17382   mp->conform_action.type = conform_action.action_type;
17383   mp->conform_action.dscp = conform_action.dscp;
17384   mp->exceed_action.type = exceed_action.action_type;
17385   mp->exceed_action.dscp = exceed_action.dscp;
17386   mp->violate_action.type = violate_action.action_type;
17387   mp->violate_action.dscp = violate_action.dscp;
17388   mp->color_aware = color_aware;
17389
17390   S (mp);
17391   W (ret);
17392   return ret;
17393 }
17394
17395 static int
17396 api_policer_dump (vat_main_t * vam)
17397 {
17398   unformat_input_t *i = vam->input;
17399   vl_api_policer_dump_t *mp;
17400   vl_api_control_ping_t *mp_ping;
17401   u8 *match_name = 0;
17402   u8 match_name_valid = 0;
17403   int ret;
17404
17405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17406     {
17407       if (unformat (i, "name %s", &match_name))
17408         {
17409           vec_add1 (match_name, 0);
17410           match_name_valid = 1;
17411         }
17412       else
17413         break;
17414     }
17415
17416   M (POLICER_DUMP, mp);
17417   mp->match_name_valid = match_name_valid;
17418   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17419   vec_free (match_name);
17420   /* send it... */
17421   S (mp);
17422
17423   /* Use a control ping for synchronization */
17424   MPING (CONTROL_PING, mp_ping);
17425   S (mp_ping);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 static int
17433 api_policer_classify_set_interface (vat_main_t * vam)
17434 {
17435   unformat_input_t *i = vam->input;
17436   vl_api_policer_classify_set_interface_t *mp;
17437   u32 sw_if_index;
17438   int sw_if_index_set;
17439   u32 ip4_table_index = ~0;
17440   u32 ip6_table_index = ~0;
17441   u32 l2_table_index = ~0;
17442   u8 is_add = 1;
17443   int ret;
17444
17445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17446     {
17447       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17448         sw_if_index_set = 1;
17449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17450         sw_if_index_set = 1;
17451       else if (unformat (i, "del"))
17452         is_add = 0;
17453       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17454         ;
17455       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17456         ;
17457       else if (unformat (i, "l2-table %d", &l2_table_index))
17458         ;
17459       else
17460         {
17461           clib_warning ("parse error '%U'", format_unformat_error, i);
17462           return -99;
17463         }
17464     }
17465
17466   if (sw_if_index_set == 0)
17467     {
17468       errmsg ("missing interface name or sw_if_index");
17469       return -99;
17470     }
17471
17472   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17473
17474   mp->sw_if_index = ntohl (sw_if_index);
17475   mp->ip4_table_index = ntohl (ip4_table_index);
17476   mp->ip6_table_index = ntohl (ip6_table_index);
17477   mp->l2_table_index = ntohl (l2_table_index);
17478   mp->is_add = is_add;
17479
17480   S (mp);
17481   W (ret);
17482   return ret;
17483 }
17484
17485 static int
17486 api_policer_classify_dump (vat_main_t * vam)
17487 {
17488   unformat_input_t *i = vam->input;
17489   vl_api_policer_classify_dump_t *mp;
17490   vl_api_control_ping_t *mp_ping;
17491   u8 type = POLICER_CLASSIFY_N_TABLES;
17492   int ret;
17493
17494   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17495     ;
17496   else
17497     {
17498       errmsg ("classify table type must be specified");
17499       return -99;
17500     }
17501
17502   if (!vam->json_output)
17503     {
17504       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17505     }
17506
17507   M (POLICER_CLASSIFY_DUMP, mp);
17508   mp->type = type;
17509   /* send it... */
17510   S (mp);
17511
17512   /* Use a control ping for synchronization */
17513   MPING (CONTROL_PING, mp_ping);
17514   S (mp_ping);
17515
17516   /* Wait for a reply... */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 static u8 *
17522 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17523 {
17524   vl_api_fib_path_nh_proto_t proto =
17525     va_arg (*args, vl_api_fib_path_nh_proto_t);
17526
17527   switch (proto)
17528     {
17529     case FIB_API_PATH_NH_PROTO_IP4:
17530       s = format (s, "ip4");
17531       break;
17532     case FIB_API_PATH_NH_PROTO_IP6:
17533       s = format (s, "ip6");
17534       break;
17535     case FIB_API_PATH_NH_PROTO_MPLS:
17536       s = format (s, "mpls");
17537       break;
17538     case FIB_API_PATH_NH_PROTO_BIER:
17539       s = format (s, "bier");
17540       break;
17541     case FIB_API_PATH_NH_PROTO_ETHERNET:
17542       s = format (s, "ethernet");
17543       break;
17544     }
17545
17546   return (s);
17547 }
17548
17549 static u8 *
17550 format_vl_api_ip_address_union (u8 * s, va_list * args)
17551 {
17552   vl_api_address_family_t af = va_arg (*args, int);
17553   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17554
17555   switch (af)
17556     {
17557     case ADDRESS_IP4:
17558       s = format (s, "%U", format_ip4_address, u->ip4);
17559       break;
17560     case ADDRESS_IP6:
17561       s = format (s, "%U", format_ip6_address, u->ip6);
17562       break;
17563     }
17564   return (s);
17565 }
17566
17567 static u8 *
17568 format_vl_api_fib_path_type (u8 * s, va_list * args)
17569 {
17570   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17571
17572   switch (t)
17573     {
17574     case FIB_API_PATH_TYPE_NORMAL:
17575       s = format (s, "normal");
17576       break;
17577     case FIB_API_PATH_TYPE_LOCAL:
17578       s = format (s, "local");
17579       break;
17580     case FIB_API_PATH_TYPE_DROP:
17581       s = format (s, "drop");
17582       break;
17583     case FIB_API_PATH_TYPE_UDP_ENCAP:
17584       s = format (s, "udp-encap");
17585       break;
17586     case FIB_API_PATH_TYPE_BIER_IMP:
17587       s = format (s, "bier-imp");
17588       break;
17589     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17590       s = format (s, "unreach");
17591       break;
17592     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17593       s = format (s, "prohibit");
17594       break;
17595     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17596       s = format (s, "src-lookup");
17597       break;
17598     case FIB_API_PATH_TYPE_DVR:
17599       s = format (s, "dvr");
17600       break;
17601     case FIB_API_PATH_TYPE_INTERFACE_RX:
17602       s = format (s, "interface-rx");
17603       break;
17604     case FIB_API_PATH_TYPE_CLASSIFY:
17605       s = format (s, "classify");
17606       break;
17607     }
17608
17609   return (s);
17610 }
17611
17612 static void
17613 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17614 {
17615   print (vam->ofp,
17616          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17617          ntohl (fp->weight), ntohl (fp->sw_if_index),
17618          format_vl_api_fib_path_type, fp->type,
17619          format_fib_api_path_nh_proto, fp->proto,
17620          format_vl_api_ip_address_union, &fp->nh.address);
17621 }
17622
17623 static void
17624 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17625                                  vl_api_fib_path_t * fp)
17626 {
17627   struct in_addr ip4;
17628   struct in6_addr ip6;
17629
17630   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17631   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17632   vat_json_object_add_uint (node, "type", fp->type);
17633   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17634   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17635     {
17636       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17637       vat_json_object_add_ip4 (node, "next_hop", ip4);
17638     }
17639   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17640     {
17641       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17642       vat_json_object_add_ip6 (node, "next_hop", ip6);
17643     }
17644 }
17645
17646 static void
17647 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17648 {
17649   vat_main_t *vam = &vat_main;
17650   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17651   vl_api_fib_path_t *fp;
17652   i32 i;
17653
17654   print (vam->ofp, "sw_if_index %d via:",
17655          ntohl (mp->mt_tunnel.mt_sw_if_index));
17656   fp = mp->mt_tunnel.mt_paths;
17657   for (i = 0; i < count; i++)
17658     {
17659       vl_api_fib_path_print (vam, fp);
17660       fp++;
17661     }
17662
17663   print (vam->ofp, "");
17664 }
17665
17666 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17667 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17668
17669 static void
17670 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17671 {
17672   vat_main_t *vam = &vat_main;
17673   vat_json_node_t *node = NULL;
17674   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17675   vl_api_fib_path_t *fp;
17676   i32 i;
17677
17678   if (VAT_JSON_ARRAY != vam->json_tree.type)
17679     {
17680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17681       vat_json_init_array (&vam->json_tree);
17682     }
17683   node = vat_json_array_add (&vam->json_tree);
17684
17685   vat_json_init_object (node);
17686   vat_json_object_add_uint (node, "sw_if_index",
17687                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17688
17689   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17690
17691   fp = mp->mt_tunnel.mt_paths;
17692   for (i = 0; i < count; i++)
17693     {
17694       vl_api_mpls_fib_path_json_print (node, fp);
17695       fp++;
17696     }
17697 }
17698
17699 static int
17700 api_mpls_tunnel_dump (vat_main_t * vam)
17701 {
17702   vl_api_mpls_tunnel_dump_t *mp;
17703   vl_api_control_ping_t *mp_ping;
17704   int ret;
17705
17706   M (MPLS_TUNNEL_DUMP, mp);
17707
17708   S (mp);
17709
17710   /* Use a control ping for synchronization */
17711   MPING (CONTROL_PING, mp_ping);
17712   S (mp_ping);
17713
17714   W (ret);
17715   return ret;
17716 }
17717
17718 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17719 #define vl_api_mpls_table_details_t_print vl_noop_handler
17720
17721
17722 static void
17723 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17724 {
17725   vat_main_t *vam = &vat_main;
17726
17727   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17728 }
17729
17730 static void vl_api_mpls_table_details_t_handler_json
17731   (vl_api_mpls_table_details_t * mp)
17732 {
17733   vat_main_t *vam = &vat_main;
17734   vat_json_node_t *node = NULL;
17735
17736   if (VAT_JSON_ARRAY != vam->json_tree.type)
17737     {
17738       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17739       vat_json_init_array (&vam->json_tree);
17740     }
17741   node = vat_json_array_add (&vam->json_tree);
17742
17743   vat_json_init_object (node);
17744   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17745 }
17746
17747 static int
17748 api_mpls_table_dump (vat_main_t * vam)
17749 {
17750   vl_api_mpls_table_dump_t *mp;
17751   vl_api_control_ping_t *mp_ping;
17752   int ret;
17753
17754   M (MPLS_TABLE_DUMP, mp);
17755   S (mp);
17756
17757   /* Use a control ping for synchronization */
17758   MPING (CONTROL_PING, mp_ping);
17759   S (mp_ping);
17760
17761   W (ret);
17762   return ret;
17763 }
17764
17765 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17766 #define vl_api_mpls_route_details_t_print vl_noop_handler
17767
17768 static void
17769 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17770 {
17771   vat_main_t *vam = &vat_main;
17772   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17773   vl_api_fib_path_t *fp;
17774   int i;
17775
17776   print (vam->ofp,
17777          "table-id %d, label %u, ess_bit %u",
17778          ntohl (mp->mr_route.mr_table_id),
17779          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17780   fp = mp->mr_route.mr_paths;
17781   for (i = 0; i < count; i++)
17782     {
17783       vl_api_fib_path_print (vam, fp);
17784       fp++;
17785     }
17786 }
17787
17788 static void vl_api_mpls_route_details_t_handler_json
17789   (vl_api_mpls_route_details_t * mp)
17790 {
17791   vat_main_t *vam = &vat_main;
17792   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17793   vat_json_node_t *node = NULL;
17794   vl_api_fib_path_t *fp;
17795   int i;
17796
17797   if (VAT_JSON_ARRAY != vam->json_tree.type)
17798     {
17799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17800       vat_json_init_array (&vam->json_tree);
17801     }
17802   node = vat_json_array_add (&vam->json_tree);
17803
17804   vat_json_init_object (node);
17805   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17806   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17807   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17808   vat_json_object_add_uint (node, "path_count", count);
17809   fp = mp->mr_route.mr_paths;
17810   for (i = 0; i < count; i++)
17811     {
17812       vl_api_mpls_fib_path_json_print (node, fp);
17813       fp++;
17814     }
17815 }
17816
17817 static int
17818 api_mpls_route_dump (vat_main_t * vam)
17819 {
17820   unformat_input_t *input = vam->input;
17821   vl_api_mpls_route_dump_t *mp;
17822   vl_api_control_ping_t *mp_ping;
17823   u32 table_id;
17824   int ret;
17825
17826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17827     {
17828       if (unformat (input, "table_id %d", &table_id))
17829         ;
17830       else
17831         break;
17832     }
17833   if (table_id == ~0)
17834     {
17835       errmsg ("missing table id");
17836       return -99;
17837     }
17838
17839   M (MPLS_ROUTE_DUMP, mp);
17840
17841   mp->table.mt_table_id = ntohl (table_id);
17842   S (mp);
17843
17844   /* Use a control ping for synchronization */
17845   MPING (CONTROL_PING, mp_ping);
17846   S (mp_ping);
17847
17848   W (ret);
17849   return ret;
17850 }
17851
17852 #define vl_api_ip_table_details_t_endian vl_noop_handler
17853 #define vl_api_ip_table_details_t_print vl_noop_handler
17854
17855 static void
17856 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17857 {
17858   vat_main_t *vam = &vat_main;
17859
17860   print (vam->ofp,
17861          "%s; table-id %d, prefix %U/%d",
17862          mp->table.name, ntohl (mp->table.table_id));
17863 }
17864
17865
17866 static void vl_api_ip_table_details_t_handler_json
17867   (vl_api_ip_table_details_t * mp)
17868 {
17869   vat_main_t *vam = &vat_main;
17870   vat_json_node_t *node = NULL;
17871
17872   if (VAT_JSON_ARRAY != vam->json_tree.type)
17873     {
17874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17875       vat_json_init_array (&vam->json_tree);
17876     }
17877   node = vat_json_array_add (&vam->json_tree);
17878
17879   vat_json_init_object (node);
17880   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17881 }
17882
17883 static int
17884 api_ip_table_dump (vat_main_t * vam)
17885 {
17886   vl_api_ip_table_dump_t *mp;
17887   vl_api_control_ping_t *mp_ping;
17888   int ret;
17889
17890   M (IP_TABLE_DUMP, mp);
17891   S (mp);
17892
17893   /* Use a control ping for synchronization */
17894   MPING (CONTROL_PING, mp_ping);
17895   S (mp_ping);
17896
17897   W (ret);
17898   return ret;
17899 }
17900
17901 static int
17902 api_ip_mtable_dump (vat_main_t * vam)
17903 {
17904   vl_api_ip_mtable_dump_t *mp;
17905   vl_api_control_ping_t *mp_ping;
17906   int ret;
17907
17908   M (IP_MTABLE_DUMP, mp);
17909   S (mp);
17910
17911   /* Use a control ping for synchronization */
17912   MPING (CONTROL_PING, mp_ping);
17913   S (mp_ping);
17914
17915   W (ret);
17916   return ret;
17917 }
17918
17919 static int
17920 api_ip_mroute_dump (vat_main_t * vam)
17921 {
17922   unformat_input_t *input = vam->input;
17923   vl_api_control_ping_t *mp_ping;
17924   vl_api_ip_mroute_dump_t *mp;
17925   int ret, is_ip6;
17926   u32 table_id;
17927
17928   is_ip6 = 0;
17929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17930     {
17931       if (unformat (input, "table_id %d", &table_id))
17932         ;
17933       else if (unformat (input, "ip6"))
17934         is_ip6 = 1;
17935       else if (unformat (input, "ip4"))
17936         is_ip6 = 0;
17937       else
17938         break;
17939     }
17940   if (table_id == ~0)
17941     {
17942       errmsg ("missing table id");
17943       return -99;
17944     }
17945
17946   M (IP_MROUTE_DUMP, mp);
17947   mp->table.table_id = table_id;
17948   mp->table.is_ip6 = is_ip6;
17949   S (mp);
17950
17951   /* Use a control ping for synchronization */
17952   MPING (CONTROL_PING, mp_ping);
17953   S (mp_ping);
17954
17955   W (ret);
17956   return ret;
17957 }
17958
17959 #define vl_api_ip_route_details_t_endian vl_noop_handler
17960 #define vl_api_ip_route_details_t_print vl_noop_handler
17961
17962 static void
17963 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17964 {
17965   vat_main_t *vam = &vat_main;
17966   u8 count = mp->route.n_paths;
17967   vl_api_fib_path_t *fp;
17968   int i;
17969
17970   print (vam->ofp,
17971          "table-id %d, prefix %U/%d",
17972          ntohl (mp->route.table_id),
17973          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17974   for (i = 0; i < count; i++)
17975     {
17976       fp = &mp->route.paths[i];
17977
17978       vl_api_fib_path_print (vam, fp);
17979       fp++;
17980     }
17981 }
17982
17983 static void vl_api_ip_route_details_t_handler_json
17984   (vl_api_ip_route_details_t * mp)
17985 {
17986   vat_main_t *vam = &vat_main;
17987   u8 count = mp->route.n_paths;
17988   vat_json_node_t *node = NULL;
17989   struct in_addr ip4;
17990   struct in6_addr ip6;
17991   vl_api_fib_path_t *fp;
17992   int i;
17993
17994   if (VAT_JSON_ARRAY != vam->json_tree.type)
17995     {
17996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17997       vat_json_init_array (&vam->json_tree);
17998     }
17999   node = vat_json_array_add (&vam->json_tree);
18000
18001   vat_json_init_object (node);
18002   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18003   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18004     {
18005       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18006       vat_json_object_add_ip6 (node, "prefix", ip6);
18007     }
18008   else
18009     {
18010       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18011       vat_json_object_add_ip4 (node, "prefix", ip4);
18012     }
18013   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18014   vat_json_object_add_uint (node, "path_count", count);
18015   for (i = 0; i < count; i++)
18016     {
18017       fp = &mp->route.paths[i];
18018       vl_api_mpls_fib_path_json_print (node, fp);
18019     }
18020 }
18021
18022 static int
18023 api_ip_route_dump (vat_main_t * vam)
18024 {
18025   unformat_input_t *input = vam->input;
18026   vl_api_ip_route_dump_t *mp;
18027   vl_api_control_ping_t *mp_ping;
18028   u32 table_id;
18029   u8 is_ip6;
18030   int ret;
18031
18032   is_ip6 = 0;
18033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18034     {
18035       if (unformat (input, "table_id %d", &table_id))
18036         ;
18037       else if (unformat (input, "ip6"))
18038         is_ip6 = 1;
18039       else if (unformat (input, "ip4"))
18040         is_ip6 = 0;
18041       else
18042         break;
18043     }
18044   if (table_id == ~0)
18045     {
18046       errmsg ("missing table id");
18047       return -99;
18048     }
18049
18050   M (IP_ROUTE_DUMP, mp);
18051
18052   mp->table.table_id = table_id;
18053   mp->table.is_ip6 = is_ip6;
18054
18055   S (mp);
18056
18057   /* Use a control ping for synchronization */
18058   MPING (CONTROL_PING, mp_ping);
18059   S (mp_ping);
18060
18061   W (ret);
18062   return ret;
18063 }
18064
18065 int
18066 api_classify_table_ids (vat_main_t * vam)
18067 {
18068   vl_api_classify_table_ids_t *mp;
18069   int ret;
18070
18071   /* Construct the API message */
18072   M (CLASSIFY_TABLE_IDS, mp);
18073   mp->context = 0;
18074
18075   S (mp);
18076   W (ret);
18077   return ret;
18078 }
18079
18080 int
18081 api_classify_table_by_interface (vat_main_t * vam)
18082 {
18083   unformat_input_t *input = vam->input;
18084   vl_api_classify_table_by_interface_t *mp;
18085
18086   u32 sw_if_index = ~0;
18087   int ret;
18088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18089     {
18090       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18091         ;
18092       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18093         ;
18094       else
18095         break;
18096     }
18097   if (sw_if_index == ~0)
18098     {
18099       errmsg ("missing interface name or sw_if_index");
18100       return -99;
18101     }
18102
18103   /* Construct the API message */
18104   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18105   mp->context = 0;
18106   mp->sw_if_index = ntohl (sw_if_index);
18107
18108   S (mp);
18109   W (ret);
18110   return ret;
18111 }
18112
18113 int
18114 api_classify_table_info (vat_main_t * vam)
18115 {
18116   unformat_input_t *input = vam->input;
18117   vl_api_classify_table_info_t *mp;
18118
18119   u32 table_id = ~0;
18120   int ret;
18121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (input, "table_id %d", &table_id))
18124         ;
18125       else
18126         break;
18127     }
18128   if (table_id == ~0)
18129     {
18130       errmsg ("missing table id");
18131       return -99;
18132     }
18133
18134   /* Construct the API message */
18135   M (CLASSIFY_TABLE_INFO, mp);
18136   mp->context = 0;
18137   mp->table_id = ntohl (table_id);
18138
18139   S (mp);
18140   W (ret);
18141   return ret;
18142 }
18143
18144 int
18145 api_classify_session_dump (vat_main_t * vam)
18146 {
18147   unformat_input_t *input = vam->input;
18148   vl_api_classify_session_dump_t *mp;
18149   vl_api_control_ping_t *mp_ping;
18150
18151   u32 table_id = ~0;
18152   int ret;
18153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18154     {
18155       if (unformat (input, "table_id %d", &table_id))
18156         ;
18157       else
18158         break;
18159     }
18160   if (table_id == ~0)
18161     {
18162       errmsg ("missing table id");
18163       return -99;
18164     }
18165
18166   /* Construct the API message */
18167   M (CLASSIFY_SESSION_DUMP, mp);
18168   mp->context = 0;
18169   mp->table_id = ntohl (table_id);
18170   S (mp);
18171
18172   /* Use a control ping for synchronization */
18173   MPING (CONTROL_PING, mp_ping);
18174   S (mp_ping);
18175
18176   W (ret);
18177   return ret;
18178 }
18179
18180 static void
18181 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18182 {
18183   vat_main_t *vam = &vat_main;
18184
18185   print (vam->ofp, "collector_address %U, collector_port %d, "
18186          "src_address %U, vrf_id %d, path_mtu %u, "
18187          "template_interval %u, udp_checksum %d",
18188          format_ip4_address, mp->collector_address,
18189          ntohs (mp->collector_port),
18190          format_ip4_address, mp->src_address,
18191          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18192          ntohl (mp->template_interval), mp->udp_checksum);
18193
18194   vam->retval = 0;
18195   vam->result_ready = 1;
18196 }
18197
18198 static void
18199   vl_api_ipfix_exporter_details_t_handler_json
18200   (vl_api_ipfix_exporter_details_t * mp)
18201 {
18202   vat_main_t *vam = &vat_main;
18203   vat_json_node_t node;
18204   struct in_addr collector_address;
18205   struct in_addr src_address;
18206
18207   vat_json_init_object (&node);
18208   clib_memcpy (&collector_address, &mp->collector_address,
18209                sizeof (collector_address));
18210   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18211   vat_json_object_add_uint (&node, "collector_port",
18212                             ntohs (mp->collector_port));
18213   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18214   vat_json_object_add_ip4 (&node, "src_address", src_address);
18215   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18216   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18217   vat_json_object_add_uint (&node, "template_interval",
18218                             ntohl (mp->template_interval));
18219   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18220
18221   vat_json_print (vam->ofp, &node);
18222   vat_json_free (&node);
18223   vam->retval = 0;
18224   vam->result_ready = 1;
18225 }
18226
18227 int
18228 api_ipfix_exporter_dump (vat_main_t * vam)
18229 {
18230   vl_api_ipfix_exporter_dump_t *mp;
18231   int ret;
18232
18233   /* Construct the API message */
18234   M (IPFIX_EXPORTER_DUMP, mp);
18235   mp->context = 0;
18236
18237   S (mp);
18238   W (ret);
18239   return ret;
18240 }
18241
18242 static int
18243 api_ipfix_classify_stream_dump (vat_main_t * vam)
18244 {
18245   vl_api_ipfix_classify_stream_dump_t *mp;
18246   int ret;
18247
18248   /* Construct the API message */
18249   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18250   mp->context = 0;
18251
18252   S (mp);
18253   W (ret);
18254   return ret;
18255   /* NOTREACHED */
18256   return 0;
18257 }
18258
18259 static void
18260   vl_api_ipfix_classify_stream_details_t_handler
18261   (vl_api_ipfix_classify_stream_details_t * mp)
18262 {
18263   vat_main_t *vam = &vat_main;
18264   print (vam->ofp, "domain_id %d, src_port %d",
18265          ntohl (mp->domain_id), ntohs (mp->src_port));
18266   vam->retval = 0;
18267   vam->result_ready = 1;
18268 }
18269
18270 static void
18271   vl_api_ipfix_classify_stream_details_t_handler_json
18272   (vl_api_ipfix_classify_stream_details_t * mp)
18273 {
18274   vat_main_t *vam = &vat_main;
18275   vat_json_node_t node;
18276
18277   vat_json_init_object (&node);
18278   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18279   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18280
18281   vat_json_print (vam->ofp, &node);
18282   vat_json_free (&node);
18283   vam->retval = 0;
18284   vam->result_ready = 1;
18285 }
18286
18287 static int
18288 api_ipfix_classify_table_dump (vat_main_t * vam)
18289 {
18290   vl_api_ipfix_classify_table_dump_t *mp;
18291   vl_api_control_ping_t *mp_ping;
18292   int ret;
18293
18294   if (!vam->json_output)
18295     {
18296       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18297              "transport_protocol");
18298     }
18299
18300   /* Construct the API message */
18301   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18302
18303   /* send it... */
18304   S (mp);
18305
18306   /* Use a control ping for synchronization */
18307   MPING (CONTROL_PING, mp_ping);
18308   S (mp_ping);
18309
18310   W (ret);
18311   return ret;
18312 }
18313
18314 static void
18315   vl_api_ipfix_classify_table_details_t_handler
18316   (vl_api_ipfix_classify_table_details_t * mp)
18317 {
18318   vat_main_t *vam = &vat_main;
18319   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18320          mp->transport_protocol);
18321 }
18322
18323 static void
18324   vl_api_ipfix_classify_table_details_t_handler_json
18325   (vl_api_ipfix_classify_table_details_t * mp)
18326 {
18327   vat_json_node_t *node = NULL;
18328   vat_main_t *vam = &vat_main;
18329
18330   if (VAT_JSON_ARRAY != vam->json_tree.type)
18331     {
18332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18333       vat_json_init_array (&vam->json_tree);
18334     }
18335
18336   node = vat_json_array_add (&vam->json_tree);
18337   vat_json_init_object (node);
18338
18339   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18340   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18341   vat_json_object_add_uint (node, "transport_protocol",
18342                             mp->transport_protocol);
18343 }
18344
18345 static int
18346 api_sw_interface_span_enable_disable (vat_main_t * vam)
18347 {
18348   unformat_input_t *i = vam->input;
18349   vl_api_sw_interface_span_enable_disable_t *mp;
18350   u32 src_sw_if_index = ~0;
18351   u32 dst_sw_if_index = ~0;
18352   u8 state = 3;
18353   int ret;
18354   u8 is_l2 = 0;
18355
18356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18357     {
18358       if (unformat
18359           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18360         ;
18361       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18362         ;
18363       else
18364         if (unformat
18365             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18366         ;
18367       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18368         ;
18369       else if (unformat (i, "disable"))
18370         state = 0;
18371       else if (unformat (i, "rx"))
18372         state = 1;
18373       else if (unformat (i, "tx"))
18374         state = 2;
18375       else if (unformat (i, "both"))
18376         state = 3;
18377       else if (unformat (i, "l2"))
18378         is_l2 = 1;
18379       else
18380         break;
18381     }
18382
18383   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18384
18385   mp->sw_if_index_from = htonl (src_sw_if_index);
18386   mp->sw_if_index_to = htonl (dst_sw_if_index);
18387   mp->state = state;
18388   mp->is_l2 = is_l2;
18389
18390   S (mp);
18391   W (ret);
18392   return ret;
18393 }
18394
18395 static void
18396 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18397                                             * mp)
18398 {
18399   vat_main_t *vam = &vat_main;
18400   u8 *sw_if_from_name = 0;
18401   u8 *sw_if_to_name = 0;
18402   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18403   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18404   char *states[] = { "none", "rx", "tx", "both" };
18405   hash_pair_t *p;
18406
18407   /* *INDENT-OFF* */
18408   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18409   ({
18410     if ((u32) p->value[0] == sw_if_index_from)
18411       {
18412         sw_if_from_name = (u8 *)(p->key);
18413         if (sw_if_to_name)
18414           break;
18415       }
18416     if ((u32) p->value[0] == sw_if_index_to)
18417       {
18418         sw_if_to_name = (u8 *)(p->key);
18419         if (sw_if_from_name)
18420           break;
18421       }
18422   }));
18423   /* *INDENT-ON* */
18424   print (vam->ofp, "%20s => %20s (%s) %s",
18425          sw_if_from_name, sw_if_to_name, states[mp->state],
18426          mp->is_l2 ? "l2" : "device");
18427 }
18428
18429 static void
18430   vl_api_sw_interface_span_details_t_handler_json
18431   (vl_api_sw_interface_span_details_t * mp)
18432 {
18433   vat_main_t *vam = &vat_main;
18434   vat_json_node_t *node = NULL;
18435   u8 *sw_if_from_name = 0;
18436   u8 *sw_if_to_name = 0;
18437   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18438   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18439   hash_pair_t *p;
18440
18441   /* *INDENT-OFF* */
18442   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18443   ({
18444     if ((u32) p->value[0] == sw_if_index_from)
18445       {
18446         sw_if_from_name = (u8 *)(p->key);
18447         if (sw_if_to_name)
18448           break;
18449       }
18450     if ((u32) p->value[0] == sw_if_index_to)
18451       {
18452         sw_if_to_name = (u8 *)(p->key);
18453         if (sw_if_from_name)
18454           break;
18455       }
18456   }));
18457   /* *INDENT-ON* */
18458
18459   if (VAT_JSON_ARRAY != vam->json_tree.type)
18460     {
18461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18462       vat_json_init_array (&vam->json_tree);
18463     }
18464   node = vat_json_array_add (&vam->json_tree);
18465
18466   vat_json_init_object (node);
18467   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18468   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18469   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18470   if (0 != sw_if_to_name)
18471     {
18472       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18473     }
18474   vat_json_object_add_uint (node, "state", mp->state);
18475   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18476 }
18477
18478 static int
18479 api_sw_interface_span_dump (vat_main_t * vam)
18480 {
18481   unformat_input_t *input = vam->input;
18482   vl_api_sw_interface_span_dump_t *mp;
18483   vl_api_control_ping_t *mp_ping;
18484   u8 is_l2 = 0;
18485   int ret;
18486
18487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18488     {
18489       if (unformat (input, "l2"))
18490         is_l2 = 1;
18491       else
18492         break;
18493     }
18494
18495   M (SW_INTERFACE_SPAN_DUMP, mp);
18496   mp->is_l2 = is_l2;
18497   S (mp);
18498
18499   /* Use a control ping for synchronization */
18500   MPING (CONTROL_PING, mp_ping);
18501   S (mp_ping);
18502
18503   W (ret);
18504   return ret;
18505 }
18506
18507 int
18508 api_pg_create_interface (vat_main_t * vam)
18509 {
18510   unformat_input_t *input = vam->input;
18511   vl_api_pg_create_interface_t *mp;
18512
18513   u32 if_id = ~0, gso_size = 0;
18514   u8 gso_enabled = 0;
18515   int ret;
18516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18517     {
18518       if (unformat (input, "if_id %d", &if_id))
18519         ;
18520       else if (unformat (input, "gso-enabled"))
18521         {
18522           gso_enabled = 1;
18523           if (unformat (input, "gso-size %u", &gso_size))
18524             ;
18525           else
18526             {
18527               errmsg ("missing gso-size");
18528               return -99;
18529             }
18530         }
18531       else
18532         break;
18533     }
18534   if (if_id == ~0)
18535     {
18536       errmsg ("missing pg interface index");
18537       return -99;
18538     }
18539
18540   /* Construct the API message */
18541   M (PG_CREATE_INTERFACE, mp);
18542   mp->context = 0;
18543   mp->interface_id = ntohl (if_id);
18544   mp->gso_enabled = gso_enabled;
18545
18546   S (mp);
18547   W (ret);
18548   return ret;
18549 }
18550
18551 int
18552 api_pg_capture (vat_main_t * vam)
18553 {
18554   unformat_input_t *input = vam->input;
18555   vl_api_pg_capture_t *mp;
18556
18557   u32 if_id = ~0;
18558   u8 enable = 1;
18559   u32 count = 1;
18560   u8 pcap_file_set = 0;
18561   u8 *pcap_file = 0;
18562   int ret;
18563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18564     {
18565       if (unformat (input, "if_id %d", &if_id))
18566         ;
18567       else if (unformat (input, "pcap %s", &pcap_file))
18568         pcap_file_set = 1;
18569       else if (unformat (input, "count %d", &count))
18570         ;
18571       else if (unformat (input, "disable"))
18572         enable = 0;
18573       else
18574         break;
18575     }
18576   if (if_id == ~0)
18577     {
18578       errmsg ("missing pg interface index");
18579       return -99;
18580     }
18581   if (pcap_file_set > 0)
18582     {
18583       if (vec_len (pcap_file) > 255)
18584         {
18585           errmsg ("pcap file name is too long");
18586           return -99;
18587         }
18588     }
18589
18590   /* Construct the API message */
18591   M (PG_CAPTURE, mp);
18592   mp->context = 0;
18593   mp->interface_id = ntohl (if_id);
18594   mp->is_enabled = enable;
18595   mp->count = ntohl (count);
18596   if (pcap_file_set != 0)
18597     {
18598       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18599     }
18600   vec_free (pcap_file);
18601
18602   S (mp);
18603   W (ret);
18604   return ret;
18605 }
18606
18607 int
18608 api_pg_enable_disable (vat_main_t * vam)
18609 {
18610   unformat_input_t *input = vam->input;
18611   vl_api_pg_enable_disable_t *mp;
18612
18613   u8 enable = 1;
18614   u8 stream_name_set = 0;
18615   u8 *stream_name = 0;
18616   int ret;
18617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18618     {
18619       if (unformat (input, "stream %s", &stream_name))
18620         stream_name_set = 1;
18621       else if (unformat (input, "disable"))
18622         enable = 0;
18623       else
18624         break;
18625     }
18626
18627   if (stream_name_set > 0)
18628     {
18629       if (vec_len (stream_name) > 255)
18630         {
18631           errmsg ("stream name too long");
18632           return -99;
18633         }
18634     }
18635
18636   /* Construct the API message */
18637   M (PG_ENABLE_DISABLE, mp);
18638   mp->context = 0;
18639   mp->is_enabled = enable;
18640   if (stream_name_set != 0)
18641     {
18642       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18643     }
18644   vec_free (stream_name);
18645
18646   S (mp);
18647   W (ret);
18648   return ret;
18649 }
18650
18651 int
18652 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18653 {
18654   unformat_input_t *input = vam->input;
18655   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18656
18657   u16 *low_ports = 0;
18658   u16 *high_ports = 0;
18659   u16 this_low;
18660   u16 this_hi;
18661   vl_api_prefix_t prefix;
18662   u32 tmp, tmp2;
18663   u8 prefix_set = 0;
18664   u32 vrf_id = ~0;
18665   u8 is_add = 1;
18666   int ret;
18667
18668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18669     {
18670       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18671         prefix_set = 1;
18672       else if (unformat (input, "vrf %d", &vrf_id))
18673         ;
18674       else if (unformat (input, "del"))
18675         is_add = 0;
18676       else if (unformat (input, "port %d", &tmp))
18677         {
18678           if (tmp == 0 || tmp > 65535)
18679             {
18680               errmsg ("port %d out of range", tmp);
18681               return -99;
18682             }
18683           this_low = tmp;
18684           this_hi = this_low + 1;
18685           vec_add1 (low_ports, this_low);
18686           vec_add1 (high_ports, this_hi);
18687         }
18688       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18689         {
18690           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18691             {
18692               errmsg ("incorrect range parameters");
18693               return -99;
18694             }
18695           this_low = tmp;
18696           /* Note: in debug CLI +1 is added to high before
18697              passing to real fn that does "the work"
18698              (ip_source_and_port_range_check_add_del).
18699              This fn is a wrapper around the binary API fn a
18700              control plane will call, which expects this increment
18701              to have occurred. Hence letting the binary API control
18702              plane fn do the increment for consistency between VAT
18703              and other control planes.
18704            */
18705           this_hi = tmp2;
18706           vec_add1 (low_ports, this_low);
18707           vec_add1 (high_ports, this_hi);
18708         }
18709       else
18710         break;
18711     }
18712
18713   if (prefix_set == 0)
18714     {
18715       errmsg ("<address>/<mask> not specified");
18716       return -99;
18717     }
18718
18719   if (vrf_id == ~0)
18720     {
18721       errmsg ("VRF ID required, not specified");
18722       return -99;
18723     }
18724
18725   if (vrf_id == 0)
18726     {
18727       errmsg
18728         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18729       return -99;
18730     }
18731
18732   if (vec_len (low_ports) == 0)
18733     {
18734       errmsg ("At least one port or port range required");
18735       return -99;
18736     }
18737
18738   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18739
18740   mp->is_add = is_add;
18741
18742   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18743
18744   mp->number_of_ranges = vec_len (low_ports);
18745
18746   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18747   vec_free (low_ports);
18748
18749   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18750   vec_free (high_ports);
18751
18752   mp->vrf_id = ntohl (vrf_id);
18753
18754   S (mp);
18755   W (ret);
18756   return ret;
18757 }
18758
18759 int
18760 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18761 {
18762   unformat_input_t *input = vam->input;
18763   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18764   u32 sw_if_index = ~0;
18765   int vrf_set = 0;
18766   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18767   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18768   u8 is_add = 1;
18769   int ret;
18770
18771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18772     {
18773       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18774         ;
18775       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18776         ;
18777       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18778         vrf_set = 1;
18779       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18780         vrf_set = 1;
18781       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18782         vrf_set = 1;
18783       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18784         vrf_set = 1;
18785       else if (unformat (input, "del"))
18786         is_add = 0;
18787       else
18788         break;
18789     }
18790
18791   if (sw_if_index == ~0)
18792     {
18793       errmsg ("Interface required but not specified");
18794       return -99;
18795     }
18796
18797   if (vrf_set == 0)
18798     {
18799       errmsg ("VRF ID required but not specified");
18800       return -99;
18801     }
18802
18803   if (tcp_out_vrf_id == 0
18804       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18805     {
18806       errmsg
18807         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18808       return -99;
18809     }
18810
18811   /* Construct the API message */
18812   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18813
18814   mp->sw_if_index = ntohl (sw_if_index);
18815   mp->is_add = is_add;
18816   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18817   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18818   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18819   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18820
18821   /* send it... */
18822   S (mp);
18823
18824   /* Wait for a reply... */
18825   W (ret);
18826   return ret;
18827 }
18828
18829 static int
18830 api_set_punt (vat_main_t * vam)
18831 {
18832   unformat_input_t *i = vam->input;
18833   vl_api_address_family_t af;
18834   vl_api_set_punt_t *mp;
18835   u32 protocol = ~0;
18836   u32 port = ~0;
18837   int is_add = 1;
18838   int ret;
18839
18840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18843         ;
18844       else if (unformat (i, "protocol %d", &protocol))
18845         ;
18846       else if (unformat (i, "port %d", &port))
18847         ;
18848       else if (unformat (i, "del"))
18849         is_add = 0;
18850       else
18851         {
18852           clib_warning ("parse error '%U'", format_unformat_error, i);
18853           return -99;
18854         }
18855     }
18856
18857   M (SET_PUNT, mp);
18858
18859   mp->is_add = (u8) is_add;
18860   mp->punt.type = PUNT_API_TYPE_L4;
18861   mp->punt.punt.l4.af = af;
18862   mp->punt.punt.l4.protocol = (u8) protocol;
18863   mp->punt.punt.l4.port = htons ((u16) port);
18864
18865   S (mp);
18866   W (ret);
18867   return ret;
18868 }
18869
18870 static int
18871 api_delete_subif (vat_main_t * vam)
18872 {
18873   unformat_input_t *i = vam->input;
18874   vl_api_delete_subif_t *mp;
18875   u32 sw_if_index = ~0;
18876   int ret;
18877
18878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18879     {
18880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18881         ;
18882       if (unformat (i, "sw_if_index %d", &sw_if_index))
18883         ;
18884       else
18885         break;
18886     }
18887
18888   if (sw_if_index == ~0)
18889     {
18890       errmsg ("missing sw_if_index");
18891       return -99;
18892     }
18893
18894   /* Construct the API message */
18895   M (DELETE_SUBIF, mp);
18896   mp->sw_if_index = ntohl (sw_if_index);
18897
18898   S (mp);
18899   W (ret);
18900   return ret;
18901 }
18902
18903 #define foreach_pbb_vtr_op      \
18904 _("disable",  L2_VTR_DISABLED)  \
18905 _("pop",  L2_VTR_POP_2)         \
18906 _("push",  L2_VTR_PUSH_2)
18907
18908 static int
18909 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18910 {
18911   unformat_input_t *i = vam->input;
18912   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18913   u32 sw_if_index = ~0, vtr_op = ~0;
18914   u16 outer_tag = ~0;
18915   u8 dmac[6], smac[6];
18916   u8 dmac_set = 0, smac_set = 0;
18917   u16 vlanid = 0;
18918   u32 sid = ~0;
18919   u32 tmp;
18920   int ret;
18921
18922   /* Shut up coverity */
18923   clib_memset (dmac, 0, sizeof (dmac));
18924   clib_memset (smac, 0, sizeof (smac));
18925
18926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18927     {
18928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18929         ;
18930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18931         ;
18932       else if (unformat (i, "vtr_op %d", &vtr_op))
18933         ;
18934 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18935       foreach_pbb_vtr_op
18936 #undef _
18937         else if (unformat (i, "translate_pbb_stag"))
18938         {
18939           if (unformat (i, "%d", &tmp))
18940             {
18941               vtr_op = L2_VTR_TRANSLATE_2_1;
18942               outer_tag = tmp;
18943             }
18944           else
18945             {
18946               errmsg
18947                 ("translate_pbb_stag operation requires outer tag definition");
18948               return -99;
18949             }
18950         }
18951       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18952         dmac_set++;
18953       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18954         smac_set++;
18955       else if (unformat (i, "sid %d", &sid))
18956         ;
18957       else if (unformat (i, "vlanid %d", &tmp))
18958         vlanid = tmp;
18959       else
18960         {
18961           clib_warning ("parse error '%U'", format_unformat_error, i);
18962           return -99;
18963         }
18964     }
18965
18966   if ((sw_if_index == ~0) || (vtr_op == ~0))
18967     {
18968       errmsg ("missing sw_if_index or vtr operation");
18969       return -99;
18970     }
18971   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18972       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18973     {
18974       errmsg
18975         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18976       return -99;
18977     }
18978
18979   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18980   mp->sw_if_index = ntohl (sw_if_index);
18981   mp->vtr_op = ntohl (vtr_op);
18982   mp->outer_tag = ntohs (outer_tag);
18983   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18984   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18985   mp->b_vlanid = ntohs (vlanid);
18986   mp->i_sid = ntohl (sid);
18987
18988   S (mp);
18989   W (ret);
18990   return ret;
18991 }
18992
18993 static int
18994 api_flow_classify_set_interface (vat_main_t * vam)
18995 {
18996   unformat_input_t *i = vam->input;
18997   vl_api_flow_classify_set_interface_t *mp;
18998   u32 sw_if_index;
18999   int sw_if_index_set;
19000   u32 ip4_table_index = ~0;
19001   u32 ip6_table_index = ~0;
19002   u8 is_add = 1;
19003   int ret;
19004
19005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19006     {
19007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19008         sw_if_index_set = 1;
19009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19010         sw_if_index_set = 1;
19011       else if (unformat (i, "del"))
19012         is_add = 0;
19013       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19014         ;
19015       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19016         ;
19017       else
19018         {
19019           clib_warning ("parse error '%U'", format_unformat_error, i);
19020           return -99;
19021         }
19022     }
19023
19024   if (sw_if_index_set == 0)
19025     {
19026       errmsg ("missing interface name or sw_if_index");
19027       return -99;
19028     }
19029
19030   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19031
19032   mp->sw_if_index = ntohl (sw_if_index);
19033   mp->ip4_table_index = ntohl (ip4_table_index);
19034   mp->ip6_table_index = ntohl (ip6_table_index);
19035   mp->is_add = is_add;
19036
19037   S (mp);
19038   W (ret);
19039   return ret;
19040 }
19041
19042 static int
19043 api_flow_classify_dump (vat_main_t * vam)
19044 {
19045   unformat_input_t *i = vam->input;
19046   vl_api_flow_classify_dump_t *mp;
19047   vl_api_control_ping_t *mp_ping;
19048   u8 type = FLOW_CLASSIFY_N_TABLES;
19049   int ret;
19050
19051   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19052     ;
19053   else
19054     {
19055       errmsg ("classify table type must be specified");
19056       return -99;
19057     }
19058
19059   if (!vam->json_output)
19060     {
19061       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19062     }
19063
19064   M (FLOW_CLASSIFY_DUMP, mp);
19065   mp->type = type;
19066   /* send it... */
19067   S (mp);
19068
19069   /* Use a control ping for synchronization */
19070   MPING (CONTROL_PING, mp_ping);
19071   S (mp_ping);
19072
19073   /* Wait for a reply... */
19074   W (ret);
19075   return ret;
19076 }
19077
19078 static int
19079 api_feature_enable_disable (vat_main_t * vam)
19080 {
19081   unformat_input_t *i = vam->input;
19082   vl_api_feature_enable_disable_t *mp;
19083   u8 *arc_name = 0;
19084   u8 *feature_name = 0;
19085   u32 sw_if_index = ~0;
19086   u8 enable = 1;
19087   int ret;
19088
19089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19090     {
19091       if (unformat (i, "arc_name %s", &arc_name))
19092         ;
19093       else if (unformat (i, "feature_name %s", &feature_name))
19094         ;
19095       else
19096         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19097         ;
19098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19099         ;
19100       else if (unformat (i, "disable"))
19101         enable = 0;
19102       else
19103         break;
19104     }
19105
19106   if (arc_name == 0)
19107     {
19108       errmsg ("missing arc name");
19109       return -99;
19110     }
19111   if (vec_len (arc_name) > 63)
19112     {
19113       errmsg ("arc name too long");
19114     }
19115
19116   if (feature_name == 0)
19117     {
19118       errmsg ("missing feature name");
19119       return -99;
19120     }
19121   if (vec_len (feature_name) > 63)
19122     {
19123       errmsg ("feature name too long");
19124     }
19125
19126   if (sw_if_index == ~0)
19127     {
19128       errmsg ("missing interface name or sw_if_index");
19129       return -99;
19130     }
19131
19132   /* Construct the API message */
19133   M (FEATURE_ENABLE_DISABLE, mp);
19134   mp->sw_if_index = ntohl (sw_if_index);
19135   mp->enable = enable;
19136   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19137   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19138   vec_free (arc_name);
19139   vec_free (feature_name);
19140
19141   S (mp);
19142   W (ret);
19143   return ret;
19144 }
19145
19146 static int
19147 api_feature_gso_enable_disable (vat_main_t * vam)
19148 {
19149   unformat_input_t *i = vam->input;
19150   vl_api_feature_gso_enable_disable_t *mp;
19151   u32 sw_if_index = ~0;
19152   u8 enable = 1;
19153   int ret;
19154
19155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19156     {
19157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19158         ;
19159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19160         ;
19161       else if (unformat (i, "enable"))
19162         enable = 1;
19163       else if (unformat (i, "disable"))
19164         enable = 0;
19165       else
19166         break;
19167     }
19168
19169   if (sw_if_index == ~0)
19170     {
19171       errmsg ("missing interface name or sw_if_index");
19172       return -99;
19173     }
19174
19175   /* Construct the API message */
19176   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19177   mp->sw_if_index = ntohl (sw_if_index);
19178   mp->enable_disable = enable;
19179
19180   S (mp);
19181   W (ret);
19182   return ret;
19183 }
19184
19185 static int
19186 api_sw_interface_tag_add_del (vat_main_t * vam)
19187 {
19188   unformat_input_t *i = vam->input;
19189   vl_api_sw_interface_tag_add_del_t *mp;
19190   u32 sw_if_index = ~0;
19191   u8 *tag = 0;
19192   u8 enable = 1;
19193   int ret;
19194
19195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19196     {
19197       if (unformat (i, "tag %s", &tag))
19198         ;
19199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19200         ;
19201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19202         ;
19203       else if (unformat (i, "del"))
19204         enable = 0;
19205       else
19206         break;
19207     }
19208
19209   if (sw_if_index == ~0)
19210     {
19211       errmsg ("missing interface name or sw_if_index");
19212       return -99;
19213     }
19214
19215   if (enable && (tag == 0))
19216     {
19217       errmsg ("no tag specified");
19218       return -99;
19219     }
19220
19221   /* Construct the API message */
19222   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19223   mp->sw_if_index = ntohl (sw_if_index);
19224   mp->is_add = enable;
19225   if (enable)
19226     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19227   vec_free (tag);
19228
19229   S (mp);
19230   W (ret);
19231   return ret;
19232 }
19233
19234 static int
19235 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19236 {
19237   unformat_input_t *i = vam->input;
19238   vl_api_mac_address_t mac = { 0 };
19239   vl_api_sw_interface_add_del_mac_address_t *mp;
19240   u32 sw_if_index = ~0;
19241   u8 is_add = 1;
19242   u8 mac_set = 0;
19243   int ret;
19244
19245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19246     {
19247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19248         ;
19249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19250         ;
19251       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19252         mac_set++;
19253       else if (unformat (i, "del"))
19254         is_add = 0;
19255       else
19256         break;
19257     }
19258
19259   if (sw_if_index == ~0)
19260     {
19261       errmsg ("missing interface name or sw_if_index");
19262       return -99;
19263     }
19264
19265   if (!mac_set)
19266     {
19267       errmsg ("missing MAC address");
19268       return -99;
19269     }
19270
19271   /* Construct the API message */
19272   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19273   mp->sw_if_index = ntohl (sw_if_index);
19274   mp->is_add = is_add;
19275   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19276
19277   S (mp);
19278   W (ret);
19279   return ret;
19280 }
19281
19282 static void vl_api_l2_xconnect_details_t_handler
19283   (vl_api_l2_xconnect_details_t * mp)
19284 {
19285   vat_main_t *vam = &vat_main;
19286
19287   print (vam->ofp, "%15d%15d",
19288          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19289 }
19290
19291 static void vl_api_l2_xconnect_details_t_handler_json
19292   (vl_api_l2_xconnect_details_t * mp)
19293 {
19294   vat_main_t *vam = &vat_main;
19295   vat_json_node_t *node = NULL;
19296
19297   if (VAT_JSON_ARRAY != vam->json_tree.type)
19298     {
19299       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19300       vat_json_init_array (&vam->json_tree);
19301     }
19302   node = vat_json_array_add (&vam->json_tree);
19303
19304   vat_json_init_object (node);
19305   vat_json_object_add_uint (node, "rx_sw_if_index",
19306                             ntohl (mp->rx_sw_if_index));
19307   vat_json_object_add_uint (node, "tx_sw_if_index",
19308                             ntohl (mp->tx_sw_if_index));
19309 }
19310
19311 static int
19312 api_l2_xconnect_dump (vat_main_t * vam)
19313 {
19314   vl_api_l2_xconnect_dump_t *mp;
19315   vl_api_control_ping_t *mp_ping;
19316   int ret;
19317
19318   if (!vam->json_output)
19319     {
19320       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19321     }
19322
19323   M (L2_XCONNECT_DUMP, mp);
19324
19325   S (mp);
19326
19327   /* Use a control ping for synchronization */
19328   MPING (CONTROL_PING, mp_ping);
19329   S (mp_ping);
19330
19331   W (ret);
19332   return ret;
19333 }
19334
19335 static int
19336 api_hw_interface_set_mtu (vat_main_t * vam)
19337 {
19338   unformat_input_t *i = vam->input;
19339   vl_api_hw_interface_set_mtu_t *mp;
19340   u32 sw_if_index = ~0;
19341   u32 mtu = 0;
19342   int ret;
19343
19344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19345     {
19346       if (unformat (i, "mtu %d", &mtu))
19347         ;
19348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19349         ;
19350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19351         ;
19352       else
19353         break;
19354     }
19355
19356   if (sw_if_index == ~0)
19357     {
19358       errmsg ("missing interface name or sw_if_index");
19359       return -99;
19360     }
19361
19362   if (mtu == 0)
19363     {
19364       errmsg ("no mtu specified");
19365       return -99;
19366     }
19367
19368   /* Construct the API message */
19369   M (HW_INTERFACE_SET_MTU, mp);
19370   mp->sw_if_index = ntohl (sw_if_index);
19371   mp->mtu = ntohs ((u16) mtu);
19372
19373   S (mp);
19374   W (ret);
19375   return ret;
19376 }
19377
19378 static int
19379 api_p2p_ethernet_add (vat_main_t * vam)
19380 {
19381   unformat_input_t *i = vam->input;
19382   vl_api_p2p_ethernet_add_t *mp;
19383   u32 parent_if_index = ~0;
19384   u32 sub_id = ~0;
19385   u8 remote_mac[6];
19386   u8 mac_set = 0;
19387   int ret;
19388
19389   clib_memset (remote_mac, 0, sizeof (remote_mac));
19390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19391     {
19392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19393         ;
19394       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19395         ;
19396       else
19397         if (unformat
19398             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19399         mac_set++;
19400       else if (unformat (i, "sub_id %d", &sub_id))
19401         ;
19402       else
19403         {
19404           clib_warning ("parse error '%U'", format_unformat_error, i);
19405           return -99;
19406         }
19407     }
19408
19409   if (parent_if_index == ~0)
19410     {
19411       errmsg ("missing interface name or sw_if_index");
19412       return -99;
19413     }
19414   if (mac_set == 0)
19415     {
19416       errmsg ("missing remote mac address");
19417       return -99;
19418     }
19419   if (sub_id == ~0)
19420     {
19421       errmsg ("missing sub-interface id");
19422       return -99;
19423     }
19424
19425   M (P2P_ETHERNET_ADD, mp);
19426   mp->parent_if_index = ntohl (parent_if_index);
19427   mp->subif_id = ntohl (sub_id);
19428   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19429
19430   S (mp);
19431   W (ret);
19432   return ret;
19433 }
19434
19435 static int
19436 api_p2p_ethernet_del (vat_main_t * vam)
19437 {
19438   unformat_input_t *i = vam->input;
19439   vl_api_p2p_ethernet_del_t *mp;
19440   u32 parent_if_index = ~0;
19441   u8 remote_mac[6];
19442   u8 mac_set = 0;
19443   int ret;
19444
19445   clib_memset (remote_mac, 0, sizeof (remote_mac));
19446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19447     {
19448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19449         ;
19450       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19451         ;
19452       else
19453         if (unformat
19454             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19455         mac_set++;
19456       else
19457         {
19458           clib_warning ("parse error '%U'", format_unformat_error, i);
19459           return -99;
19460         }
19461     }
19462
19463   if (parent_if_index == ~0)
19464     {
19465       errmsg ("missing interface name or sw_if_index");
19466       return -99;
19467     }
19468   if (mac_set == 0)
19469     {
19470       errmsg ("missing remote mac address");
19471       return -99;
19472     }
19473
19474   M (P2P_ETHERNET_DEL, mp);
19475   mp->parent_if_index = ntohl (parent_if_index);
19476   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19477
19478   S (mp);
19479   W (ret);
19480   return ret;
19481 }
19482
19483 static int
19484 api_lldp_config (vat_main_t * vam)
19485 {
19486   unformat_input_t *i = vam->input;
19487   vl_api_lldp_config_t *mp;
19488   int tx_hold = 0;
19489   int tx_interval = 0;
19490   u8 *sys_name = NULL;
19491   int ret;
19492
19493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19494     {
19495       if (unformat (i, "system-name %s", &sys_name))
19496         ;
19497       else if (unformat (i, "tx-hold %d", &tx_hold))
19498         ;
19499       else if (unformat (i, "tx-interval %d", &tx_interval))
19500         ;
19501       else
19502         {
19503           clib_warning ("parse error '%U'", format_unformat_error, i);
19504           return -99;
19505         }
19506     }
19507
19508   vec_add1 (sys_name, 0);
19509
19510   M (LLDP_CONFIG, mp);
19511   mp->tx_hold = htonl (tx_hold);
19512   mp->tx_interval = htonl (tx_interval);
19513   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19514   vec_free (sys_name);
19515
19516   S (mp);
19517   W (ret);
19518   return ret;
19519 }
19520
19521 static int
19522 api_sw_interface_set_lldp (vat_main_t * vam)
19523 {
19524   unformat_input_t *i = vam->input;
19525   vl_api_sw_interface_set_lldp_t *mp;
19526   u32 sw_if_index = ~0;
19527   u32 enable = 1;
19528   u8 *port_desc = NULL, *mgmt_oid = NULL;
19529   ip4_address_t ip4_addr;
19530   ip6_address_t ip6_addr;
19531   int ret;
19532
19533   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19534   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19535
19536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19537     {
19538       if (unformat (i, "disable"))
19539         enable = 0;
19540       else
19541         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19542         ;
19543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19544         ;
19545       else if (unformat (i, "port-desc %s", &port_desc))
19546         ;
19547       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19548         ;
19549       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19550         ;
19551       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19552         ;
19553       else
19554         break;
19555     }
19556
19557   if (sw_if_index == ~0)
19558     {
19559       errmsg ("missing interface name or sw_if_index");
19560       return -99;
19561     }
19562
19563   /* Construct the API message */
19564   vec_add1 (port_desc, 0);
19565   vec_add1 (mgmt_oid, 0);
19566   M (SW_INTERFACE_SET_LLDP, mp);
19567   mp->sw_if_index = ntohl (sw_if_index);
19568   mp->enable = enable;
19569   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19570   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19571   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19572   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19573   vec_free (port_desc);
19574   vec_free (mgmt_oid);
19575
19576   S (mp);
19577   W (ret);
19578   return ret;
19579 }
19580
19581 static int
19582 api_tcp_configure_src_addresses (vat_main_t * vam)
19583 {
19584   vl_api_tcp_configure_src_addresses_t *mp;
19585   unformat_input_t *i = vam->input;
19586   vl_api_address_t first, last;
19587   u8 range_set = 0;
19588   u32 vrf_id = 0;
19589   int ret;
19590
19591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19592     {
19593       if (unformat (i, "%U - %U",
19594                     unformat_vl_api_address, &first,
19595                     unformat_vl_api_address, &last))
19596         {
19597           if (range_set)
19598             {
19599               errmsg ("one range per message (range already set)");
19600               return -99;
19601             }
19602           range_set = 1;
19603         }
19604       else if (unformat (i, "vrf %d", &vrf_id))
19605         ;
19606       else
19607         break;
19608     }
19609
19610   if (range_set == 0)
19611     {
19612       errmsg ("address range not set");
19613       return -99;
19614     }
19615
19616   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19617
19618   mp->vrf_id = ntohl (vrf_id);
19619   clib_memcpy (&mp->first_address, &first, sizeof (first));
19620   clib_memcpy (&mp->last_address, &last, sizeof (last));
19621
19622   S (mp);
19623   W (ret);
19624   return ret;
19625 }
19626
19627 static void vl_api_app_namespace_add_del_reply_t_handler
19628   (vl_api_app_namespace_add_del_reply_t * mp)
19629 {
19630   vat_main_t *vam = &vat_main;
19631   i32 retval = ntohl (mp->retval);
19632   if (vam->async_mode)
19633     {
19634       vam->async_errors += (retval < 0);
19635     }
19636   else
19637     {
19638       vam->retval = retval;
19639       if (retval == 0)
19640         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19641       vam->result_ready = 1;
19642     }
19643 }
19644
19645 static void vl_api_app_namespace_add_del_reply_t_handler_json
19646   (vl_api_app_namespace_add_del_reply_t * mp)
19647 {
19648   vat_main_t *vam = &vat_main;
19649   vat_json_node_t node;
19650
19651   vat_json_init_object (&node);
19652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19653   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19654
19655   vat_json_print (vam->ofp, &node);
19656   vat_json_free (&node);
19657
19658   vam->retval = ntohl (mp->retval);
19659   vam->result_ready = 1;
19660 }
19661
19662 static int
19663 api_app_namespace_add_del (vat_main_t * vam)
19664 {
19665   vl_api_app_namespace_add_del_t *mp;
19666   unformat_input_t *i = vam->input;
19667   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19668   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19669   u64 secret;
19670   int ret;
19671
19672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19673     {
19674       if (unformat (i, "id %_%v%_", &ns_id))
19675         ;
19676       else if (unformat (i, "secret %lu", &secret))
19677         secret_set = 1;
19678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19679         sw_if_index_set = 1;
19680       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19681         ;
19682       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19683         ;
19684       else
19685         break;
19686     }
19687   if (!ns_id || !secret_set || !sw_if_index_set)
19688     {
19689       errmsg ("namespace id, secret and sw_if_index must be set");
19690       return -99;
19691     }
19692   if (vec_len (ns_id) > 64)
19693     {
19694       errmsg ("namespace id too long");
19695       return -99;
19696     }
19697   M (APP_NAMESPACE_ADD_DEL, mp);
19698
19699   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19700   mp->secret = clib_host_to_net_u64 (secret);
19701   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19702   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19703   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19704   vec_free (ns_id);
19705   S (mp);
19706   W (ret);
19707   return ret;
19708 }
19709
19710 static int
19711 api_sock_init_shm (vat_main_t * vam)
19712 {
19713 #if VPP_API_TEST_BUILTIN == 0
19714   unformat_input_t *i = vam->input;
19715   vl_api_shm_elem_config_t *config = 0;
19716   u64 size = 64 << 20;
19717   int rv;
19718
19719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (i, "size %U", unformat_memory_size, &size))
19722         ;
19723       else
19724         break;
19725     }
19726
19727   /*
19728    * Canned custom ring allocator config.
19729    * Should probably parse all of this
19730    */
19731   vec_validate (config, 6);
19732   config[0].type = VL_API_VLIB_RING;
19733   config[0].size = 256;
19734   config[0].count = 32;
19735
19736   config[1].type = VL_API_VLIB_RING;
19737   config[1].size = 1024;
19738   config[1].count = 16;
19739
19740   config[2].type = VL_API_VLIB_RING;
19741   config[2].size = 4096;
19742   config[2].count = 2;
19743
19744   config[3].type = VL_API_CLIENT_RING;
19745   config[3].size = 256;
19746   config[3].count = 32;
19747
19748   config[4].type = VL_API_CLIENT_RING;
19749   config[4].size = 1024;
19750   config[4].count = 16;
19751
19752   config[5].type = VL_API_CLIENT_RING;
19753   config[5].size = 4096;
19754   config[5].count = 2;
19755
19756   config[6].type = VL_API_QUEUE;
19757   config[6].count = 128;
19758   config[6].size = sizeof (uword);
19759
19760   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19761   if (!rv)
19762     vam->client_index_invalid = 1;
19763   return rv;
19764 #else
19765   return -99;
19766 #endif
19767 }
19768
19769 static void
19770 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19771 {
19772   vat_main_t *vam = &vat_main;
19773   fib_prefix_t lcl, rmt;
19774
19775   ip_prefix_decode (&mp->lcl, &lcl);
19776   ip_prefix_decode (&mp->rmt, &rmt);
19777
19778   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19779     {
19780       print (vam->ofp,
19781              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19782              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19783              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19784              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19785              &rmt.fp_addr.ip4, rmt.fp_len,
19786              clib_net_to_host_u16 (mp->rmt_port),
19787              clib_net_to_host_u32 (mp->action_index), mp->tag);
19788     }
19789   else
19790     {
19791       print (vam->ofp,
19792              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19793              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19794              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19795              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19796              &rmt.fp_addr.ip6, rmt.fp_len,
19797              clib_net_to_host_u16 (mp->rmt_port),
19798              clib_net_to_host_u32 (mp->action_index), mp->tag);
19799     }
19800 }
19801
19802 static void
19803 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19804                                              mp)
19805 {
19806   vat_main_t *vam = &vat_main;
19807   vat_json_node_t *node = NULL;
19808   struct in6_addr ip6;
19809   struct in_addr ip4;
19810
19811   fib_prefix_t lcl, rmt;
19812
19813   ip_prefix_decode (&mp->lcl, &lcl);
19814   ip_prefix_decode (&mp->rmt, &rmt);
19815
19816   if (VAT_JSON_ARRAY != vam->json_tree.type)
19817     {
19818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19819       vat_json_init_array (&vam->json_tree);
19820     }
19821   node = vat_json_array_add (&vam->json_tree);
19822   vat_json_init_object (node);
19823
19824   vat_json_object_add_uint (node, "appns_index",
19825                             clib_net_to_host_u32 (mp->appns_index));
19826   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19827   vat_json_object_add_uint (node, "scope", mp->scope);
19828   vat_json_object_add_uint (node, "action_index",
19829                             clib_net_to_host_u32 (mp->action_index));
19830   vat_json_object_add_uint (node, "lcl_port",
19831                             clib_net_to_host_u16 (mp->lcl_port));
19832   vat_json_object_add_uint (node, "rmt_port",
19833                             clib_net_to_host_u16 (mp->rmt_port));
19834   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19835   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19836   vat_json_object_add_string_copy (node, "tag", mp->tag);
19837   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19838     {
19839       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19840       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19841       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19842       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19843     }
19844   else
19845     {
19846       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19847       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19848       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19849       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19850     }
19851 }
19852
19853 static int
19854 api_session_rule_add_del (vat_main_t * vam)
19855 {
19856   vl_api_session_rule_add_del_t *mp;
19857   unformat_input_t *i = vam->input;
19858   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19859   u32 appns_index = 0, scope = 0;
19860   ip4_address_t lcl_ip4, rmt_ip4;
19861   ip6_address_t lcl_ip6, rmt_ip6;
19862   u8 is_ip4 = 1, conn_set = 0;
19863   u8 is_add = 1, *tag = 0;
19864   int ret;
19865   fib_prefix_t lcl, rmt;
19866
19867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19868     {
19869       if (unformat (i, "del"))
19870         is_add = 0;
19871       else if (unformat (i, "add"))
19872         ;
19873       else if (unformat (i, "proto tcp"))
19874         proto = 0;
19875       else if (unformat (i, "proto udp"))
19876         proto = 1;
19877       else if (unformat (i, "appns %d", &appns_index))
19878         ;
19879       else if (unformat (i, "scope %d", &scope))
19880         ;
19881       else if (unformat (i, "tag %_%v%_", &tag))
19882         ;
19883       else
19884         if (unformat
19885             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19886              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19887              &rmt_port))
19888         {
19889           is_ip4 = 1;
19890           conn_set = 1;
19891         }
19892       else
19893         if (unformat
19894             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19895              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19896              &rmt_port))
19897         {
19898           is_ip4 = 0;
19899           conn_set = 1;
19900         }
19901       else if (unformat (i, "action %d", &action))
19902         ;
19903       else
19904         break;
19905     }
19906   if (proto == ~0 || !conn_set || action == ~0)
19907     {
19908       errmsg ("transport proto, connection and action must be set");
19909       return -99;
19910     }
19911
19912   if (scope > 3)
19913     {
19914       errmsg ("scope should be 0-3");
19915       return -99;
19916     }
19917
19918   M (SESSION_RULE_ADD_DEL, mp);
19919
19920   clib_memset (&lcl, 0, sizeof (lcl));
19921   clib_memset (&rmt, 0, sizeof (rmt));
19922   if (is_ip4)
19923     {
19924       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19925       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19926       lcl.fp_len = lcl_plen;
19927       rmt.fp_len = rmt_plen;
19928     }
19929   else
19930     {
19931       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19932       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19933       lcl.fp_len = lcl_plen;
19934       rmt.fp_len = rmt_plen;
19935     }
19936
19937
19938   ip_prefix_encode (&lcl, &mp->lcl);
19939   ip_prefix_encode (&rmt, &mp->rmt);
19940   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19941   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19942   mp->transport_proto =
19943     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19944   mp->action_index = clib_host_to_net_u32 (action);
19945   mp->appns_index = clib_host_to_net_u32 (appns_index);
19946   mp->scope = scope;
19947   mp->is_add = is_add;
19948   if (tag)
19949     {
19950       clib_memcpy (mp->tag, tag, vec_len (tag));
19951       vec_free (tag);
19952     }
19953
19954   S (mp);
19955   W (ret);
19956   return ret;
19957 }
19958
19959 static int
19960 api_session_rules_dump (vat_main_t * vam)
19961 {
19962   vl_api_session_rules_dump_t *mp;
19963   vl_api_control_ping_t *mp_ping;
19964   int ret;
19965
19966   if (!vam->json_output)
19967     {
19968       print (vam->ofp, "%=20s", "Session Rules");
19969     }
19970
19971   M (SESSION_RULES_DUMP, mp);
19972   /* send it... */
19973   S (mp);
19974
19975   /* Use a control ping for synchronization */
19976   MPING (CONTROL_PING, mp_ping);
19977   S (mp_ping);
19978
19979   /* Wait for a reply... */
19980   W (ret);
19981   return ret;
19982 }
19983
19984 static int
19985 api_ip_container_proxy_add_del (vat_main_t * vam)
19986 {
19987   vl_api_ip_container_proxy_add_del_t *mp;
19988   unformat_input_t *i = vam->input;
19989   u32 sw_if_index = ~0;
19990   vl_api_prefix_t pfx = { };
19991   u8 is_add = 1;
19992   int ret;
19993
19994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19995     {
19996       if (unformat (i, "del"))
19997         is_add = 0;
19998       else if (unformat (i, "add"))
19999         ;
20000       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20001         ;
20002       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20003         ;
20004       else
20005         break;
20006     }
20007   if (sw_if_index == ~0 || pfx.len == 0)
20008     {
20009       errmsg ("address and sw_if_index must be set");
20010       return -99;
20011     }
20012
20013   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20014
20015   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20016   mp->is_add = is_add;
20017   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20018
20019   S (mp);
20020   W (ret);
20021   return ret;
20022 }
20023
20024 static int
20025 api_qos_record_enable_disable (vat_main_t * vam)
20026 {
20027   unformat_input_t *i = vam->input;
20028   vl_api_qos_record_enable_disable_t *mp;
20029   u32 sw_if_index, qs = 0xff;
20030   u8 sw_if_index_set = 0;
20031   u8 enable = 1;
20032   int ret;
20033
20034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20035     {
20036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20037         sw_if_index_set = 1;
20038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20039         sw_if_index_set = 1;
20040       else if (unformat (i, "%U", unformat_qos_source, &qs))
20041         ;
20042       else if (unformat (i, "disable"))
20043         enable = 0;
20044       else
20045         {
20046           clib_warning ("parse error '%U'", format_unformat_error, i);
20047           return -99;
20048         }
20049     }
20050
20051   if (sw_if_index_set == 0)
20052     {
20053       errmsg ("missing interface name or sw_if_index");
20054       return -99;
20055     }
20056   if (qs == 0xff)
20057     {
20058       errmsg ("input location must be specified");
20059       return -99;
20060     }
20061
20062   M (QOS_RECORD_ENABLE_DISABLE, mp);
20063
20064   mp->record.sw_if_index = ntohl (sw_if_index);
20065   mp->record.input_source = qs;
20066   mp->enable = enable;
20067
20068   S (mp);
20069   W (ret);
20070   return ret;
20071 }
20072
20073
20074 static int
20075 q_or_quit (vat_main_t * vam)
20076 {
20077 #if VPP_API_TEST_BUILTIN == 0
20078   longjmp (vam->jump_buf, 1);
20079 #endif
20080   return 0;                     /* not so much */
20081 }
20082
20083 static int
20084 q (vat_main_t * vam)
20085 {
20086   return q_or_quit (vam);
20087 }
20088
20089 static int
20090 quit (vat_main_t * vam)
20091 {
20092   return q_or_quit (vam);
20093 }
20094
20095 static int
20096 comment (vat_main_t * vam)
20097 {
20098   return 0;
20099 }
20100
20101 static int
20102 elog_save (vat_main_t * vam)
20103 {
20104 #if VPP_API_TEST_BUILTIN == 0
20105   elog_main_t *em = &vam->elog_main;
20106   unformat_input_t *i = vam->input;
20107   char *file, *chroot_file;
20108   clib_error_t *error;
20109
20110   if (!unformat (i, "%s", &file))
20111     {
20112       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20113       return 0;
20114     }
20115
20116   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20117   if (strstr (file, "..") || index (file, '/'))
20118     {
20119       errmsg ("illegal characters in filename '%s'", file);
20120       return 0;
20121     }
20122
20123   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20124
20125   vec_free (file);
20126
20127   errmsg ("Saving %wd of %wd events to %s",
20128           elog_n_events_in_buffer (em),
20129           elog_buffer_capacity (em), chroot_file);
20130
20131   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20132   vec_free (chroot_file);
20133
20134   if (error)
20135     clib_error_report (error);
20136 #else
20137   errmsg ("Use the vpp event loger...");
20138 #endif
20139
20140   return 0;
20141 }
20142
20143 static int
20144 elog_setup (vat_main_t * vam)
20145 {
20146 #if VPP_API_TEST_BUILTIN == 0
20147   elog_main_t *em = &vam->elog_main;
20148   unformat_input_t *i = vam->input;
20149   u32 nevents = 128 << 10;
20150
20151   (void) unformat (i, "nevents %d", &nevents);
20152
20153   elog_init (em, nevents);
20154   vl_api_set_elog_main (em);
20155   vl_api_set_elog_trace_api_messages (1);
20156   errmsg ("Event logger initialized with %u events", nevents);
20157 #else
20158   errmsg ("Use the vpp event loger...");
20159 #endif
20160   return 0;
20161 }
20162
20163 static int
20164 elog_enable (vat_main_t * vam)
20165 {
20166 #if VPP_API_TEST_BUILTIN == 0
20167   elog_main_t *em = &vam->elog_main;
20168
20169   elog_enable_disable (em, 1 /* enable */ );
20170   vl_api_set_elog_trace_api_messages (1);
20171   errmsg ("Event logger enabled...");
20172 #else
20173   errmsg ("Use the vpp event loger...");
20174 #endif
20175   return 0;
20176 }
20177
20178 static int
20179 elog_disable (vat_main_t * vam)
20180 {
20181 #if VPP_API_TEST_BUILTIN == 0
20182   elog_main_t *em = &vam->elog_main;
20183
20184   elog_enable_disable (em, 0 /* enable */ );
20185   vl_api_set_elog_trace_api_messages (1);
20186   errmsg ("Event logger disabled...");
20187 #else
20188   errmsg ("Use the vpp event loger...");
20189 #endif
20190   return 0;
20191 }
20192
20193 static int
20194 statseg (vat_main_t * vam)
20195 {
20196   ssvm_private_t *ssvmp = &vam->stat_segment;
20197   ssvm_shared_header_t *shared_header = ssvmp->sh;
20198   vlib_counter_t **counters;
20199   u64 thread0_index1_packets;
20200   u64 thread0_index1_bytes;
20201   f64 vector_rate, input_rate;
20202   uword *p;
20203
20204   uword *counter_vector_by_name;
20205   if (vam->stat_segment_lockp == 0)
20206     {
20207       errmsg ("Stat segment not mapped...");
20208       return -99;
20209     }
20210
20211   /* look up "/if/rx for sw_if_index 1 as a test */
20212
20213   clib_spinlock_lock (vam->stat_segment_lockp);
20214
20215   counter_vector_by_name = (uword *) shared_header->opaque[1];
20216
20217   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20218   if (p == 0)
20219     {
20220       clib_spinlock_unlock (vam->stat_segment_lockp);
20221       errmsg ("/if/tx not found?");
20222       return -99;
20223     }
20224
20225   /* Fish per-thread vector of combined counters from shared memory */
20226   counters = (vlib_counter_t **) p[0];
20227
20228   if (vec_len (counters[0]) < 2)
20229     {
20230       clib_spinlock_unlock (vam->stat_segment_lockp);
20231       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20232       return -99;
20233     }
20234
20235   /* Read thread 0 sw_if_index 1 counter */
20236   thread0_index1_packets = counters[0][1].packets;
20237   thread0_index1_bytes = counters[0][1].bytes;
20238
20239   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20240   if (p == 0)
20241     {
20242       clib_spinlock_unlock (vam->stat_segment_lockp);
20243       errmsg ("vector_rate not found?");
20244       return -99;
20245     }
20246
20247   vector_rate = *(f64 *) (p[0]);
20248   p = hash_get_mem (counter_vector_by_name, "input_rate");
20249   if (p == 0)
20250     {
20251       clib_spinlock_unlock (vam->stat_segment_lockp);
20252       errmsg ("input_rate not found?");
20253       return -99;
20254     }
20255   input_rate = *(f64 *) (p[0]);
20256
20257   clib_spinlock_unlock (vam->stat_segment_lockp);
20258
20259   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20260          vector_rate, input_rate);
20261   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20262          thread0_index1_packets, thread0_index1_bytes);
20263
20264   return 0;
20265 }
20266
20267 static int
20268 cmd_cmp (void *a1, void *a2)
20269 {
20270   u8 **c1 = a1;
20271   u8 **c2 = a2;
20272
20273   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20274 }
20275
20276 static int
20277 help (vat_main_t * vam)
20278 {
20279   u8 **cmds = 0;
20280   u8 *name = 0;
20281   hash_pair_t *p;
20282   unformat_input_t *i = vam->input;
20283   int j;
20284
20285   if (unformat (i, "%s", &name))
20286     {
20287       uword *hs;
20288
20289       vec_add1 (name, 0);
20290
20291       hs = hash_get_mem (vam->help_by_name, name);
20292       if (hs)
20293         print (vam->ofp, "usage: %s %s", name, hs[0]);
20294       else
20295         print (vam->ofp, "No such msg / command '%s'", name);
20296       vec_free (name);
20297       return 0;
20298     }
20299
20300   print (vam->ofp, "Help is available for the following:");
20301
20302     /* *INDENT-OFF* */
20303     hash_foreach_pair (p, vam->function_by_name,
20304     ({
20305       vec_add1 (cmds, (u8 *)(p->key));
20306     }));
20307     /* *INDENT-ON* */
20308
20309   vec_sort_with_function (cmds, cmd_cmp);
20310
20311   for (j = 0; j < vec_len (cmds); j++)
20312     print (vam->ofp, "%s", cmds[j]);
20313
20314   vec_free (cmds);
20315   return 0;
20316 }
20317
20318 static int
20319 set (vat_main_t * vam)
20320 {
20321   u8 *name = 0, *value = 0;
20322   unformat_input_t *i = vam->input;
20323
20324   if (unformat (i, "%s", &name))
20325     {
20326       /* The input buffer is a vector, not a string. */
20327       value = vec_dup (i->buffer);
20328       vec_delete (value, i->index, 0);
20329       /* Almost certainly has a trailing newline */
20330       if (value[vec_len (value) - 1] == '\n')
20331         value[vec_len (value) - 1] = 0;
20332       /* Make sure it's a proper string, one way or the other */
20333       vec_add1 (value, 0);
20334       (void) clib_macro_set_value (&vam->macro_main,
20335                                    (char *) name, (char *) value);
20336     }
20337   else
20338     errmsg ("usage: set <name> <value>");
20339
20340   vec_free (name);
20341   vec_free (value);
20342   return 0;
20343 }
20344
20345 static int
20346 unset (vat_main_t * vam)
20347 {
20348   u8 *name = 0;
20349
20350   if (unformat (vam->input, "%s", &name))
20351     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20352       errmsg ("unset: %s wasn't set", name);
20353   vec_free (name);
20354   return 0;
20355 }
20356
20357 typedef struct
20358 {
20359   u8 *name;
20360   u8 *value;
20361 } macro_sort_t;
20362
20363
20364 static int
20365 macro_sort_cmp (void *a1, void *a2)
20366 {
20367   macro_sort_t *s1 = a1;
20368   macro_sort_t *s2 = a2;
20369
20370   return strcmp ((char *) (s1->name), (char *) (s2->name));
20371 }
20372
20373 static int
20374 dump_macro_table (vat_main_t * vam)
20375 {
20376   macro_sort_t *sort_me = 0, *sm;
20377   int i;
20378   hash_pair_t *p;
20379
20380     /* *INDENT-OFF* */
20381     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20382     ({
20383       vec_add2 (sort_me, sm, 1);
20384       sm->name = (u8 *)(p->key);
20385       sm->value = (u8 *) (p->value[0]);
20386     }));
20387     /* *INDENT-ON* */
20388
20389   vec_sort_with_function (sort_me, macro_sort_cmp);
20390
20391   if (vec_len (sort_me))
20392     print (vam->ofp, "%-15s%s", "Name", "Value");
20393   else
20394     print (vam->ofp, "The macro table is empty...");
20395
20396   for (i = 0; i < vec_len (sort_me); i++)
20397     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20398   return 0;
20399 }
20400
20401 static int
20402 dump_node_table (vat_main_t * vam)
20403 {
20404   int i, j;
20405   vlib_node_t *node, *next_node;
20406
20407   if (vec_len (vam->graph_nodes) == 0)
20408     {
20409       print (vam->ofp, "Node table empty, issue get_node_graph...");
20410       return 0;
20411     }
20412
20413   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20414     {
20415       node = vam->graph_nodes[0][i];
20416       print (vam->ofp, "[%d] %s", i, node->name);
20417       for (j = 0; j < vec_len (node->next_nodes); j++)
20418         {
20419           if (node->next_nodes[j] != ~0)
20420             {
20421               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20422               print (vam->ofp, "  [%d] %s", j, next_node->name);
20423             }
20424         }
20425     }
20426   return 0;
20427 }
20428
20429 static int
20430 value_sort_cmp (void *a1, void *a2)
20431 {
20432   name_sort_t *n1 = a1;
20433   name_sort_t *n2 = a2;
20434
20435   if (n1->value < n2->value)
20436     return -1;
20437   if (n1->value > n2->value)
20438     return 1;
20439   return 0;
20440 }
20441
20442
20443 static int
20444 dump_msg_api_table (vat_main_t * vam)
20445 {
20446   api_main_t *am = vlibapi_get_main ();
20447   name_sort_t *nses = 0, *ns;
20448   hash_pair_t *hp;
20449   int i;
20450
20451   /* *INDENT-OFF* */
20452   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20453   ({
20454     vec_add2 (nses, ns, 1);
20455     ns->name = (u8 *)(hp->key);
20456     ns->value = (u32) hp->value[0];
20457   }));
20458   /* *INDENT-ON* */
20459
20460   vec_sort_with_function (nses, value_sort_cmp);
20461
20462   for (i = 0; i < vec_len (nses); i++)
20463     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20464   vec_free (nses);
20465   return 0;
20466 }
20467
20468 static int
20469 get_msg_id (vat_main_t * vam)
20470 {
20471   u8 *name_and_crc;
20472   u32 message_index;
20473
20474   if (unformat (vam->input, "%s", &name_and_crc))
20475     {
20476       message_index = vl_msg_api_get_msg_index (name_and_crc);
20477       if (message_index == ~0)
20478         {
20479           print (vam->ofp, " '%s' not found", name_and_crc);
20480           return 0;
20481         }
20482       print (vam->ofp, " '%s' has message index %d",
20483              name_and_crc, message_index);
20484       return 0;
20485     }
20486   errmsg ("name_and_crc required...");
20487   return 0;
20488 }
20489
20490 static int
20491 search_node_table (vat_main_t * vam)
20492 {
20493   unformat_input_t *line_input = vam->input;
20494   u8 *node_to_find;
20495   int j;
20496   vlib_node_t *node, *next_node;
20497   uword *p;
20498
20499   if (vam->graph_node_index_by_name == 0)
20500     {
20501       print (vam->ofp, "Node table empty, issue get_node_graph...");
20502       return 0;
20503     }
20504
20505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20506     {
20507       if (unformat (line_input, "%s", &node_to_find))
20508         {
20509           vec_add1 (node_to_find, 0);
20510           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20511           if (p == 0)
20512             {
20513               print (vam->ofp, "%s not found...", node_to_find);
20514               goto out;
20515             }
20516           node = vam->graph_nodes[0][p[0]];
20517           print (vam->ofp, "[%d] %s", p[0], node->name);
20518           for (j = 0; j < vec_len (node->next_nodes); j++)
20519             {
20520               if (node->next_nodes[j] != ~0)
20521                 {
20522                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20523                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20524                 }
20525             }
20526         }
20527
20528       else
20529         {
20530           clib_warning ("parse error '%U'", format_unformat_error,
20531                         line_input);
20532           return -99;
20533         }
20534
20535     out:
20536       vec_free (node_to_find);
20537
20538     }
20539
20540   return 0;
20541 }
20542
20543
20544 static int
20545 script (vat_main_t * vam)
20546 {
20547 #if (VPP_API_TEST_BUILTIN==0)
20548   u8 *s = 0;
20549   char *save_current_file;
20550   unformat_input_t save_input;
20551   jmp_buf save_jump_buf;
20552   u32 save_line_number;
20553
20554   FILE *new_fp, *save_ifp;
20555
20556   if (unformat (vam->input, "%s", &s))
20557     {
20558       new_fp = fopen ((char *) s, "r");
20559       if (new_fp == 0)
20560         {
20561           errmsg ("Couldn't open script file %s", s);
20562           vec_free (s);
20563           return -99;
20564         }
20565     }
20566   else
20567     {
20568       errmsg ("Missing script name");
20569       return -99;
20570     }
20571
20572   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20573   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20574   save_ifp = vam->ifp;
20575   save_line_number = vam->input_line_number;
20576   save_current_file = (char *) vam->current_file;
20577
20578   vam->input_line_number = 0;
20579   vam->ifp = new_fp;
20580   vam->current_file = s;
20581   do_one_file (vam);
20582
20583   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20584   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20585   vam->ifp = save_ifp;
20586   vam->input_line_number = save_line_number;
20587   vam->current_file = (u8 *) save_current_file;
20588   vec_free (s);
20589
20590   return 0;
20591 #else
20592   clib_warning ("use the exec command...");
20593   return -99;
20594 #endif
20595 }
20596
20597 static int
20598 echo (vat_main_t * vam)
20599 {
20600   print (vam->ofp, "%v", vam->input->buffer);
20601   return 0;
20602 }
20603
20604 /* List of API message constructors, CLI names map to api_xxx */
20605 #define foreach_vpe_api_msg                                             \
20606 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20607 _(sw_interface_dump,"")                                                 \
20608 _(sw_interface_set_flags,                                               \
20609   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20610 _(sw_interface_add_del_address,                                         \
20611   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20612 _(sw_interface_set_rx_mode,                                             \
20613   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20614 _(sw_interface_set_rx_placement,                                        \
20615   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20616 _(sw_interface_rx_placement_dump,                                       \
20617   "[<intfc> | sw_if_index <id>]")                                         \
20618 _(sw_interface_set_table,                                               \
20619   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20620 _(sw_interface_set_mpls_enable,                                         \
20621   "<intfc> | sw_if_index [disable | dis]")                              \
20622 _(sw_interface_set_vpath,                                               \
20623   "<intfc> | sw_if_index <id> enable | disable")                        \
20624 _(sw_interface_set_vxlan_bypass,                                        \
20625   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20626 _(sw_interface_set_geneve_bypass,                                       \
20627   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20628 _(sw_interface_set_l2_xconnect,                                         \
20629   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20630   "enable | disable")                                                   \
20631 _(sw_interface_set_l2_bridge,                                           \
20632   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20633   "[shg <split-horizon-group>] [bvi]\n"                                 \
20634   "enable | disable")                                                   \
20635 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20636 _(bridge_domain_add_del,                                                \
20637   "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") \
20638 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20639 _(l2fib_add_del,                                                        \
20640   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20641 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20642 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20643 _(l2_flags,                                                             \
20644   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20645 _(bridge_flags,                                                         \
20646   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20647 _(tap_create_v2,                                                        \
20648   "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]") \
20649 _(tap_delete_v2,                                                        \
20650   "<vpp-if-name> | sw_if_index <id>")                                   \
20651 _(sw_interface_tap_v2_dump, "")                                         \
20652 _(virtio_pci_create,                                                    \
20653   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20654 _(virtio_pci_delete,                                                    \
20655   "<vpp-if-name> | sw_if_index <id>")                                   \
20656 _(sw_interface_virtio_pci_dump, "")                                     \
20657 _(bond_create,                                                          \
20658   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20659   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20660   "[id <if-id>]")                                                       \
20661 _(bond_delete,                                                          \
20662   "<vpp-if-name> | sw_if_index <id>")                                   \
20663 _(bond_enslave,                                                         \
20664   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20665 _(bond_detach_slave,                                                    \
20666   "sw_if_index <n>")                                                    \
20667  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20668 _(sw_interface_bond_dump, "")                                           \
20669 _(sw_interface_slave_dump,                                              \
20670   "<vpp-if-name> | sw_if_index <id>")                                   \
20671 _(ip_table_add_del,                                                     \
20672   "table <n> [ipv6] [add | del]\n")                                     \
20673 _(ip_route_add_del,                                                     \
20674   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20675   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20676   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20677   "[multipath] [count <n>] [del]")                                      \
20678 _(ip_mroute_add_del,                                                    \
20679   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20680   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20681 _(mpls_table_add_del,                                                   \
20682   "table <n> [add | del]\n")                                            \
20683 _(mpls_route_add_del,                                                   \
20684   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20685   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20686   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20687   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20688   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20689   "[count <n>] [del]")                                                  \
20690 _(mpls_ip_bind_unbind,                                                  \
20691   "<label> <addr/len>")                                                 \
20692 _(mpls_tunnel_add_del,                                                  \
20693   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20694   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20695   "[l2-only]  [out-label <n>]")                                         \
20696 _(sr_mpls_policy_add,                                                   \
20697   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20698 _(sr_mpls_policy_del,                                                   \
20699   "bsid <id>")                                                          \
20700 _(bier_table_add_del,                                                   \
20701   "<label> <sub-domain> <set> <bsl> [del]")                             \
20702 _(bier_route_add_del,                                                   \
20703   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20704   "[<intfc> | sw_if_index <id>]"                                        \
20705   "[weight <n>] [del] [multipath]")                                     \
20706 _(sw_interface_set_unnumbered,                                          \
20707   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20708 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20709 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20710   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20711   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20712   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20713 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20714 _(ip_table_flush, "table <n> [ipv6]")                                   \
20715 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20716 _(set_ip_flow_hash,                                                     \
20717   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20718 _(sw_interface_ip6_enable_disable,                                      \
20719   "<intfc> | sw_if_index <id> enable | disable")                        \
20720 _(l2_patch_add_del,                                                     \
20721   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20722   "enable | disable")                                                   \
20723 _(sr_localsid_add_del,                                                  \
20724   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20725   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20726 _(classify_add_del_table,                                               \
20727   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20728   " [del] [del-chain] mask <mask-value>\n"                              \
20729   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20730   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20731 _(classify_add_del_session,                                             \
20732   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20733   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20734   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20735   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20736 _(classify_set_interface_ip_table,                                      \
20737   "<intfc> | sw_if_index <nn> table <nn>")                              \
20738 _(classify_set_interface_l2_tables,                                     \
20739   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20740   "  [other-table <nn>]")                                               \
20741 _(get_node_index, "node <node-name")                                    \
20742 _(add_node_next, "node <node-name> next <next-node-name>")              \
20743 _(l2tpv3_create_tunnel,                                                 \
20744   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20745   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20746   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20747 _(l2tpv3_set_tunnel_cookies,                                            \
20748   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20749   "[new_remote_cookie <nn>]\n")                                         \
20750 _(l2tpv3_interface_enable_disable,                                      \
20751   "<intfc> | sw_if_index <nn> enable | disable")                        \
20752 _(l2tpv3_set_lookup_key,                                                \
20753   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20754 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20755 _(vxlan_offload_rx,                                                     \
20756   "hw { <interface name> | hw_if_index <nn>} "                          \
20757   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20758 _(vxlan_add_del_tunnel,                                                 \
20759   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20760   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20761   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20762 _(geneve_add_del_tunnel,                                                \
20763   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20764   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20765   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20766 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20767 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20768 _(gre_tunnel_add_del,                                                   \
20769   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20770   "[teb | erspan <session-id>] [del]")                                  \
20771 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20772 _(l2_fib_clear_table, "")                                               \
20773 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20774 _(l2_interface_vlan_tag_rewrite,                                        \
20775   "<intfc> | sw_if_index <nn> \n"                                       \
20776   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20777   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20778 _(create_vhost_user_if,                                                 \
20779         "socket <filename> [server] [renumber <dev_instance>] "         \
20780         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20781         "[mac <mac_address>]")                                          \
20782 _(modify_vhost_user_if,                                                 \
20783         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20784         "[server] [renumber <dev_instance>] [gso]")                     \
20785 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20786 _(sw_interface_vhost_user_dump, "")                                     \
20787 _(show_version, "")                                                     \
20788 _(show_threads, "")                                                     \
20789 _(vxlan_gpe_add_del_tunnel,                                             \
20790   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20791   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20792   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20793   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20794 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20795 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20796 _(interface_name_renumber,                                              \
20797   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20798 _(input_acl_set_interface,                                              \
20799   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20800   "  [l2-table <nn>] [del]")                                            \
20801 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20802 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20803 _(ip_dump, "ipv4 | ipv6")                                               \
20804 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20805 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20806   "  spid_id <n> ")                                                     \
20807 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20808   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20809   "  integ_alg <alg> integ_key <hex>")                                  \
20810 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20811   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20812   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20813   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20814 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20815   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20816   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20817   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20818   "  [instance <n>]")     \
20819 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20820 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20821 _(delete_loopback,"sw_if_index <nn>")                                   \
20822 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20823 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20824 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20825 _(want_interface_events,  "enable|disable")                             \
20826 _(get_first_msg_id, "client <name>")                                    \
20827 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20828 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20829   "fib-id <nn> [ip4][ip6][default]")                                    \
20830 _(get_node_graph, " ")                                                  \
20831 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20832 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20833 _(ioam_disable, "")                                                     \
20834 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20835                             " sw_if_index <sw_if_index> p <priority> "  \
20836                             "w <weight>] [del]")                        \
20837 _(one_add_del_locator, "locator-set <locator_name> "                    \
20838                         "iface <intf> | sw_if_index <sw_if_index> "     \
20839                         "p <priority> w <weight> [del]")                \
20840 _(one_add_del_local_eid,"vni <vni> eid "                                \
20841                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20842                          "locator-set <locator_name> [del]"             \
20843                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20844 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20845 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20846 _(one_enable_disable, "enable|disable")                                 \
20847 _(one_map_register_enable_disable, "enable|disable")                    \
20848 _(one_map_register_fallback_threshold, "<value>")                       \
20849 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20850 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20851                                "[seid <seid>] "                         \
20852                                "rloc <locator> p <prio> "               \
20853                                "w <weight> [rloc <loc> ... ] "          \
20854                                "action <action> [del-all]")             \
20855 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20856                           "<local-eid>")                                \
20857 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20858 _(one_use_petr, "ip-address> | disable")                                \
20859 _(one_map_request_mode, "src-dst|dst-only")                             \
20860 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20861 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20862 _(one_locator_set_dump, "[local | remote]")                             \
20863 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20864 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20865                        "[local] | [remote]")                            \
20866 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20867 _(one_ndp_bd_get, "")                                                   \
20868 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20869 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20870 _(one_l2_arp_bd_get, "")                                                \
20871 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20872 _(one_stats_enable_disable, "enable|disable")                           \
20873 _(show_one_stats_enable_disable, "")                                    \
20874 _(one_eid_table_vni_dump, "")                                           \
20875 _(one_eid_table_map_dump, "l2|l3")                                      \
20876 _(one_map_resolver_dump, "")                                            \
20877 _(one_map_server_dump, "")                                              \
20878 _(one_adjacencies_get, "vni <vni>")                                     \
20879 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20880 _(show_one_rloc_probe_state, "")                                        \
20881 _(show_one_map_register_state, "")                                      \
20882 _(show_one_status, "")                                                  \
20883 _(one_stats_dump, "")                                                   \
20884 _(one_stats_flush, "")                                                  \
20885 _(one_get_map_request_itr_rlocs, "")                                    \
20886 _(one_map_register_set_ttl, "<ttl>")                                    \
20887 _(one_set_transport_protocol, "udp|api")                                \
20888 _(one_get_transport_protocol, "")                                       \
20889 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20890 _(one_show_xtr_mode, "")                                                \
20891 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20892 _(one_show_pitr_mode, "")                                               \
20893 _(one_enable_disable_petr_mode, "enable|disable")                       \
20894 _(one_show_petr_mode, "")                                               \
20895 _(show_one_nsh_mapping, "")                                             \
20896 _(show_one_pitr, "")                                                    \
20897 _(show_one_use_petr, "")                                                \
20898 _(show_one_map_request_mode, "")                                        \
20899 _(show_one_map_register_ttl, "")                                        \
20900 _(show_one_map_register_fallback_threshold, "")                         \
20901 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20902                             " sw_if_index <sw_if_index> p <priority> "  \
20903                             "w <weight>] [del]")                        \
20904 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20905                         "iface <intf> | sw_if_index <sw_if_index> "     \
20906                         "p <priority> w <weight> [del]")                \
20907 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20908                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20909                          "locator-set <locator_name> [del]"             \
20910                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20911 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20912 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20913 _(lisp_enable_disable, "enable|disable")                                \
20914 _(lisp_map_register_enable_disable, "enable|disable")                   \
20915 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20916 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20917                                "[seid <seid>] "                         \
20918                                "rloc <locator> p <prio> "               \
20919                                "w <weight> [rloc <loc> ... ] "          \
20920                                "action <action> [del-all]")             \
20921 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20922                           "<local-eid>")                                \
20923 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20924 _(lisp_use_petr, "<ip-address> | disable")                              \
20925 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20926 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20927 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20928 _(lisp_locator_set_dump, "[local | remote]")                            \
20929 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20930 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20931                        "[local] | [remote]")                            \
20932 _(lisp_eid_table_vni_dump, "")                                          \
20933 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20934 _(lisp_map_resolver_dump, "")                                           \
20935 _(lisp_map_server_dump, "")                                             \
20936 _(lisp_adjacencies_get, "vni <vni>")                                    \
20937 _(gpe_fwd_entry_vnis_get, "")                                           \
20938 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20939 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20940                                 "[table <table-id>]")                   \
20941 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20942 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20943 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20944 _(gpe_get_encap_mode, "")                                               \
20945 _(lisp_gpe_add_del_iface, "up|down")                                    \
20946 _(lisp_gpe_enable_disable, "enable|disable")                            \
20947 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20948   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20949 _(show_lisp_rloc_probe_state, "")                                       \
20950 _(show_lisp_map_register_state, "")                                     \
20951 _(show_lisp_status, "")                                                 \
20952 _(lisp_get_map_request_itr_rlocs, "")                                   \
20953 _(show_lisp_pitr, "")                                                   \
20954 _(show_lisp_use_petr, "")                                               \
20955 _(show_lisp_map_request_mode, "")                                       \
20956 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20957 _(af_packet_delete, "name <host interface name>")                       \
20958 _(af_packet_dump, "")                                                   \
20959 _(policer_add_del, "name <policer name> <params> [del]")                \
20960 _(policer_dump, "[name <policer name>]")                                \
20961 _(policer_classify_set_interface,                                       \
20962   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20963   "  [l2-table <nn>] [del]")                                            \
20964 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20965 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20966 _(mpls_table_dump, "")                                                  \
20967 _(mpls_route_dump, "table-id <ID>")                                     \
20968 _(classify_table_ids, "")                                               \
20969 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20970 _(classify_table_info, "table_id <nn>")                                 \
20971 _(classify_session_dump, "table_id <nn>")                               \
20972 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20973     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20974     "[template_interval <nn>] [udp_checksum]")                          \
20975 _(ipfix_exporter_dump, "")                                              \
20976 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20977 _(ipfix_classify_stream_dump, "")                                       \
20978 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20979 _(ipfix_classify_table_dump, "")                                        \
20980 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20981 _(sw_interface_span_dump, "[l2]")                                           \
20982 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20983 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20984 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20985 _(pg_enable_disable, "[stream <id>] disable")                           \
20986 _(ip_source_and_port_range_check_add_del,                               \
20987   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20988 _(ip_source_and_port_range_check_interface_add_del,                     \
20989   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20990   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20991 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20992 _(l2_interface_pbb_tag_rewrite,                                         \
20993   "<intfc> | sw_if_index <nn> \n"                                       \
20994   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20995   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20996 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20997 _(flow_classify_set_interface,                                          \
20998   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20999 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21000 _(ip_table_dump, "")                                                    \
21001 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21002 _(ip_mtable_dump, "")                                                   \
21003 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21004 _(feature_enable_disable, "arc_name <arc_name> "                        \
21005   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21006 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21007   "[enable | disable] ")                                                \
21008 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21009 "[disable]")                                                            \
21010 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21011   "mac <mac-address> [del]")                                            \
21012 _(l2_xconnect_dump, "")                                                 \
21013 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21014 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21015 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21016 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21017 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21018 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21019   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21020 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21021 _(sock_init_shm, "size <nnn>")                                          \
21022 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21023 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21024   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21025 _(session_rules_dump, "")                                               \
21026 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21027 _(output_acl_set_interface,                                             \
21028   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21029   "  [l2-table <nn>] [del]")                                            \
21030 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21031
21032 /* List of command functions, CLI names map directly to functions */
21033 #define foreach_cli_function                                    \
21034 _(comment, "usage: comment <ignore-rest-of-line>")              \
21035 _(dump_interface_table, "usage: dump_interface_table")          \
21036 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21037 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21038 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21039 _(dump_macro_table, "usage: dump_macro_table ")                 \
21040 _(dump_node_table, "usage: dump_node_table")                    \
21041 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21042 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21043 _(elog_disable, "usage: elog_disable")                          \
21044 _(elog_enable, "usage: elog_enable")                            \
21045 _(elog_save, "usage: elog_save <filename>")                     \
21046 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21047 _(echo, "usage: echo <message>")                                \
21048 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21049 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21050 _(help, "usage: help")                                          \
21051 _(q, "usage: quit")                                             \
21052 _(quit, "usage: quit")                                          \
21053 _(search_node_table, "usage: search_node_table <name>...")      \
21054 _(set, "usage: set <variable-name> <value>")                    \
21055 _(script, "usage: script <file-name>")                          \
21056 _(statseg, "usage: statseg")                                    \
21057 _(unset, "usage: unset <variable-name>")
21058
21059 #define _(N,n)                                  \
21060     static void vl_api_##n##_t_handler_uni      \
21061     (vl_api_##n##_t * mp)                       \
21062     {                                           \
21063         vat_main_t * vam = &vat_main;           \
21064         if (vam->json_output) {                 \
21065             vl_api_##n##_t_handler_json(mp);    \
21066         } else {                                \
21067             vl_api_##n##_t_handler(mp);         \
21068         }                                       \
21069     }
21070 foreach_vpe_api_reply_msg;
21071 #if VPP_API_TEST_BUILTIN == 0
21072 foreach_standalone_reply_msg;
21073 #endif
21074 #undef _
21075
21076 void
21077 vat_api_hookup (vat_main_t * vam)
21078 {
21079 #define _(N,n)                                                  \
21080     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21081                            vl_api_##n##_t_handler_uni,          \
21082                            vl_noop_handler,                     \
21083                            vl_api_##n##_t_endian,               \
21084                            vl_api_##n##_t_print,                \
21085                            sizeof(vl_api_##n##_t), 1);
21086   foreach_vpe_api_reply_msg;
21087 #if VPP_API_TEST_BUILTIN == 0
21088   foreach_standalone_reply_msg;
21089 #endif
21090 #undef _
21091
21092 #if (VPP_API_TEST_BUILTIN==0)
21093   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21094
21095   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21096
21097   vam->function_by_name = hash_create_string (0, sizeof (uword));
21098
21099   vam->help_by_name = hash_create_string (0, sizeof (uword));
21100 #endif
21101
21102   /* API messages we can send */
21103 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21104   foreach_vpe_api_msg;
21105 #undef _
21106
21107   /* Help strings */
21108 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21109   foreach_vpe_api_msg;
21110 #undef _
21111
21112   /* CLI functions */
21113 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21114   foreach_cli_function;
21115 #undef _
21116
21117   /* Help strings */
21118 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21119   foreach_cli_function;
21120 #undef _
21121 }
21122
21123 #if VPP_API_TEST_BUILTIN
21124 static clib_error_t *
21125 vat_api_hookup_shim (vlib_main_t * vm)
21126 {
21127   vat_api_hookup (&vat_main);
21128   return 0;
21129 }
21130
21131 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21132 #endif
21133
21134 /*
21135  * fd.io coding-style-patch-verification: ON
21136  *
21137  * Local Variables:
21138  * eval: (c-set-style "gnu")
21139  * End:
21140  */