a98e2ed873dca3050e38a1a2d81c6efa2abf253e
[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_MARK_AND_TRANSMIT)
4559     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4560   else
4561     conform_dscp_str = format (0, "");
4562
4563   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4564     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4565   else
4566     exceed_dscp_str = format (0, "");
4567
4568   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4569     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_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_MARK_AND_TRANSMIT)
4662     {
4663       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_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_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_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_MARK_AND_TRANSMIT)
4677     {
4678       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4679       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4680       vec_free (dscp_str);
4681     }
4682
4683   vec_free (rate_type_str);
4684   vec_free (round_type_str);
4685   vec_free (type_str);
4686   vec_free (conform_action_str);
4687   vec_free (exceed_action_str);
4688   vec_free (violate_action_str);
4689 }
4690
4691 static void
4692 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4693                                            mp)
4694 {
4695   vat_main_t *vam = &vat_main;
4696   int i, count = ntohl (mp->count);
4697
4698   if (count > 0)
4699     print (vam->ofp, "classify table ids (%d) : ", count);
4700   for (i = 0; i < count; i++)
4701     {
4702       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4703       print (vam->ofp, (i < count - 1) ? "," : "");
4704     }
4705   vam->retval = ntohl (mp->retval);
4706   vam->result_ready = 1;
4707 }
4708
4709 static void
4710   vl_api_classify_table_ids_reply_t_handler_json
4711   (vl_api_classify_table_ids_reply_t * mp)
4712 {
4713   vat_main_t *vam = &vat_main;
4714   int i, count = ntohl (mp->count);
4715
4716   if (count > 0)
4717     {
4718       vat_json_node_t node;
4719
4720       vat_json_init_object (&node);
4721       for (i = 0; i < count; i++)
4722         {
4723           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4724         }
4725       vat_json_print (vam->ofp, &node);
4726       vat_json_free (&node);
4727     }
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   u32 table_id;
4738
4739   table_id = ntohl (mp->l2_table_id);
4740   if (table_id != ~0)
4741     print (vam->ofp, "l2 table id : %d", table_id);
4742   else
4743     print (vam->ofp, "l2 table id : No input ACL tables configured");
4744   table_id = ntohl (mp->ip4_table_id);
4745   if (table_id != ~0)
4746     print (vam->ofp, "ip4 table id : %d", table_id);
4747   else
4748     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4749   table_id = ntohl (mp->ip6_table_id);
4750   if (table_id != ~0)
4751     print (vam->ofp, "ip6 table id : %d", table_id);
4752   else
4753     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4754   vam->retval = ntohl (mp->retval);
4755   vam->result_ready = 1;
4756 }
4757
4758 static void
4759   vl_api_classify_table_by_interface_reply_t_handler_json
4760   (vl_api_classify_table_by_interface_reply_t * mp)
4761 {
4762   vat_main_t *vam = &vat_main;
4763   vat_json_node_t node;
4764
4765   vat_json_init_object (&node);
4766
4767   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4768   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4769   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4770
4771   vat_json_print (vam->ofp, &node);
4772   vat_json_free (&node);
4773
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static void vl_api_policer_add_del_reply_t_handler
4779   (vl_api_policer_add_del_reply_t * mp)
4780 {
4781   vat_main_t *vam = &vat_main;
4782   i32 retval = ntohl (mp->retval);
4783   if (vam->async_mode)
4784     {
4785       vam->async_errors += (retval < 0);
4786     }
4787   else
4788     {
4789       vam->retval = retval;
4790       vam->result_ready = 1;
4791       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4792         /*
4793          * Note: this is just barely thread-safe, depends on
4794          * the main thread spinning waiting for an answer...
4795          */
4796         errmsg ("policer index %d", ntohl (mp->policer_index));
4797     }
4798 }
4799
4800 static void vl_api_policer_add_del_reply_t_handler_json
4801   (vl_api_policer_add_del_reply_t * mp)
4802 {
4803   vat_main_t *vam = &vat_main;
4804   vat_json_node_t node;
4805
4806   vat_json_init_object (&node);
4807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4808   vat_json_object_add_uint (&node, "policer_index",
4809                             ntohl (mp->policer_index));
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 /* Format hex dump. */
4819 u8 *
4820 format_hex_bytes (u8 * s, va_list * va)
4821 {
4822   u8 *bytes = va_arg (*va, u8 *);
4823   int n_bytes = va_arg (*va, int);
4824   uword i;
4825
4826   /* Print short or long form depending on byte count. */
4827   uword short_form = n_bytes <= 32;
4828   u32 indent = format_get_indent (s);
4829
4830   if (n_bytes == 0)
4831     return s;
4832
4833   for (i = 0; i < n_bytes; i++)
4834     {
4835       if (!short_form && (i % 32) == 0)
4836         s = format (s, "%08x: ", i);
4837       s = format (s, "%02x", bytes[i]);
4838       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4839         s = format (s, "\n%U", format_white_space, indent);
4840     }
4841
4842   return s;
4843 }
4844
4845 static void
4846 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4847                                             * mp)
4848 {
4849   vat_main_t *vam = &vat_main;
4850   i32 retval = ntohl (mp->retval);
4851   if (retval == 0)
4852     {
4853       print (vam->ofp, "classify table info :");
4854       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4855              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4856              ntohl (mp->miss_next_index));
4857       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4858              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4859              ntohl (mp->match_n_vectors));
4860       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4861              ntohl (mp->mask_length));
4862     }
4863   vam->retval = retval;
4864   vam->result_ready = 1;
4865 }
4866
4867 static void
4868   vl_api_classify_table_info_reply_t_handler_json
4869   (vl_api_classify_table_info_reply_t * mp)
4870 {
4871   vat_main_t *vam = &vat_main;
4872   vat_json_node_t node;
4873
4874   i32 retval = ntohl (mp->retval);
4875   if (retval == 0)
4876     {
4877       vat_json_init_object (&node);
4878
4879       vat_json_object_add_int (&node, "sessions",
4880                                ntohl (mp->active_sessions));
4881       vat_json_object_add_int (&node, "nexttbl",
4882                                ntohl (mp->next_table_index));
4883       vat_json_object_add_int (&node, "nextnode",
4884                                ntohl (mp->miss_next_index));
4885       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4886       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4887       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4888       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4889                       ntohl (mp->mask_length), 0);
4890       vat_json_object_add_string_copy (&node, "mask", s);
4891
4892       vat_json_print (vam->ofp, &node);
4893       vat_json_free (&node);
4894     }
4895   vam->retval = ntohl (mp->retval);
4896   vam->result_ready = 1;
4897 }
4898
4899 static void
4900 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4901                                            mp)
4902 {
4903   vat_main_t *vam = &vat_main;
4904
4905   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4906          ntohl (mp->hit_next_index), ntohl (mp->advance),
4907          ntohl (mp->opaque_index));
4908   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4909          ntohl (mp->match_length));
4910 }
4911
4912 static void
4913   vl_api_classify_session_details_t_handler_json
4914   (vl_api_classify_session_details_t * mp)
4915 {
4916   vat_main_t *vam = &vat_main;
4917   vat_json_node_t *node = NULL;
4918
4919   if (VAT_JSON_ARRAY != vam->json_tree.type)
4920     {
4921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4922       vat_json_init_array (&vam->json_tree);
4923     }
4924   node = vat_json_array_add (&vam->json_tree);
4925
4926   vat_json_init_object (node);
4927   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4928   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4929   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4930   u8 *s =
4931     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4932             0);
4933   vat_json_object_add_string_copy (node, "match", s);
4934 }
4935
4936 static void vl_api_pg_create_interface_reply_t_handler
4937   (vl_api_pg_create_interface_reply_t * mp)
4938 {
4939   vat_main_t *vam = &vat_main;
4940
4941   vam->retval = ntohl (mp->retval);
4942   vam->result_ready = 1;
4943 }
4944
4945 static void vl_api_pg_create_interface_reply_t_handler_json
4946   (vl_api_pg_create_interface_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       vat_json_init_object (&node);
4955
4956       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4957
4958       vat_json_print (vam->ofp, &node);
4959       vat_json_free (&node);
4960     }
4961   vam->retval = ntohl (mp->retval);
4962   vam->result_ready = 1;
4963 }
4964
4965 static void vl_api_policer_classify_details_t_handler
4966   (vl_api_policer_classify_details_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969
4970   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4971          ntohl (mp->table_index));
4972 }
4973
4974 static void vl_api_policer_classify_details_t_handler_json
4975   (vl_api_policer_classify_details_t * mp)
4976 {
4977   vat_main_t *vam = &vat_main;
4978   vat_json_node_t *node;
4979
4980   if (VAT_JSON_ARRAY != vam->json_tree.type)
4981     {
4982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4983       vat_json_init_array (&vam->json_tree);
4984     }
4985   node = vat_json_array_add (&vam->json_tree);
4986
4987   vat_json_init_object (node);
4988   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4989   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4990 }
4991
4992 static void vl_api_flow_classify_details_t_handler
4993   (vl_api_flow_classify_details_t * mp)
4994 {
4995   vat_main_t *vam = &vat_main;
4996
4997   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4998          ntohl (mp->table_index));
4999 }
5000
5001 static void vl_api_flow_classify_details_t_handler_json
5002   (vl_api_flow_classify_details_t * mp)
5003 {
5004   vat_main_t *vam = &vat_main;
5005   vat_json_node_t *node;
5006
5007   if (VAT_JSON_ARRAY != vam->json_tree.type)
5008     {
5009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5010       vat_json_init_array (&vam->json_tree);
5011     }
5012   node = vat_json_array_add (&vam->json_tree);
5013
5014   vat_json_init_object (node);
5015   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5016   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5017 }
5018
5019 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5020 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5022 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5023 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5024 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5025 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5029
5030 /*
5031  * Generate boilerplate reply handlers, which
5032  * dig the return value out of the xxx_reply_t API message,
5033  * stick it into vam->retval, and set vam->result_ready
5034  *
5035  * Could also do this by pointing N message decode slots at
5036  * a single function, but that could break in subtle ways.
5037  */
5038
5039 #define foreach_standard_reply_retval_handler           \
5040 _(sw_interface_set_flags_reply)                         \
5041 _(sw_interface_add_del_address_reply)                   \
5042 _(sw_interface_set_rx_mode_reply)                       \
5043 _(sw_interface_set_rx_placement_reply)                  \
5044 _(sw_interface_set_table_reply)                         \
5045 _(sw_interface_set_mpls_enable_reply)                   \
5046 _(sw_interface_set_vpath_reply)                         \
5047 _(sw_interface_set_vxlan_bypass_reply)                  \
5048 _(sw_interface_set_geneve_bypass_reply)                 \
5049 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5050 _(sw_interface_set_l2_bridge_reply)                     \
5051 _(sw_interface_set_bond_weight_reply)                   \
5052 _(bridge_domain_add_del_reply)                          \
5053 _(sw_interface_set_l2_xconnect_reply)                   \
5054 _(l2fib_add_del_reply)                                  \
5055 _(l2fib_flush_int_reply)                                \
5056 _(l2fib_flush_bd_reply)                                 \
5057 _(ip_route_add_del_reply)                               \
5058 _(ip_table_add_del_reply)                               \
5059 _(ip_table_replace_begin_reply)                         \
5060 _(ip_table_flush_reply)                                 \
5061 _(ip_table_replace_end_reply)                           \
5062 _(ip_mroute_add_del_reply)                              \
5063 _(mpls_route_add_del_reply)                             \
5064 _(mpls_table_add_del_reply)                             \
5065 _(mpls_ip_bind_unbind_reply)                            \
5066 _(bier_route_add_del_reply)                             \
5067 _(bier_table_add_del_reply)                             \
5068 _(sw_interface_set_unnumbered_reply)                    \
5069 _(set_ip_flow_hash_reply)                               \
5070 _(sw_interface_ip6_enable_disable_reply)                \
5071 _(l2_patch_add_del_reply)                               \
5072 _(sr_mpls_policy_add_reply)                             \
5073 _(sr_mpls_policy_mod_reply)                             \
5074 _(sr_mpls_policy_del_reply)                             \
5075 _(sr_policy_add_reply)                                  \
5076 _(sr_policy_mod_reply)                                  \
5077 _(sr_policy_del_reply)                                  \
5078 _(sr_localsid_add_del_reply)                            \
5079 _(sr_steering_add_del_reply)                            \
5080 _(classify_add_del_session_reply)                       \
5081 _(classify_set_interface_ip_table_reply)                \
5082 _(classify_set_interface_l2_tables_reply)               \
5083 _(l2tpv3_set_tunnel_cookies_reply)                      \
5084 _(l2tpv3_interface_enable_disable_reply)                \
5085 _(l2tpv3_set_lookup_key_reply)                          \
5086 _(l2_fib_clear_table_reply)                             \
5087 _(l2_interface_efp_filter_reply)                        \
5088 _(l2_interface_vlan_tag_rewrite_reply)                  \
5089 _(modify_vhost_user_if_reply)                           \
5090 _(delete_vhost_user_if_reply)                           \
5091 _(want_l2_macs_events_reply)                            \
5092 _(input_acl_set_interface_reply)                        \
5093 _(ipsec_spd_add_del_reply)                              \
5094 _(ipsec_interface_add_del_spd_reply)                    \
5095 _(ipsec_spd_entry_add_del_reply)                        \
5096 _(ipsec_sad_entry_add_del_reply)                        \
5097 _(ipsec_tunnel_if_add_del_reply)                        \
5098 _(ipsec_tunnel_if_set_sa_reply)                         \
5099 _(delete_loopback_reply)                                \
5100 _(bd_ip_mac_add_del_reply)                              \
5101 _(bd_ip_mac_flush_reply)                                \
5102 _(want_interface_events_reply)                          \
5103 _(cop_interface_enable_disable_reply)                   \
5104 _(cop_whitelist_enable_disable_reply)                   \
5105 _(sw_interface_clear_stats_reply)                       \
5106 _(ioam_enable_reply)                                    \
5107 _(ioam_disable_reply)                                   \
5108 _(one_add_del_locator_reply)                            \
5109 _(one_add_del_local_eid_reply)                          \
5110 _(one_add_del_remote_mapping_reply)                     \
5111 _(one_add_del_adjacency_reply)                          \
5112 _(one_add_del_map_resolver_reply)                       \
5113 _(one_add_del_map_server_reply)                         \
5114 _(one_enable_disable_reply)                             \
5115 _(one_rloc_probe_enable_disable_reply)                  \
5116 _(one_map_register_enable_disable_reply)                \
5117 _(one_map_register_set_ttl_reply)                       \
5118 _(one_set_transport_protocol_reply)                     \
5119 _(one_map_register_fallback_threshold_reply)            \
5120 _(one_pitr_set_locator_set_reply)                       \
5121 _(one_map_request_mode_reply)                           \
5122 _(one_add_del_map_request_itr_rlocs_reply)              \
5123 _(one_eid_table_add_del_map_reply)                      \
5124 _(one_use_petr_reply)                                   \
5125 _(one_stats_enable_disable_reply)                       \
5126 _(one_add_del_l2_arp_entry_reply)                       \
5127 _(one_add_del_ndp_entry_reply)                          \
5128 _(one_stats_flush_reply)                                \
5129 _(one_enable_disable_xtr_mode_reply)                    \
5130 _(one_enable_disable_pitr_mode_reply)                   \
5131 _(one_enable_disable_petr_mode_reply)                   \
5132 _(gpe_enable_disable_reply)                             \
5133 _(gpe_set_encap_mode_reply)                             \
5134 _(gpe_add_del_iface_reply)                              \
5135 _(gpe_add_del_native_fwd_rpath_reply)                   \
5136 _(af_packet_delete_reply)                               \
5137 _(policer_classify_set_interface_reply)                 \
5138 _(set_ipfix_exporter_reply)                             \
5139 _(set_ipfix_classify_stream_reply)                      \
5140 _(ipfix_classify_table_add_del_reply)                   \
5141 _(flow_classify_set_interface_reply)                    \
5142 _(sw_interface_span_enable_disable_reply)               \
5143 _(pg_capture_reply)                                     \
5144 _(pg_enable_disable_reply)                              \
5145 _(ip_source_and_port_range_check_add_del_reply)         \
5146 _(ip_source_and_port_range_check_interface_add_del_reply)\
5147 _(delete_subif_reply)                                   \
5148 _(l2_interface_pbb_tag_rewrite_reply)                   \
5149 _(set_punt_reply)                                       \
5150 _(feature_enable_disable_reply)                         \
5151 _(feature_gso_enable_disable_reply)                     \
5152 _(sw_interface_tag_add_del_reply)                       \
5153 _(sw_interface_add_del_mac_address_reply)               \
5154 _(hw_interface_set_mtu_reply)                           \
5155 _(p2p_ethernet_add_reply)                               \
5156 _(p2p_ethernet_del_reply)                               \
5157 _(lldp_config_reply)                                    \
5158 _(sw_interface_set_lldp_reply)                          \
5159 _(tcp_configure_src_addresses_reply)                    \
5160 _(session_rule_add_del_reply)                           \
5161 _(ip_container_proxy_add_del_reply)                     \
5162 _(output_acl_set_interface_reply)                       \
5163 _(qos_record_enable_disable_reply)
5164
5165 #define _(n)                                    \
5166     static void vl_api_##n##_t_handler          \
5167     (vl_api_##n##_t * mp)                       \
5168     {                                           \
5169         vat_main_t * vam = &vat_main;           \
5170         i32 retval = ntohl(mp->retval);         \
5171         if (vam->async_mode) {                  \
5172             vam->async_errors += (retval < 0);  \
5173         } else {                                \
5174             vam->retval = retval;               \
5175             vam->result_ready = 1;              \
5176         }                                       \
5177     }
5178 foreach_standard_reply_retval_handler;
5179 #undef _
5180
5181 #define _(n)                                    \
5182     static void vl_api_##n##_t_handler_json     \
5183     (vl_api_##n##_t * mp)                       \
5184     {                                           \
5185         vat_main_t * vam = &vat_main;           \
5186         vat_json_node_t node;                   \
5187         vat_json_init_object(&node);            \
5188         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5189         vat_json_print(vam->ofp, &node);        \
5190         vam->retval = ntohl(mp->retval);        \
5191         vam->result_ready = 1;                  \
5192     }
5193 foreach_standard_reply_retval_handler;
5194 #undef _
5195
5196 /*
5197  * Table of message reply handlers, must include boilerplate handlers
5198  * we just generated
5199  */
5200
5201 #define foreach_vpe_api_reply_msg                                       \
5202 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5203 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5204 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5205 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5206 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5207 _(CLI_REPLY, cli_reply)                                                 \
5208 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5209 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5210   sw_interface_add_del_address_reply)                                   \
5211 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5212 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5213 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5214 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5215 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5216 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5217 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5218 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5219 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5220 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5221   sw_interface_set_l2_xconnect_reply)                                   \
5222 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5223   sw_interface_set_l2_bridge_reply)                                     \
5224 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5225 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5226 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5227 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5228 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5229 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5230 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5231 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5232 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5233 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5234 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5235 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5236 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5237 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5238 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5239 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5240 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5241 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5242 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5243 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5244 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5245 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5246 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5247 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5248 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5249 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5250 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5251 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5252 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5253 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5254 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5255 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5256 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5257 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5258   sw_interface_set_unnumbered_reply)                                    \
5259 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5260 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5261 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5262 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5263   sw_interface_ip6_enable_disable_reply)                                \
5264 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5265 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5266 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5267 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5268 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5269 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5270 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5271 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5272 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5273 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5274 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5275 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5276 classify_set_interface_ip_table_reply)                                  \
5277 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5278   classify_set_interface_l2_tables_reply)                               \
5279 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5280 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5281 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5282 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5283 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5284   l2tpv3_interface_enable_disable_reply)                                \
5285 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5286 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5287 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5288 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5289 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5290 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5291 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5292 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5293 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5294 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5295 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5296 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5297 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5298 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5299 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5300 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5301 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5302 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5303 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5304 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5305 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5306 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5307 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5308 _(L2_MACS_EVENT, l2_macs_event)                                         \
5309 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5310 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5311 _(IP_DETAILS, ip_details)                                               \
5312 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5313 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5314 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5315 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5316 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5317 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5318 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5319 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5320 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5321 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5322 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5323 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5324 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5325 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5326 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5327 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5328 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5329 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5330 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5331 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5332 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5333 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5334 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5335 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5336 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5337 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5338 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5339 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5340   one_map_register_enable_disable_reply)                                \
5341 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5342 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5343 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5344 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5345   one_map_register_fallback_threshold_reply)                            \
5346 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5347   one_rloc_probe_enable_disable_reply)                                  \
5348 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5349 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5350 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5351 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5352 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5353 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5354 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5355 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5356 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5357 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5358 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5359 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5360 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5361 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5362 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5363 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5364   show_one_stats_enable_disable_reply)                                  \
5365 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5366 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5367 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5368 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5369 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5370 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5371 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5372 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5373   one_enable_disable_pitr_mode_reply)                                   \
5374 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5375   one_enable_disable_petr_mode_reply)                                   \
5376 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5377 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5378 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5379 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5380 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5381 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5382 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5383 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5384 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5385 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5386 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5387 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5388   gpe_add_del_native_fwd_rpath_reply)                                   \
5389 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5390   gpe_fwd_entry_path_details)                                           \
5391 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5392 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5393   one_add_del_map_request_itr_rlocs_reply)                              \
5394 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5395   one_get_map_request_itr_rlocs_reply)                                  \
5396 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5397 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5398 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5399 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5400 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5401 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5402   show_one_map_register_state_reply)                                    \
5403 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5404 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5405   show_one_map_register_fallback_threshold_reply)                       \
5406 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5407 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5408 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5409 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5410 _(POLICER_DETAILS, policer_details)                                     \
5411 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5412 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5413 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5414 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5415 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5416 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5417 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5418 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5419 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5420 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5421 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5422 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5423 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5424 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5425 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5426 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5427 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5428 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5429 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5430 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5431 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5432 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5433 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5434 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5435  ip_source_and_port_range_check_add_del_reply)                          \
5436 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5437  ip_source_and_port_range_check_interface_add_del_reply)                \
5438 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5439 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5440 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5441 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5442 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5443 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5444 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5445 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5446 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5447 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5448 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5449 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5450 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5451 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5452 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5453 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5454 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5455 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5456 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5457 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5458 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5459 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5460 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5461
5462 #define foreach_standalone_reply_msg                                    \
5463 _(SW_INTERFACE_EVENT, sw_interface_event)
5464
5465 typedef struct
5466 {
5467   u8 *name;
5468   u32 value;
5469 } name_sort_t;
5470
5471 #define STR_VTR_OP_CASE(op)     \
5472     case L2_VTR_ ## op:         \
5473         return "" # op;
5474
5475 static const char *
5476 str_vtr_op (u32 vtr_op)
5477 {
5478   switch (vtr_op)
5479     {
5480       STR_VTR_OP_CASE (DISABLED);
5481       STR_VTR_OP_CASE (PUSH_1);
5482       STR_VTR_OP_CASE (PUSH_2);
5483       STR_VTR_OP_CASE (POP_1);
5484       STR_VTR_OP_CASE (POP_2);
5485       STR_VTR_OP_CASE (TRANSLATE_1_1);
5486       STR_VTR_OP_CASE (TRANSLATE_1_2);
5487       STR_VTR_OP_CASE (TRANSLATE_2_1);
5488       STR_VTR_OP_CASE (TRANSLATE_2_2);
5489     }
5490
5491   return "UNKNOWN";
5492 }
5493
5494 static int
5495 dump_sub_interface_table (vat_main_t * vam)
5496 {
5497   const sw_interface_subif_t *sub = NULL;
5498
5499   if (vam->json_output)
5500     {
5501       clib_warning
5502         ("JSON output supported only for VPE API calls and dump_stats_table");
5503       return -99;
5504     }
5505
5506   print (vam->ofp,
5507          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5508          "Interface", "sw_if_index",
5509          "sub id", "dot1ad", "tags", "outer id",
5510          "inner id", "exact", "default", "outer any", "inner any");
5511
5512   vec_foreach (sub, vam->sw_if_subif_table)
5513   {
5514     print (vam->ofp,
5515            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5516            sub->interface_name,
5517            sub->sw_if_index,
5518            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5519            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5520            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5521            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5522     if (sub->vtr_op != L2_VTR_DISABLED)
5523       {
5524         print (vam->ofp,
5525                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5526                "tag1: %d tag2: %d ]",
5527                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5528                sub->vtr_tag1, sub->vtr_tag2);
5529       }
5530   }
5531
5532   return 0;
5533 }
5534
5535 static int
5536 name_sort_cmp (void *a1, void *a2)
5537 {
5538   name_sort_t *n1 = a1;
5539   name_sort_t *n2 = a2;
5540
5541   return strcmp ((char *) n1->name, (char *) n2->name);
5542 }
5543
5544 static int
5545 dump_interface_table (vat_main_t * vam)
5546 {
5547   hash_pair_t *p;
5548   name_sort_t *nses = 0, *ns;
5549
5550   if (vam->json_output)
5551     {
5552       clib_warning
5553         ("JSON output supported only for VPE API calls and dump_stats_table");
5554       return -99;
5555     }
5556
5557   /* *INDENT-OFF* */
5558   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5559   ({
5560     vec_add2 (nses, ns, 1);
5561     ns->name = (u8 *)(p->key);
5562     ns->value = (u32) p->value[0];
5563   }));
5564   /* *INDENT-ON* */
5565
5566   vec_sort_with_function (nses, name_sort_cmp);
5567
5568   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5569   vec_foreach (ns, nses)
5570   {
5571     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5572   }
5573   vec_free (nses);
5574   return 0;
5575 }
5576
5577 static int
5578 dump_ip_table (vat_main_t * vam, int is_ipv6)
5579 {
5580   const ip_details_t *det = NULL;
5581   const ip_address_details_t *address = NULL;
5582   u32 i = ~0;
5583
5584   print (vam->ofp, "%-12s", "sw_if_index");
5585
5586   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5587   {
5588     i++;
5589     if (!det->present)
5590       {
5591         continue;
5592       }
5593     print (vam->ofp, "%-12d", i);
5594     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5595     if (!det->addr)
5596       {
5597         continue;
5598       }
5599     vec_foreach (address, det->addr)
5600     {
5601       print (vam->ofp,
5602              "            %-30U%-13d",
5603              is_ipv6 ? format_ip6_address : format_ip4_address,
5604              address->ip, address->prefix_length);
5605     }
5606   }
5607
5608   return 0;
5609 }
5610
5611 static int
5612 dump_ipv4_table (vat_main_t * vam)
5613 {
5614   if (vam->json_output)
5615     {
5616       clib_warning
5617         ("JSON output supported only for VPE API calls and dump_stats_table");
5618       return -99;
5619     }
5620
5621   return dump_ip_table (vam, 0);
5622 }
5623
5624 static int
5625 dump_ipv6_table (vat_main_t * vam)
5626 {
5627   if (vam->json_output)
5628     {
5629       clib_warning
5630         ("JSON output supported only for VPE API calls and dump_stats_table");
5631       return -99;
5632     }
5633
5634   return dump_ip_table (vam, 1);
5635 }
5636
5637 /*
5638  * Pass CLI buffers directly in the CLI_INBAND API message,
5639  * instead of an additional shared memory area.
5640  */
5641 static int
5642 exec_inband (vat_main_t * vam)
5643 {
5644   vl_api_cli_inband_t *mp;
5645   unformat_input_t *i = vam->input;
5646   int ret;
5647
5648   if (vec_len (i->buffer) == 0)
5649     return -1;
5650
5651   if (vam->exec_mode == 0 && unformat (i, "mode"))
5652     {
5653       vam->exec_mode = 1;
5654       return 0;
5655     }
5656   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5657     {
5658       vam->exec_mode = 0;
5659       return 0;
5660     }
5661
5662   /*
5663    * In order for the CLI command to work, it
5664    * must be a vector ending in \n, not a C-string ending
5665    * in \n\0.
5666    */
5667   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5668   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5669
5670   S (mp);
5671   W (ret);
5672   /* json responses may or may not include a useful reply... */
5673   if (vec_len (vam->cmd_reply))
5674     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5675   return ret;
5676 }
5677
5678 int
5679 exec (vat_main_t * vam)
5680 {
5681   return exec_inband (vam);
5682 }
5683
5684 static int
5685 api_create_loopback (vat_main_t * vam)
5686 {
5687   unformat_input_t *i = vam->input;
5688   vl_api_create_loopback_t *mp;
5689   vl_api_create_loopback_instance_t *mp_lbi;
5690   u8 mac_address[6];
5691   u8 mac_set = 0;
5692   u8 is_specified = 0;
5693   u32 user_instance = 0;
5694   int ret;
5695
5696   clib_memset (mac_address, 0, sizeof (mac_address));
5697
5698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5699     {
5700       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5701         mac_set = 1;
5702       if (unformat (i, "instance %d", &user_instance))
5703         is_specified = 1;
5704       else
5705         break;
5706     }
5707
5708   if (is_specified)
5709     {
5710       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5711       mp_lbi->is_specified = is_specified;
5712       if (is_specified)
5713         mp_lbi->user_instance = htonl (user_instance);
5714       if (mac_set)
5715         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5716       S (mp_lbi);
5717     }
5718   else
5719     {
5720       /* Construct the API message */
5721       M (CREATE_LOOPBACK, mp);
5722       if (mac_set)
5723         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5724       S (mp);
5725     }
5726
5727   W (ret);
5728   return ret;
5729 }
5730
5731 static int
5732 api_delete_loopback (vat_main_t * vam)
5733 {
5734   unformat_input_t *i = vam->input;
5735   vl_api_delete_loopback_t *mp;
5736   u32 sw_if_index = ~0;
5737   int ret;
5738
5739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5740     {
5741       if (unformat (i, "sw_if_index %d", &sw_if_index))
5742         ;
5743       else
5744         break;
5745     }
5746
5747   if (sw_if_index == ~0)
5748     {
5749       errmsg ("missing sw_if_index");
5750       return -99;
5751     }
5752
5753   /* Construct the API message */
5754   M (DELETE_LOOPBACK, mp);
5755   mp->sw_if_index = ntohl (sw_if_index);
5756
5757   S (mp);
5758   W (ret);
5759   return ret;
5760 }
5761
5762 static int
5763 api_want_interface_events (vat_main_t * vam)
5764 {
5765   unformat_input_t *i = vam->input;
5766   vl_api_want_interface_events_t *mp;
5767   int enable = -1;
5768   int ret;
5769
5770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5771     {
5772       if (unformat (i, "enable"))
5773         enable = 1;
5774       else if (unformat (i, "disable"))
5775         enable = 0;
5776       else
5777         break;
5778     }
5779
5780   if (enable == -1)
5781     {
5782       errmsg ("missing enable|disable");
5783       return -99;
5784     }
5785
5786   M (WANT_INTERFACE_EVENTS, mp);
5787   mp->enable_disable = enable;
5788
5789   vam->interface_event_display = enable;
5790
5791   S (mp);
5792   W (ret);
5793   return ret;
5794 }
5795
5796
5797 /* Note: non-static, called once to set up the initial intfc table */
5798 int
5799 api_sw_interface_dump (vat_main_t * vam)
5800 {
5801   vl_api_sw_interface_dump_t *mp;
5802   vl_api_control_ping_t *mp_ping;
5803   hash_pair_t *p;
5804   name_sort_t *nses = 0, *ns;
5805   sw_interface_subif_t *sub = NULL;
5806   int ret;
5807
5808   /* Toss the old name table */
5809   /* *INDENT-OFF* */
5810   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5811   ({
5812     vec_add2 (nses, ns, 1);
5813     ns->name = (u8 *)(p->key);
5814     ns->value = (u32) p->value[0];
5815   }));
5816   /* *INDENT-ON* */
5817
5818   hash_free (vam->sw_if_index_by_interface_name);
5819
5820   vec_foreach (ns, nses) vec_free (ns->name);
5821
5822   vec_free (nses);
5823
5824   vec_foreach (sub, vam->sw_if_subif_table)
5825   {
5826     vec_free (sub->interface_name);
5827   }
5828   vec_free (vam->sw_if_subif_table);
5829
5830   /* recreate the interface name hash table */
5831   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5832
5833   /*
5834    * Ask for all interface names. Otherwise, the epic catalog of
5835    * name filters becomes ridiculously long, and vat ends up needing
5836    * to be taught about new interface types.
5837    */
5838   M (SW_INTERFACE_DUMP, mp);
5839   S (mp);
5840
5841   /* Use a control ping for synchronization */
5842   MPING (CONTROL_PING, mp_ping);
5843   S (mp_ping);
5844
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_sw_interface_set_flags (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_sw_interface_set_flags_t *mp;
5854   u32 sw_if_index;
5855   u8 sw_if_index_set = 0;
5856   u8 admin_up = 0;
5857   int ret;
5858
5859   /* Parse args required to build the message */
5860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5861     {
5862       if (unformat (i, "admin-up"))
5863         admin_up = 1;
5864       else if (unformat (i, "admin-down"))
5865         admin_up = 0;
5866       else
5867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5868         sw_if_index_set = 1;
5869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5870         sw_if_index_set = 1;
5871       else
5872         break;
5873     }
5874
5875   if (sw_if_index_set == 0)
5876     {
5877       errmsg ("missing interface name or sw_if_index");
5878       return -99;
5879     }
5880
5881   /* Construct the API message */
5882   M (SW_INTERFACE_SET_FLAGS, mp);
5883   mp->sw_if_index = ntohl (sw_if_index);
5884   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5885
5886   /* send it... */
5887   S (mp);
5888
5889   /* Wait for a reply, return the good/bad news... */
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_sw_interface_set_rx_mode (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_rx_mode_t *mp;
5899   u32 sw_if_index;
5900   u8 sw_if_index_set = 0;
5901   int ret;
5902   u8 queue_id_valid = 0;
5903   u32 queue_id;
5904   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5905
5906   /* Parse args required to build the message */
5907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5908     {
5909       if (unformat (i, "queue %d", &queue_id))
5910         queue_id_valid = 1;
5911       else if (unformat (i, "polling"))
5912         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5913       else if (unformat (i, "interrupt"))
5914         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5915       else if (unformat (i, "adaptive"))
5916         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5917       else
5918         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5919         sw_if_index_set = 1;
5920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5921         sw_if_index_set = 1;
5922       else
5923         break;
5924     }
5925
5926   if (sw_if_index_set == 0)
5927     {
5928       errmsg ("missing interface name or sw_if_index");
5929       return -99;
5930     }
5931   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5932     {
5933       errmsg ("missing rx-mode");
5934       return -99;
5935     }
5936
5937   /* Construct the API message */
5938   M (SW_INTERFACE_SET_RX_MODE, mp);
5939   mp->sw_if_index = ntohl (sw_if_index);
5940   mp->mode = (vl_api_rx_mode_t) mode;
5941   mp->queue_id_valid = queue_id_valid;
5942   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5943
5944   /* send it... */
5945   S (mp);
5946
5947   /* Wait for a reply, return the good/bad news... */
5948   W (ret);
5949   return ret;
5950 }
5951
5952 static int
5953 api_sw_interface_set_rx_placement (vat_main_t * vam)
5954 {
5955   unformat_input_t *i = vam->input;
5956   vl_api_sw_interface_set_rx_placement_t *mp;
5957   u32 sw_if_index;
5958   u8 sw_if_index_set = 0;
5959   int ret;
5960   u8 is_main = 0;
5961   u32 queue_id, thread_index;
5962
5963   /* Parse args required to build the message */
5964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965     {
5966       if (unformat (i, "queue %d", &queue_id))
5967         ;
5968       else if (unformat (i, "main"))
5969         is_main = 1;
5970       else if (unformat (i, "worker %d", &thread_index))
5971         ;
5972       else
5973         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5974         sw_if_index_set = 1;
5975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5976         sw_if_index_set = 1;
5977       else
5978         break;
5979     }
5980
5981   if (sw_if_index_set == 0)
5982     {
5983       errmsg ("missing interface name or sw_if_index");
5984       return -99;
5985     }
5986
5987   if (is_main)
5988     thread_index = 0;
5989   /* Construct the API message */
5990   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5991   mp->sw_if_index = ntohl (sw_if_index);
5992   mp->worker_id = ntohl (thread_index);
5993   mp->queue_id = ntohl (queue_id);
5994   mp->is_main = is_main;
5995
5996   /* send it... */
5997   S (mp);
5998   /* Wait for a reply, return the good/bad news... */
5999   W (ret);
6000   return ret;
6001 }
6002
6003 static void vl_api_sw_interface_rx_placement_details_t_handler
6004   (vl_api_sw_interface_rx_placement_details_t * mp)
6005 {
6006   vat_main_t *vam = &vat_main;
6007   u32 worker_id = ntohl (mp->worker_id);
6008
6009   print (vam->ofp,
6010          "\n%-11d %-11s %-6d %-5d %-9s",
6011          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6012          worker_id, ntohl (mp->queue_id),
6013          (mp->mode ==
6014           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6015 }
6016
6017 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6018   (vl_api_sw_interface_rx_placement_details_t * mp)
6019 {
6020   vat_main_t *vam = &vat_main;
6021   vat_json_node_t *node = NULL;
6022
6023   if (VAT_JSON_ARRAY != vam->json_tree.type)
6024     {
6025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6026       vat_json_init_array (&vam->json_tree);
6027     }
6028   node = vat_json_array_add (&vam->json_tree);
6029
6030   vat_json_init_object (node);
6031   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6032   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6033   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6034   vat_json_object_add_uint (node, "mode", mp->mode);
6035 }
6036
6037 static int
6038 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6039 {
6040   unformat_input_t *i = vam->input;
6041   vl_api_sw_interface_rx_placement_dump_t *mp;
6042   vl_api_control_ping_t *mp_ping;
6043   int ret;
6044   u32 sw_if_index;
6045   u8 sw_if_index_set = 0;
6046
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6050         sw_if_index_set++;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         sw_if_index_set++;
6053       else
6054         break;
6055     }
6056
6057   print (vam->ofp,
6058          "\n%-11s %-11s %-6s %-5s %-4s",
6059          "sw_if_index", "main/worker", "thread", "queue", "mode");
6060
6061   /* Dump Interface rx placement */
6062   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6063
6064   if (sw_if_index_set)
6065     mp->sw_if_index = htonl (sw_if_index);
6066   else
6067     mp->sw_if_index = ~0;
6068
6069   S (mp);
6070
6071   /* Use a control ping for synchronization */
6072   MPING (CONTROL_PING, mp_ping);
6073   S (mp_ping);
6074
6075   W (ret);
6076   return ret;
6077 }
6078
6079 static int
6080 api_sw_interface_clear_stats (vat_main_t * vam)
6081 {
6082   unformat_input_t *i = vam->input;
6083   vl_api_sw_interface_clear_stats_t *mp;
6084   u32 sw_if_index;
6085   u8 sw_if_index_set = 0;
6086   int ret;
6087
6088   /* Parse args required to build the message */
6089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090     {
6091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6092         sw_if_index_set = 1;
6093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6094         sw_if_index_set = 1;
6095       else
6096         break;
6097     }
6098
6099   /* Construct the API message */
6100   M (SW_INTERFACE_CLEAR_STATS, mp);
6101
6102   if (sw_if_index_set == 1)
6103     mp->sw_if_index = ntohl (sw_if_index);
6104   else
6105     mp->sw_if_index = ~0;
6106
6107   /* send it... */
6108   S (mp);
6109
6110   /* Wait for a reply, return the good/bad news... */
6111   W (ret);
6112   return ret;
6113 }
6114
6115 static int
6116 api_sw_interface_add_del_address (vat_main_t * vam)
6117 {
6118   unformat_input_t *i = vam->input;
6119   vl_api_sw_interface_add_del_address_t *mp;
6120   u32 sw_if_index;
6121   u8 sw_if_index_set = 0;
6122   u8 is_add = 1, del_all = 0;
6123   u32 address_length = 0;
6124   u8 v4_address_set = 0;
6125   u8 v6_address_set = 0;
6126   ip4_address_t v4address;
6127   ip6_address_t v6address;
6128   int ret;
6129
6130   /* Parse args required to build the message */
6131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6132     {
6133       if (unformat (i, "del-all"))
6134         del_all = 1;
6135       else if (unformat (i, "del"))
6136         is_add = 0;
6137       else
6138         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6139         sw_if_index_set = 1;
6140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6141         sw_if_index_set = 1;
6142       else if (unformat (i, "%U/%d",
6143                          unformat_ip4_address, &v4address, &address_length))
6144         v4_address_set = 1;
6145       else if (unformat (i, "%U/%d",
6146                          unformat_ip6_address, &v6address, &address_length))
6147         v6_address_set = 1;
6148       else
6149         break;
6150     }
6151
6152   if (sw_if_index_set == 0)
6153     {
6154       errmsg ("missing interface name or sw_if_index");
6155       return -99;
6156     }
6157   if (v4_address_set && v6_address_set)
6158     {
6159       errmsg ("both v4 and v6 addresses set");
6160       return -99;
6161     }
6162   if (!v4_address_set && !v6_address_set && !del_all)
6163     {
6164       errmsg ("no addresses set");
6165       return -99;
6166     }
6167
6168   /* Construct the API message */
6169   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6170
6171   mp->sw_if_index = ntohl (sw_if_index);
6172   mp->is_add = is_add;
6173   mp->del_all = del_all;
6174   if (v6_address_set)
6175     {
6176       mp->prefix.address.af = ADDRESS_IP6;
6177       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6178     }
6179   else
6180     {
6181       mp->prefix.address.af = ADDRESS_IP4;
6182       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6183     }
6184   mp->prefix.len = address_length;
6185
6186   /* send it... */
6187   S (mp);
6188
6189   /* Wait for a reply, return good/bad news  */
6190   W (ret);
6191   return ret;
6192 }
6193
6194 static int
6195 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6196 {
6197   unformat_input_t *i = vam->input;
6198   vl_api_sw_interface_set_mpls_enable_t *mp;
6199   u32 sw_if_index;
6200   u8 sw_if_index_set = 0;
6201   u8 enable = 1;
6202   int ret;
6203
6204   /* Parse args required to build the message */
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6208         sw_if_index_set = 1;
6209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6210         sw_if_index_set = 1;
6211       else if (unformat (i, "disable"))
6212         enable = 0;
6213       else if (unformat (i, "dis"))
6214         enable = 0;
6215       else
6216         break;
6217     }
6218
6219   if (sw_if_index_set == 0)
6220     {
6221       errmsg ("missing interface name or sw_if_index");
6222       return -99;
6223     }
6224
6225   /* Construct the API message */
6226   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6227
6228   mp->sw_if_index = ntohl (sw_if_index);
6229   mp->enable = enable;
6230
6231   /* send it... */
6232   S (mp);
6233
6234   /* Wait for a reply... */
6235   W (ret);
6236   return ret;
6237 }
6238
6239 static int
6240 api_sw_interface_set_table (vat_main_t * vam)
6241 {
6242   unformat_input_t *i = vam->input;
6243   vl_api_sw_interface_set_table_t *mp;
6244   u32 sw_if_index, vrf_id = 0;
6245   u8 sw_if_index_set = 0;
6246   u8 is_ipv6 = 0;
6247   int ret;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6255         sw_if_index_set = 1;
6256       else if (unformat (i, "vrf %d", &vrf_id))
6257         ;
6258       else if (unformat (i, "ipv6"))
6259         is_ipv6 = 1;
6260       else
6261         break;
6262     }
6263
6264   if (sw_if_index_set == 0)
6265     {
6266       errmsg ("missing interface name or sw_if_index");
6267       return -99;
6268     }
6269
6270   /* Construct the API message */
6271   M (SW_INTERFACE_SET_TABLE, mp);
6272
6273   mp->sw_if_index = ntohl (sw_if_index);
6274   mp->is_ipv6 = is_ipv6;
6275   mp->vrf_id = ntohl (vrf_id);
6276
6277   /* send it... */
6278   S (mp);
6279
6280   /* Wait for a reply... */
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static void vl_api_sw_interface_get_table_reply_t_handler
6286   (vl_api_sw_interface_get_table_reply_t * mp)
6287 {
6288   vat_main_t *vam = &vat_main;
6289
6290   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6291
6292   vam->retval = ntohl (mp->retval);
6293   vam->result_ready = 1;
6294
6295 }
6296
6297 static void vl_api_sw_interface_get_table_reply_t_handler_json
6298   (vl_api_sw_interface_get_table_reply_t * mp)
6299 {
6300   vat_main_t *vam = &vat_main;
6301   vat_json_node_t node;
6302
6303   vat_json_init_object (&node);
6304   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6305   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6306
6307   vat_json_print (vam->ofp, &node);
6308   vat_json_free (&node);
6309
6310   vam->retval = ntohl (mp->retval);
6311   vam->result_ready = 1;
6312 }
6313
6314 static int
6315 api_sw_interface_get_table (vat_main_t * vam)
6316 {
6317   unformat_input_t *i = vam->input;
6318   vl_api_sw_interface_get_table_t *mp;
6319   u32 sw_if_index;
6320   u8 sw_if_index_set = 0;
6321   u8 is_ipv6 = 0;
6322   int ret;
6323
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6327         sw_if_index_set = 1;
6328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "ipv6"))
6331         is_ipv6 = 1;
6332       else
6333         break;
6334     }
6335
6336   if (sw_if_index_set == 0)
6337     {
6338       errmsg ("missing interface name or sw_if_index");
6339       return -99;
6340     }
6341
6342   M (SW_INTERFACE_GET_TABLE, mp);
6343   mp->sw_if_index = htonl (sw_if_index);
6344   mp->is_ipv6 = is_ipv6;
6345
6346   S (mp);
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_sw_interface_set_vpath (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_sw_interface_set_vpath_t *mp;
6356   u32 sw_if_index = 0;
6357   u8 sw_if_index_set = 0;
6358   u8 is_enable = 0;
6359   int ret;
6360
6361   /* Parse args required to build the message */
6362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6363     {
6364       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6365         sw_if_index_set = 1;
6366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "enable"))
6369         is_enable = 1;
6370       else if (unformat (i, "disable"))
6371         is_enable = 0;
6372       else
6373         break;
6374     }
6375
6376   if (sw_if_index_set == 0)
6377     {
6378       errmsg ("missing interface name or sw_if_index");
6379       return -99;
6380     }
6381
6382   /* Construct the API message */
6383   M (SW_INTERFACE_SET_VPATH, mp);
6384
6385   mp->sw_if_index = ntohl (sw_if_index);
6386   mp->enable = is_enable;
6387
6388   /* send it... */
6389   S (mp);
6390
6391   /* Wait for a reply... */
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6401   u32 sw_if_index = 0;
6402   u8 sw_if_index_set = 0;
6403   u8 is_enable = 1;
6404   u8 is_ipv6 = 0;
6405   int ret;
6406
6407   /* Parse args required to build the message */
6408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6409     {
6410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6411         sw_if_index_set = 1;
6412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "enable"))
6415         is_enable = 1;
6416       else if (unformat (i, "disable"))
6417         is_enable = 0;
6418       else if (unformat (i, "ip4"))
6419         is_ipv6 = 0;
6420       else if (unformat (i, "ip6"))
6421         is_ipv6 = 1;
6422       else
6423         break;
6424     }
6425
6426   if (sw_if_index_set == 0)
6427     {
6428       errmsg ("missing interface name or sw_if_index");
6429       return -99;
6430     }
6431
6432   /* Construct the API message */
6433   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6434
6435   mp->sw_if_index = ntohl (sw_if_index);
6436   mp->enable = is_enable;
6437   mp->is_ipv6 = is_ipv6;
6438
6439   /* send it... */
6440   S (mp);
6441
6442   /* Wait for a reply... */
6443   W (ret);
6444   return ret;
6445 }
6446
6447 static int
6448 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6449 {
6450   unformat_input_t *i = vam->input;
6451   vl_api_sw_interface_set_geneve_bypass_t *mp;
6452   u32 sw_if_index = 0;
6453   u8 sw_if_index_set = 0;
6454   u8 is_enable = 1;
6455   u8 is_ipv6 = 0;
6456   int ret;
6457
6458   /* Parse args required to build the message */
6459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6460     {
6461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6462         sw_if_index_set = 1;
6463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6464         sw_if_index_set = 1;
6465       else if (unformat (i, "enable"))
6466         is_enable = 1;
6467       else if (unformat (i, "disable"))
6468         is_enable = 0;
6469       else if (unformat (i, "ip4"))
6470         is_ipv6 = 0;
6471       else if (unformat (i, "ip6"))
6472         is_ipv6 = 1;
6473       else
6474         break;
6475     }
6476
6477   if (sw_if_index_set == 0)
6478     {
6479       errmsg ("missing interface name or sw_if_index");
6480       return -99;
6481     }
6482
6483   /* Construct the API message */
6484   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6485
6486   mp->sw_if_index = ntohl (sw_if_index);
6487   mp->enable = is_enable;
6488   mp->is_ipv6 = is_ipv6;
6489
6490   /* send it... */
6491   S (mp);
6492
6493   /* Wait for a reply... */
6494   W (ret);
6495   return ret;
6496 }
6497
6498 static int
6499 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6500 {
6501   unformat_input_t *i = vam->input;
6502   vl_api_sw_interface_set_l2_xconnect_t *mp;
6503   u32 rx_sw_if_index;
6504   u8 rx_sw_if_index_set = 0;
6505   u32 tx_sw_if_index;
6506   u8 tx_sw_if_index_set = 0;
6507   u8 enable = 1;
6508   int ret;
6509
6510   /* Parse args required to build the message */
6511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6512     {
6513       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6514         rx_sw_if_index_set = 1;
6515       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6516         tx_sw_if_index_set = 1;
6517       else if (unformat (i, "rx"))
6518         {
6519           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520             {
6521               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6522                             &rx_sw_if_index))
6523                 rx_sw_if_index_set = 1;
6524             }
6525           else
6526             break;
6527         }
6528       else if (unformat (i, "tx"))
6529         {
6530           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6531             {
6532               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6533                             &tx_sw_if_index))
6534                 tx_sw_if_index_set = 1;
6535             }
6536           else
6537             break;
6538         }
6539       else if (unformat (i, "enable"))
6540         enable = 1;
6541       else if (unformat (i, "disable"))
6542         enable = 0;
6543       else
6544         break;
6545     }
6546
6547   if (rx_sw_if_index_set == 0)
6548     {
6549       errmsg ("missing rx interface name or rx_sw_if_index");
6550       return -99;
6551     }
6552
6553   if (enable && (tx_sw_if_index_set == 0))
6554     {
6555       errmsg ("missing tx interface name or tx_sw_if_index");
6556       return -99;
6557     }
6558
6559   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6560
6561   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6562   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6563   mp->enable = enable;
6564
6565   S (mp);
6566   W (ret);
6567   return ret;
6568 }
6569
6570 static int
6571 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_l2_bridge_t *mp;
6575   vl_api_l2_port_type_t port_type;
6576   u32 rx_sw_if_index;
6577   u8 rx_sw_if_index_set = 0;
6578   u32 bd_id;
6579   u8 bd_id_set = 0;
6580   u32 shg = 0;
6581   u8 enable = 1;
6582   int ret;
6583
6584   port_type = L2_API_PORT_TYPE_NORMAL;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "bd_id %d", &bd_id))
6592         bd_id_set = 1;
6593       else
6594         if (unformat
6595             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6596         rx_sw_if_index_set = 1;
6597       else if (unformat (i, "shg %d", &shg))
6598         ;
6599       else if (unformat (i, "bvi"))
6600         port_type = L2_API_PORT_TYPE_BVI;
6601       else if (unformat (i, "uu-fwd"))
6602         port_type = L2_API_PORT_TYPE_UU_FWD;
6603       else if (unformat (i, "enable"))
6604         enable = 1;
6605       else if (unformat (i, "disable"))
6606         enable = 0;
6607       else
6608         break;
6609     }
6610
6611   if (rx_sw_if_index_set == 0)
6612     {
6613       errmsg ("missing rx interface name or sw_if_index");
6614       return -99;
6615     }
6616
6617   if (enable && (bd_id_set == 0))
6618     {
6619       errmsg ("missing bridge domain");
6620       return -99;
6621     }
6622
6623   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6624
6625   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6626   mp->bd_id = ntohl (bd_id);
6627   mp->shg = (u8) shg;
6628   mp->port_type = ntohl (port_type);
6629   mp->enable = enable;
6630
6631   S (mp);
6632   W (ret);
6633   return ret;
6634 }
6635
6636 static int
6637 api_bridge_domain_dump (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_bridge_domain_dump_t *mp;
6641   vl_api_control_ping_t *mp_ping;
6642   u32 bd_id = ~0;
6643   int ret;
6644
6645   /* Parse args required to build the message */
6646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6647     {
6648       if (unformat (i, "bd_id %d", &bd_id))
6649         ;
6650       else
6651         break;
6652     }
6653
6654   M (BRIDGE_DOMAIN_DUMP, mp);
6655   mp->bd_id = ntohl (bd_id);
6656   S (mp);
6657
6658   /* Use a control ping for synchronization */
6659   MPING (CONTROL_PING, mp_ping);
6660   S (mp_ping);
6661
6662   W (ret);
6663   return ret;
6664 }
6665
6666 static int
6667 api_bridge_domain_add_del (vat_main_t * vam)
6668 {
6669   unformat_input_t *i = vam->input;
6670   vl_api_bridge_domain_add_del_t *mp;
6671   u32 bd_id = ~0;
6672   u8 is_add = 1;
6673   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6674   u8 *bd_tag = NULL;
6675   u32 mac_age = 0;
6676   int ret;
6677
6678   /* Parse args required to build the message */
6679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6680     {
6681       if (unformat (i, "bd_id %d", &bd_id))
6682         ;
6683       else if (unformat (i, "flood %d", &flood))
6684         ;
6685       else if (unformat (i, "uu-flood %d", &uu_flood))
6686         ;
6687       else if (unformat (i, "forward %d", &forward))
6688         ;
6689       else if (unformat (i, "learn %d", &learn))
6690         ;
6691       else if (unformat (i, "arp-term %d", &arp_term))
6692         ;
6693       else if (unformat (i, "mac-age %d", &mac_age))
6694         ;
6695       else if (unformat (i, "bd-tag %s", &bd_tag))
6696         ;
6697       else if (unformat (i, "del"))
6698         {
6699           is_add = 0;
6700           flood = uu_flood = forward = learn = 0;
6701         }
6702       else
6703         break;
6704     }
6705
6706   if (bd_id == ~0)
6707     {
6708       errmsg ("missing bridge domain");
6709       ret = -99;
6710       goto done;
6711     }
6712
6713   if (mac_age > 255)
6714     {
6715       errmsg ("mac age must be less than 256 ");
6716       ret = -99;
6717       goto done;
6718     }
6719
6720   if ((bd_tag) && (vec_len (bd_tag) > 63))
6721     {
6722       errmsg ("bd-tag cannot be longer than 63");
6723       ret = -99;
6724       goto done;
6725     }
6726
6727   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6728
6729   mp->bd_id = ntohl (bd_id);
6730   mp->flood = flood;
6731   mp->uu_flood = uu_flood;
6732   mp->forward = forward;
6733   mp->learn = learn;
6734   mp->arp_term = arp_term;
6735   mp->is_add = is_add;
6736   mp->mac_age = (u8) mac_age;
6737   if (bd_tag)
6738     {
6739       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6740       mp->bd_tag[vec_len (bd_tag)] = 0;
6741     }
6742   S (mp);
6743   W (ret);
6744
6745 done:
6746   vec_free (bd_tag);
6747   return ret;
6748 }
6749
6750 static int
6751 api_l2fib_flush_bd (vat_main_t * vam)
6752 {
6753   unformat_input_t *i = vam->input;
6754   vl_api_l2fib_flush_bd_t *mp;
6755   u32 bd_id = ~0;
6756   int ret;
6757
6758   /* Parse args required to build the message */
6759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6760     {
6761       if (unformat (i, "bd_id %d", &bd_id));
6762       else
6763         break;
6764     }
6765
6766   if (bd_id == ~0)
6767     {
6768       errmsg ("missing bridge domain");
6769       return -99;
6770     }
6771
6772   M (L2FIB_FLUSH_BD, mp);
6773
6774   mp->bd_id = htonl (bd_id);
6775
6776   S (mp);
6777   W (ret);
6778   return ret;
6779 }
6780
6781 static int
6782 api_l2fib_flush_int (vat_main_t * vam)
6783 {
6784   unformat_input_t *i = vam->input;
6785   vl_api_l2fib_flush_int_t *mp;
6786   u32 sw_if_index = ~0;
6787   int ret;
6788
6789   /* Parse args required to build the message */
6790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791     {
6792       if (unformat (i, "sw_if_index %d", &sw_if_index));
6793       else
6794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6795       else
6796         break;
6797     }
6798
6799   if (sw_if_index == ~0)
6800     {
6801       errmsg ("missing interface name or sw_if_index");
6802       return -99;
6803     }
6804
6805   M (L2FIB_FLUSH_INT, mp);
6806
6807   mp->sw_if_index = ntohl (sw_if_index);
6808
6809   S (mp);
6810   W (ret);
6811   return ret;
6812 }
6813
6814 static int
6815 api_l2fib_add_del (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_l2fib_add_del_t *mp;
6819   f64 timeout;
6820   u8 mac[6] = { 0 };
6821   u8 mac_set = 0;
6822   u32 bd_id;
6823   u8 bd_id_set = 0;
6824   u32 sw_if_index = 0;
6825   u8 sw_if_index_set = 0;
6826   u8 is_add = 1;
6827   u8 static_mac = 0;
6828   u8 filter_mac = 0;
6829   u8 bvi_mac = 0;
6830   int count = 1;
6831   f64 before = 0;
6832   int j;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6838         mac_set = 1;
6839       else if (unformat (i, "bd_id %d", &bd_id))
6840         bd_id_set = 1;
6841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6842         sw_if_index_set = 1;
6843       else if (unformat (i, "sw_if"))
6844         {
6845           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846             {
6847               if (unformat
6848                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6849                 sw_if_index_set = 1;
6850             }
6851           else
6852             break;
6853         }
6854       else if (unformat (i, "static"))
6855         static_mac = 1;
6856       else if (unformat (i, "filter"))
6857         {
6858           filter_mac = 1;
6859           static_mac = 1;
6860         }
6861       else if (unformat (i, "bvi"))
6862         {
6863           bvi_mac = 1;
6864           static_mac = 1;
6865         }
6866       else if (unformat (i, "del"))
6867         is_add = 0;
6868       else if (unformat (i, "count %d", &count))
6869         ;
6870       else
6871         break;
6872     }
6873
6874   if (mac_set == 0)
6875     {
6876       errmsg ("missing mac address");
6877       return -99;
6878     }
6879
6880   if (bd_id_set == 0)
6881     {
6882       errmsg ("missing bridge domain");
6883       return -99;
6884     }
6885
6886   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6887     {
6888       errmsg ("missing interface name or sw_if_index");
6889       return -99;
6890     }
6891
6892   if (count > 1)
6893     {
6894       /* Turn on async mode */
6895       vam->async_mode = 1;
6896       vam->async_errors = 0;
6897       before = vat_time_now (vam);
6898     }
6899
6900   for (j = 0; j < count; j++)
6901     {
6902       M (L2FIB_ADD_DEL, mp);
6903
6904       clib_memcpy (mp->mac, mac, 6);
6905       mp->bd_id = ntohl (bd_id);
6906       mp->is_add = is_add;
6907       mp->sw_if_index = ntohl (sw_if_index);
6908
6909       if (is_add)
6910         {
6911           mp->static_mac = static_mac;
6912           mp->filter_mac = filter_mac;
6913           mp->bvi_mac = bvi_mac;
6914         }
6915       increment_mac_address (mac);
6916       /* send it... */
6917       S (mp);
6918     }
6919
6920   if (count > 1)
6921     {
6922       vl_api_control_ping_t *mp_ping;
6923       f64 after;
6924
6925       /* Shut off async mode */
6926       vam->async_mode = 0;
6927
6928       MPING (CONTROL_PING, mp_ping);
6929       S (mp_ping);
6930
6931       timeout = vat_time_now (vam) + 1.0;
6932       while (vat_time_now (vam) < timeout)
6933         if (vam->result_ready == 1)
6934           goto out;
6935       vam->retval = -99;
6936
6937     out:
6938       if (vam->retval == -99)
6939         errmsg ("timeout");
6940
6941       if (vam->async_errors > 0)
6942         {
6943           errmsg ("%d asynchronous errors", vam->async_errors);
6944           vam->retval = -98;
6945         }
6946       vam->async_errors = 0;
6947       after = vat_time_now (vam);
6948
6949       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6950              count, after - before, count / (after - before));
6951     }
6952   else
6953     {
6954       int ret;
6955
6956       /* Wait for a reply... */
6957       W (ret);
6958       return ret;
6959     }
6960   /* Return the good/bad news */
6961   return (vam->retval);
6962 }
6963
6964 static int
6965 api_bridge_domain_set_mac_age (vat_main_t * vam)
6966 {
6967   unformat_input_t *i = vam->input;
6968   vl_api_bridge_domain_set_mac_age_t *mp;
6969   u32 bd_id = ~0;
6970   u32 mac_age = 0;
6971   int ret;
6972
6973   /* Parse args required to build the message */
6974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6975     {
6976       if (unformat (i, "bd_id %d", &bd_id));
6977       else if (unformat (i, "mac-age %d", &mac_age));
6978       else
6979         break;
6980     }
6981
6982   if (bd_id == ~0)
6983     {
6984       errmsg ("missing bridge domain");
6985       return -99;
6986     }
6987
6988   if (mac_age > 255)
6989     {
6990       errmsg ("mac age must be less than 256 ");
6991       return -99;
6992     }
6993
6994   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6995
6996   mp->bd_id = htonl (bd_id);
6997   mp->mac_age = (u8) mac_age;
6998
6999   S (mp);
7000   W (ret);
7001   return ret;
7002 }
7003
7004 static int
7005 api_l2_flags (vat_main_t * vam)
7006 {
7007   unformat_input_t *i = vam->input;
7008   vl_api_l2_flags_t *mp;
7009   u32 sw_if_index;
7010   u32 flags = 0;
7011   u8 sw_if_index_set = 0;
7012   u8 is_set = 0;
7013   int ret;
7014
7015   /* Parse args required to build the message */
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "sw_if_index %d", &sw_if_index))
7019         sw_if_index_set = 1;
7020       else if (unformat (i, "sw_if"))
7021         {
7022           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023             {
7024               if (unformat
7025                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7026                 sw_if_index_set = 1;
7027             }
7028           else
7029             break;
7030         }
7031       else if (unformat (i, "learn"))
7032         flags |= L2_LEARN;
7033       else if (unformat (i, "forward"))
7034         flags |= L2_FWD;
7035       else if (unformat (i, "flood"))
7036         flags |= L2_FLOOD;
7037       else if (unformat (i, "uu-flood"))
7038         flags |= L2_UU_FLOOD;
7039       else if (unformat (i, "arp-term"))
7040         flags |= L2_ARP_TERM;
7041       else if (unformat (i, "off"))
7042         is_set = 0;
7043       else if (unformat (i, "disable"))
7044         is_set = 0;
7045       else
7046         break;
7047     }
7048
7049   if (sw_if_index_set == 0)
7050     {
7051       errmsg ("missing interface name or sw_if_index");
7052       return -99;
7053     }
7054
7055   M (L2_FLAGS, mp);
7056
7057   mp->sw_if_index = ntohl (sw_if_index);
7058   mp->feature_bitmap = ntohl (flags);
7059   mp->is_set = is_set;
7060
7061   S (mp);
7062   W (ret);
7063   return ret;
7064 }
7065
7066 static int
7067 api_bridge_flags (vat_main_t * vam)
7068 {
7069   unformat_input_t *i = vam->input;
7070   vl_api_bridge_flags_t *mp;
7071   u32 bd_id;
7072   u8 bd_id_set = 0;
7073   u8 is_set = 1;
7074   bd_flags_t flags = 0;
7075   int ret;
7076
7077   /* Parse args required to build the message */
7078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7079     {
7080       if (unformat (i, "bd_id %d", &bd_id))
7081         bd_id_set = 1;
7082       else if (unformat (i, "learn"))
7083         flags |= BRIDGE_API_FLAG_LEARN;
7084       else if (unformat (i, "forward"))
7085         flags |= BRIDGE_API_FLAG_FWD;
7086       else if (unformat (i, "flood"))
7087         flags |= BRIDGE_API_FLAG_FLOOD;
7088       else if (unformat (i, "uu-flood"))
7089         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7090       else if (unformat (i, "arp-term"))
7091         flags |= BRIDGE_API_FLAG_ARP_TERM;
7092       else if (unformat (i, "off"))
7093         is_set = 0;
7094       else if (unformat (i, "disable"))
7095         is_set = 0;
7096       else
7097         break;
7098     }
7099
7100   if (bd_id_set == 0)
7101     {
7102       errmsg ("missing bridge domain");
7103       return -99;
7104     }
7105
7106   M (BRIDGE_FLAGS, mp);
7107
7108   mp->bd_id = ntohl (bd_id);
7109   mp->flags = ntohl (flags);
7110   mp->is_set = is_set;
7111
7112   S (mp);
7113   W (ret);
7114   return ret;
7115 }
7116
7117 static int
7118 api_bd_ip_mac_add_del (vat_main_t * vam)
7119 {
7120   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7121   vl_api_mac_address_t mac = { 0 };
7122   unformat_input_t *i = vam->input;
7123   vl_api_bd_ip_mac_add_del_t *mp;
7124   u32 bd_id;
7125   u8 is_add = 1;
7126   u8 bd_id_set = 0;
7127   u8 ip_set = 0;
7128   u8 mac_set = 0;
7129   int ret;
7130
7131
7132   /* Parse args required to build the message */
7133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7134     {
7135       if (unformat (i, "bd_id %d", &bd_id))
7136         {
7137           bd_id_set++;
7138         }
7139       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7140         {
7141           ip_set++;
7142         }
7143       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7144         {
7145           mac_set++;
7146         }
7147       else if (unformat (i, "del"))
7148         is_add = 0;
7149       else
7150         break;
7151     }
7152
7153   if (bd_id_set == 0)
7154     {
7155       errmsg ("missing bridge domain");
7156       return -99;
7157     }
7158   else if (ip_set == 0)
7159     {
7160       errmsg ("missing IP address");
7161       return -99;
7162     }
7163   else if (mac_set == 0)
7164     {
7165       errmsg ("missing MAC address");
7166       return -99;
7167     }
7168
7169   M (BD_IP_MAC_ADD_DEL, mp);
7170
7171   mp->entry.bd_id = ntohl (bd_id);
7172   mp->is_add = is_add;
7173
7174   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7175   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7176
7177   S (mp);
7178   W (ret);
7179   return ret;
7180 }
7181
7182 static int
7183 api_bd_ip_mac_flush (vat_main_t * vam)
7184 {
7185   unformat_input_t *i = vam->input;
7186   vl_api_bd_ip_mac_flush_t *mp;
7187   u32 bd_id;
7188   u8 bd_id_set = 0;
7189   int ret;
7190
7191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7192     {
7193       if (unformat (i, "bd_id %d", &bd_id))
7194         {
7195           bd_id_set++;
7196         }
7197       else
7198         break;
7199     }
7200
7201   if (bd_id_set == 0)
7202     {
7203       errmsg ("missing bridge domain");
7204       return -99;
7205     }
7206
7207   M (BD_IP_MAC_FLUSH, mp);
7208
7209   mp->bd_id = ntohl (bd_id);
7210
7211   S (mp);
7212   W (ret);
7213   return ret;
7214 }
7215
7216 static void vl_api_bd_ip_mac_details_t_handler
7217   (vl_api_bd_ip_mac_details_t * mp)
7218 {
7219   vat_main_t *vam = &vat_main;
7220
7221   print (vam->ofp,
7222          "\n%-5d %U %U",
7223          ntohl (mp->entry.bd_id),
7224          format_vl_api_mac_address, mp->entry.mac,
7225          format_vl_api_address, &mp->entry.ip);
7226 }
7227
7228 static void vl_api_bd_ip_mac_details_t_handler_json
7229   (vl_api_bd_ip_mac_details_t * mp)
7230 {
7231   vat_main_t *vam = &vat_main;
7232   vat_json_node_t *node = NULL;
7233
7234   if (VAT_JSON_ARRAY != vam->json_tree.type)
7235     {
7236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7237       vat_json_init_array (&vam->json_tree);
7238     }
7239   node = vat_json_array_add (&vam->json_tree);
7240
7241   vat_json_init_object (node);
7242   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7243   vat_json_object_add_string_copy (node, "mac_address",
7244                                    format (0, "%U", format_vl_api_mac_address,
7245                                            &mp->entry.mac));
7246   u8 *ip = 0;
7247
7248   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7249   vat_json_object_add_string_copy (node, "ip_address", ip);
7250   vec_free (ip);
7251 }
7252
7253 static int
7254 api_bd_ip_mac_dump (vat_main_t * vam)
7255 {
7256   unformat_input_t *i = vam->input;
7257   vl_api_bd_ip_mac_dump_t *mp;
7258   vl_api_control_ping_t *mp_ping;
7259   int ret;
7260   u32 bd_id;
7261   u8 bd_id_set = 0;
7262
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264     {
7265       if (unformat (i, "bd_id %d", &bd_id))
7266         {
7267           bd_id_set++;
7268         }
7269       else
7270         break;
7271     }
7272
7273   print (vam->ofp,
7274          "\n%-5s %-7s %-20s %-30s",
7275          "bd_id", "is_ipv6", "mac_address", "ip_address");
7276
7277   /* Dump Bridge Domain Ip to Mac entries */
7278   M (BD_IP_MAC_DUMP, mp);
7279
7280   if (bd_id_set)
7281     mp->bd_id = htonl (bd_id);
7282   else
7283     mp->bd_id = ~0;
7284
7285   S (mp);
7286
7287   /* Use a control ping for synchronization */
7288   MPING (CONTROL_PING, mp_ping);
7289   S (mp_ping);
7290
7291   W (ret);
7292   return ret;
7293 }
7294
7295 static int
7296 api_tap_create_v2 (vat_main_t * vam)
7297 {
7298   unformat_input_t *i = vam->input;
7299   vl_api_tap_create_v2_t *mp;
7300   u8 mac_address[6];
7301   u8 random_mac = 1;
7302   u32 id = ~0;
7303   u32 num_rx_queues = 0;
7304   u8 *host_if_name = 0;
7305   u8 host_if_name_set = 0;
7306   u8 *host_ns = 0;
7307   u8 host_ns_set = 0;
7308   u8 host_mac_addr[6];
7309   u8 host_mac_addr_set = 0;
7310   u8 *host_bridge = 0;
7311   u8 host_bridge_set = 0;
7312   u8 host_ip4_prefix_set = 0;
7313   u8 host_ip6_prefix_set = 0;
7314   ip4_address_t host_ip4_addr;
7315   ip4_address_t host_ip4_gw;
7316   u8 host_ip4_gw_set = 0;
7317   u32 host_ip4_prefix_len = 0;
7318   ip6_address_t host_ip6_addr;
7319   ip6_address_t host_ip6_gw;
7320   u8 host_ip6_gw_set = 0;
7321   u32 host_ip6_prefix_len = 0;
7322   u32 host_mtu_size = 0;
7323   u8 host_mtu_set = 0;
7324   u32 tap_flags = 0;
7325   int ret;
7326   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7327
7328   clib_memset (mac_address, 0, sizeof (mac_address));
7329
7330   /* Parse args required to build the message */
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "id %u", &id))
7334         ;
7335       else
7336         if (unformat
7337             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7338         random_mac = 0;
7339       else if (unformat (i, "host-if-name %s", &host_if_name))
7340         host_if_name_set = 1;
7341       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7342         ;
7343       else if (unformat (i, "host-ns %s", &host_ns))
7344         host_ns_set = 1;
7345       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7346                          host_mac_addr))
7347         host_mac_addr_set = 1;
7348       else if (unformat (i, "host-bridge %s", &host_bridge))
7349         host_bridge_set = 1;
7350       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7351                          &host_ip4_addr, &host_ip4_prefix_len))
7352         host_ip4_prefix_set = 1;
7353       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7354                          &host_ip6_addr, &host_ip6_prefix_len))
7355         host_ip6_prefix_set = 1;
7356       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7357                          &host_ip4_gw))
7358         host_ip4_gw_set = 1;
7359       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7360                          &host_ip6_gw))
7361         host_ip6_gw_set = 1;
7362       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7363         ;
7364       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7365         ;
7366       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7367         host_mtu_set = 1;
7368       else if (unformat (i, "no-gso"))
7369         tap_flags &= ~TAP_FLAG_GSO;
7370       else if (unformat (i, "gso"))
7371         tap_flags |= TAP_FLAG_GSO;
7372       else if (unformat (i, "csum-offload"))
7373         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7374       else if (unformat (i, "persist"))
7375         tap_flags |= TAP_FLAG_PERSIST;
7376       else if (unformat (i, "attach"))
7377         tap_flags |= TAP_FLAG_ATTACH;
7378       else
7379         break;
7380     }
7381
7382   if (vec_len (host_if_name) > 63)
7383     {
7384       errmsg ("tap name too long. ");
7385       return -99;
7386     }
7387   if (vec_len (host_ns) > 63)
7388     {
7389       errmsg ("host name space too long. ");
7390       return -99;
7391     }
7392   if (vec_len (host_bridge) > 63)
7393     {
7394       errmsg ("host bridge name too long. ");
7395       return -99;
7396     }
7397   if (host_ip4_prefix_len > 32)
7398     {
7399       errmsg ("host ip4 prefix length not valid. ");
7400       return -99;
7401     }
7402   if (host_ip6_prefix_len > 128)
7403     {
7404       errmsg ("host ip6 prefix length not valid. ");
7405       return -99;
7406     }
7407   if (!is_pow2 (rx_ring_sz))
7408     {
7409       errmsg ("rx ring size must be power of 2. ");
7410       return -99;
7411     }
7412   if (rx_ring_sz > 32768)
7413     {
7414       errmsg ("rx ring size must be 32768 or lower. ");
7415       return -99;
7416     }
7417   if (!is_pow2 (tx_ring_sz))
7418     {
7419       errmsg ("tx ring size must be power of 2. ");
7420       return -99;
7421     }
7422   if (tx_ring_sz > 32768)
7423     {
7424       errmsg ("tx ring size must be 32768 or lower. ");
7425       return -99;
7426     }
7427   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7428     {
7429       errmsg ("host MTU size must be in between 64 and 65355. ");
7430       return -99;
7431     }
7432
7433   /* Construct the API message */
7434   M (TAP_CREATE_V2, mp);
7435
7436   mp->id = ntohl (id);
7437   mp->use_random_mac = random_mac;
7438   mp->num_rx_queues = (u8) num_rx_queues;
7439   mp->tx_ring_sz = ntohs (tx_ring_sz);
7440   mp->rx_ring_sz = ntohs (rx_ring_sz);
7441   mp->host_mtu_set = host_mtu_set;
7442   mp->host_mtu_size = ntohl (host_mtu_size);
7443   mp->host_mac_addr_set = host_mac_addr_set;
7444   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7445   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7446   mp->host_ip4_gw_set = host_ip4_gw_set;
7447   mp->host_ip6_gw_set = host_ip6_gw_set;
7448   mp->tap_flags = ntohl (tap_flags);
7449   mp->host_namespace_set = host_ns_set;
7450   mp->host_if_name_set = host_if_name_set;
7451   mp->host_bridge_set = host_bridge_set;
7452
7453   if (random_mac == 0)
7454     clib_memcpy (mp->mac_address, mac_address, 6);
7455   if (host_mac_addr_set)
7456     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7457   if (host_if_name_set)
7458     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7459   if (host_ns_set)
7460     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7461   if (host_bridge_set)
7462     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7463   if (host_ip4_prefix_set)
7464     {
7465       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7466       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7467     }
7468   if (host_ip6_prefix_set)
7469     {
7470       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7471       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7472     }
7473   if (host_ip4_gw_set)
7474     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7475   if (host_ip6_gw_set)
7476     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7477
7478   vec_free (host_ns);
7479   vec_free (host_if_name);
7480   vec_free (host_bridge);
7481
7482   /* send it... */
7483   S (mp);
7484
7485   /* Wait for a reply... */
7486   W (ret);
7487   return ret;
7488 }
7489
7490 static int
7491 api_tap_delete_v2 (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_tap_delete_v2_t *mp;
7495   u32 sw_if_index = ~0;
7496   u8 sw_if_index_set = 0;
7497   int ret;
7498
7499   /* Parse args required to build the message */
7500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7501     {
7502       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7503         sw_if_index_set = 1;
7504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7505         sw_if_index_set = 1;
7506       else
7507         break;
7508     }
7509
7510   if (sw_if_index_set == 0)
7511     {
7512       errmsg ("missing vpp interface name. ");
7513       return -99;
7514     }
7515
7516   /* Construct the API message */
7517   M (TAP_DELETE_V2, mp);
7518
7519   mp->sw_if_index = ntohl (sw_if_index);
7520
7521   /* send it... */
7522   S (mp);
7523
7524   /* Wait for a reply... */
7525   W (ret);
7526   return ret;
7527 }
7528
7529 uword
7530 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7531 {
7532   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7533   u32 x[4];
7534
7535   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7536     return 0;
7537
7538   addr->domain = x[0];
7539   addr->bus = x[1];
7540   addr->slot = x[2];
7541   addr->function = x[3];
7542
7543   return 1;
7544 }
7545
7546 static int
7547 api_virtio_pci_create (vat_main_t * vam)
7548 {
7549   unformat_input_t *i = vam->input;
7550   vl_api_virtio_pci_create_t *mp;
7551   u8 mac_address[6];
7552   u8 random_mac = 1;
7553   u8 gso_enabled = 0;
7554   u8 checksum_offload_enabled = 0;
7555   u32 pci_addr = 0;
7556   u64 features = (u64) ~ (0ULL);
7557   int ret;
7558
7559   clib_memset (mac_address, 0, sizeof (mac_address));
7560
7561   /* Parse args required to build the message */
7562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7563     {
7564       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7565         {
7566           random_mac = 0;
7567         }
7568       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7569         ;
7570       else if (unformat (i, "features 0x%llx", &features))
7571         ;
7572       else if (unformat (i, "gso-enabled"))
7573         gso_enabled = 1;
7574       else if (unformat (i, "csum-offload-enabled"))
7575         checksum_offload_enabled = 1;
7576       else
7577         break;
7578     }
7579
7580   if (pci_addr == 0)
7581     {
7582       errmsg ("pci address must be non zero. ");
7583       return -99;
7584     }
7585
7586   /* Construct the API message */
7587   M (VIRTIO_PCI_CREATE, mp);
7588
7589   mp->use_random_mac = random_mac;
7590
7591   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7592   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7593   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7594   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7595
7596   mp->features = clib_host_to_net_u64 (features);
7597   mp->gso_enabled = gso_enabled;
7598   mp->checksum_offload_enabled = checksum_offload_enabled;
7599
7600   if (random_mac == 0)
7601     clib_memcpy (mp->mac_address, mac_address, 6);
7602
7603   /* send it... */
7604   S (mp);
7605
7606   /* Wait for a reply... */
7607   W (ret);
7608   return ret;
7609 }
7610
7611 static int
7612 api_virtio_pci_delete (vat_main_t * vam)
7613 {
7614   unformat_input_t *i = vam->input;
7615   vl_api_virtio_pci_delete_t *mp;
7616   u32 sw_if_index = ~0;
7617   u8 sw_if_index_set = 0;
7618   int ret;
7619
7620   /* Parse args required to build the message */
7621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7622     {
7623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7624         sw_if_index_set = 1;
7625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7626         sw_if_index_set = 1;
7627       else
7628         break;
7629     }
7630
7631   if (sw_if_index_set == 0)
7632     {
7633       errmsg ("missing vpp interface name. ");
7634       return -99;
7635     }
7636
7637   /* Construct the API message */
7638   M (VIRTIO_PCI_DELETE, mp);
7639
7640   mp->sw_if_index = htonl (sw_if_index);
7641
7642   /* send it... */
7643   S (mp);
7644
7645   /* Wait for a reply... */
7646   W (ret);
7647   return ret;
7648 }
7649
7650 static int
7651 api_bond_create (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_bond_create_t *mp;
7655   u8 mac_address[6];
7656   u8 custom_mac = 0;
7657   int ret;
7658   u8 mode;
7659   u8 lb;
7660   u8 mode_is_set = 0;
7661   u32 id = ~0;
7662   u8 numa_only = 0;
7663
7664   clib_memset (mac_address, 0, sizeof (mac_address));
7665   lb = BOND_LB_L2;
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7671         mode_is_set = 1;
7672       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7673                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7674         ;
7675       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7676                          mac_address))
7677         custom_mac = 1;
7678       else if (unformat (i, "numa-only"))
7679         numa_only = 1;
7680       else if (unformat (i, "id %u", &id))
7681         ;
7682       else
7683         break;
7684     }
7685
7686   if (mode_is_set == 0)
7687     {
7688       errmsg ("Missing bond mode. ");
7689       return -99;
7690     }
7691
7692   /* Construct the API message */
7693   M (BOND_CREATE, mp);
7694
7695   mp->use_custom_mac = custom_mac;
7696
7697   mp->mode = htonl (mode);
7698   mp->lb = htonl (lb);
7699   mp->id = htonl (id);
7700   mp->numa_only = numa_only;
7701
7702   if (custom_mac)
7703     clib_memcpy (mp->mac_address, mac_address, 6);
7704
7705   /* send it... */
7706   S (mp);
7707
7708   /* Wait for a reply... */
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_bond_delete (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_bond_delete_t *mp;
7718   u32 sw_if_index = ~0;
7719   u8 sw_if_index_set = 0;
7720   int ret;
7721
7722   /* Parse args required to build the message */
7723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7724     {
7725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7726         sw_if_index_set = 1;
7727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7728         sw_if_index_set = 1;
7729       else
7730         break;
7731     }
7732
7733   if (sw_if_index_set == 0)
7734     {
7735       errmsg ("missing vpp interface name. ");
7736       return -99;
7737     }
7738
7739   /* Construct the API message */
7740   M (BOND_DELETE, mp);
7741
7742   mp->sw_if_index = ntohl (sw_if_index);
7743
7744   /* send it... */
7745   S (mp);
7746
7747   /* Wait for a reply... */
7748   W (ret);
7749   return ret;
7750 }
7751
7752 static int
7753 api_bond_enslave (vat_main_t * vam)
7754 {
7755   unformat_input_t *i = vam->input;
7756   vl_api_bond_enslave_t *mp;
7757   u32 bond_sw_if_index;
7758   int ret;
7759   u8 is_passive;
7760   u8 is_long_timeout;
7761   u32 bond_sw_if_index_is_set = 0;
7762   u32 sw_if_index;
7763   u8 sw_if_index_is_set = 0;
7764
7765   /* Parse args required to build the message */
7766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7767     {
7768       if (unformat (i, "sw_if_index %d", &sw_if_index))
7769         sw_if_index_is_set = 1;
7770       else if (unformat (i, "bond %u", &bond_sw_if_index))
7771         bond_sw_if_index_is_set = 1;
7772       else if (unformat (i, "passive %d", &is_passive))
7773         ;
7774       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7775         ;
7776       else
7777         break;
7778     }
7779
7780   if (bond_sw_if_index_is_set == 0)
7781     {
7782       errmsg ("Missing bond sw_if_index. ");
7783       return -99;
7784     }
7785   if (sw_if_index_is_set == 0)
7786     {
7787       errmsg ("Missing slave sw_if_index. ");
7788       return -99;
7789     }
7790
7791   /* Construct the API message */
7792   M (BOND_ENSLAVE, mp);
7793
7794   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7795   mp->sw_if_index = ntohl (sw_if_index);
7796   mp->is_long_timeout = is_long_timeout;
7797   mp->is_passive = is_passive;
7798
7799   /* send it... */
7800   S (mp);
7801
7802   /* Wait for a reply... */
7803   W (ret);
7804   return ret;
7805 }
7806
7807 static int
7808 api_bond_detach_slave (vat_main_t * vam)
7809 {
7810   unformat_input_t *i = vam->input;
7811   vl_api_bond_detach_slave_t *mp;
7812   u32 sw_if_index = ~0;
7813   u8 sw_if_index_set = 0;
7814   int ret;
7815
7816   /* Parse args required to build the message */
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7820         sw_if_index_set = 1;
7821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7822         sw_if_index_set = 1;
7823       else
7824         break;
7825     }
7826
7827   if (sw_if_index_set == 0)
7828     {
7829       errmsg ("missing vpp interface name. ");
7830       return -99;
7831     }
7832
7833   /* Construct the API message */
7834   M (BOND_DETACH_SLAVE, mp);
7835
7836   mp->sw_if_index = ntohl (sw_if_index);
7837
7838   /* send it... */
7839   S (mp);
7840
7841   /* Wait for a reply... */
7842   W (ret);
7843   return ret;
7844 }
7845
7846 static int
7847 api_ip_table_add_del (vat_main_t * vam)
7848 {
7849   unformat_input_t *i = vam->input;
7850   vl_api_ip_table_add_del_t *mp;
7851   u32 table_id = ~0;
7852   u8 is_ipv6 = 0;
7853   u8 is_add = 1;
7854   int ret = 0;
7855
7856   /* Parse args required to build the message */
7857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7858     {
7859       if (unformat (i, "ipv6"))
7860         is_ipv6 = 1;
7861       else if (unformat (i, "del"))
7862         is_add = 0;
7863       else if (unformat (i, "add"))
7864         is_add = 1;
7865       else if (unformat (i, "table %d", &table_id))
7866         ;
7867       else
7868         {
7869           clib_warning ("parse error '%U'", format_unformat_error, i);
7870           return -99;
7871         }
7872     }
7873
7874   if (~0 == table_id)
7875     {
7876       errmsg ("missing table-ID");
7877       return -99;
7878     }
7879
7880   /* Construct the API message */
7881   M (IP_TABLE_ADD_DEL, mp);
7882
7883   mp->table.table_id = ntohl (table_id);
7884   mp->table.is_ip6 = is_ipv6;
7885   mp->is_add = is_add;
7886
7887   /* send it... */
7888   S (mp);
7889
7890   /* Wait for a reply... */
7891   W (ret);
7892
7893   return ret;
7894 }
7895
7896 uword
7897 unformat_fib_path (unformat_input_t * input, va_list * args)
7898 {
7899   vat_main_t *vam = va_arg (*args, vat_main_t *);
7900   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7901   u32 weight, preference;
7902   mpls_label_t out_label;
7903
7904   clib_memset (path, 0, sizeof (*path));
7905   path->weight = 1;
7906   path->sw_if_index = ~0;
7907   path->rpf_id = ~0;
7908   path->n_labels = 0;
7909
7910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7911     {
7912       if (unformat (input, "%U %U",
7913                     unformat_vl_api_ip4_address,
7914                     &path->nh.address.ip4,
7915                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7916         {
7917           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7918         }
7919       else if (unformat (input, "%U %U",
7920                          unformat_vl_api_ip6_address,
7921                          &path->nh.address.ip6,
7922                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7923         {
7924           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7925         }
7926       else if (unformat (input, "weight %u", &weight))
7927         {
7928           path->weight = weight;
7929         }
7930       else if (unformat (input, "preference %u", &preference))
7931         {
7932           path->preference = preference;
7933         }
7934       else if (unformat (input, "%U next-hop-table %d",
7935                          unformat_vl_api_ip4_address,
7936                          &path->nh.address.ip4, &path->table_id))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7939         }
7940       else if (unformat (input, "%U next-hop-table %d",
7941                          unformat_vl_api_ip6_address,
7942                          &path->nh.address.ip6, &path->table_id))
7943         {
7944           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7945         }
7946       else if (unformat (input, "%U",
7947                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7948         {
7949           /*
7950            * the recursive next-hops are by default in the default table
7951            */
7952           path->table_id = 0;
7953           path->sw_if_index = ~0;
7954           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7955         }
7956       else if (unformat (input, "%U",
7957                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7958         {
7959           /*
7960            * the recursive next-hops are by default in the default table
7961            */
7962           path->table_id = 0;
7963           path->sw_if_index = ~0;
7964           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7965         }
7966       else if (unformat (input, "resolve-via-host"))
7967         {
7968           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7969         }
7970       else if (unformat (input, "resolve-via-attached"))
7971         {
7972           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7973         }
7974       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7975         {
7976           path->type = FIB_API_PATH_TYPE_LOCAL;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7979         }
7980       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7981         {
7982           path->type = FIB_API_PATH_TYPE_LOCAL;
7983           path->sw_if_index = ~0;
7984           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7985         }
7986       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7987         ;
7988       else if (unformat (input, "via-label %d", &path->nh.via_label))
7989         {
7990           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7991           path->sw_if_index = ~0;
7992         }
7993       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7994         {
7995           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7996           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7997         }
7998       else if (unformat (input, "local"))
7999         {
8000           path->type = FIB_API_PATH_TYPE_LOCAL;
8001         }
8002       else if (unformat (input, "out-labels"))
8003         {
8004           while (unformat (input, "%d", &out_label))
8005             {
8006               path->label_stack[path->n_labels].label = out_label;
8007               path->label_stack[path->n_labels].is_uniform = 0;
8008               path->label_stack[path->n_labels].ttl = 64;
8009               path->n_labels++;
8010             }
8011         }
8012       else if (unformat (input, "via"))
8013         {
8014           /* new path, back up and return */
8015           unformat_put_input (input);
8016           unformat_put_input (input);
8017           unformat_put_input (input);
8018           unformat_put_input (input);
8019           break;
8020         }
8021       else
8022         {
8023           return (0);
8024         }
8025     }
8026
8027   path->proto = ntohl (path->proto);
8028   path->type = ntohl (path->type);
8029   path->flags = ntohl (path->flags);
8030   path->table_id = ntohl (path->table_id);
8031   path->sw_if_index = ntohl (path->sw_if_index);
8032
8033   return (1);
8034 }
8035
8036 static int
8037 api_ip_route_add_del (vat_main_t * vam)
8038 {
8039   unformat_input_t *i = vam->input;
8040   vl_api_ip_route_add_del_t *mp;
8041   u32 vrf_id = 0;
8042   u8 is_add = 1;
8043   u8 is_multipath = 0;
8044   u8 prefix_set = 0;
8045   u8 path_count = 0;
8046   vl_api_prefix_t pfx = { };
8047   vl_api_fib_path_t paths[8];
8048   int count = 1;
8049   int j;
8050   f64 before = 0;
8051   u32 random_add_del = 0;
8052   u32 *random_vector = 0;
8053   u32 random_seed = 0xdeaddabe;
8054
8055   /* Parse args required to build the message */
8056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8057     {
8058       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8059         prefix_set = 1;
8060       else if (unformat (i, "del"))
8061         is_add = 0;
8062       else if (unformat (i, "add"))
8063         is_add = 1;
8064       else if (unformat (i, "vrf %d", &vrf_id))
8065         ;
8066       else if (unformat (i, "count %d", &count))
8067         ;
8068       else if (unformat (i, "random"))
8069         random_add_del = 1;
8070       else if (unformat (i, "multipath"))
8071         is_multipath = 1;
8072       else if (unformat (i, "seed %d", &random_seed))
8073         ;
8074       else
8075         if (unformat
8076             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8077         {
8078           path_count++;
8079           if (8 == path_count)
8080             {
8081               errmsg ("max 8 paths");
8082               return -99;
8083             }
8084         }
8085       else
8086         {
8087           clib_warning ("parse error '%U'", format_unformat_error, i);
8088           return -99;
8089         }
8090     }
8091
8092   if (!path_count)
8093     {
8094       errmsg ("specify a path; via ...");
8095       return -99;
8096     }
8097   if (prefix_set == 0)
8098     {
8099       errmsg ("missing prefix");
8100       return -99;
8101     }
8102
8103   /* Generate a pile of unique, random routes */
8104   if (random_add_del)
8105     {
8106       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8107       u32 this_random_address;
8108       uword *random_hash;
8109
8110       random_hash = hash_create (count, sizeof (uword));
8111
8112       hash_set (random_hash, i->as_u32, 1);
8113       for (j = 0; j <= count; j++)
8114         {
8115           do
8116             {
8117               this_random_address = random_u32 (&random_seed);
8118               this_random_address =
8119                 clib_host_to_net_u32 (this_random_address);
8120             }
8121           while (hash_get (random_hash, this_random_address));
8122           vec_add1 (random_vector, this_random_address);
8123           hash_set (random_hash, this_random_address, 1);
8124         }
8125       hash_free (random_hash);
8126       set_ip4_address (&pfx.address, random_vector[0]);
8127     }
8128
8129   if (count > 1)
8130     {
8131       /* Turn on async mode */
8132       vam->async_mode = 1;
8133       vam->async_errors = 0;
8134       before = vat_time_now (vam);
8135     }
8136
8137   for (j = 0; j < count; j++)
8138     {
8139       /* Construct the API message */
8140       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8141
8142       mp->is_add = is_add;
8143       mp->is_multipath = is_multipath;
8144
8145       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8146       mp->route.table_id = ntohl (vrf_id);
8147       mp->route.n_paths = path_count;
8148
8149       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8150
8151       if (random_add_del)
8152         set_ip4_address (&pfx.address, random_vector[j + 1]);
8153       else
8154         increment_address (&pfx.address);
8155       /* send it... */
8156       S (mp);
8157       /* If we receive SIGTERM, stop now... */
8158       if (vam->do_exit)
8159         break;
8160     }
8161
8162   /* When testing multiple add/del ops, use a control-ping to sync */
8163   if (count > 1)
8164     {
8165       vl_api_control_ping_t *mp_ping;
8166       f64 after;
8167       f64 timeout;
8168
8169       /* Shut off async mode */
8170       vam->async_mode = 0;
8171
8172       MPING (CONTROL_PING, mp_ping);
8173       S (mp_ping);
8174
8175       timeout = vat_time_now (vam) + 1.0;
8176       while (vat_time_now (vam) < timeout)
8177         if (vam->result_ready == 1)
8178           goto out;
8179       vam->retval = -99;
8180
8181     out:
8182       if (vam->retval == -99)
8183         errmsg ("timeout");
8184
8185       if (vam->async_errors > 0)
8186         {
8187           errmsg ("%d asynchronous errors", vam->async_errors);
8188           vam->retval = -98;
8189         }
8190       vam->async_errors = 0;
8191       after = vat_time_now (vam);
8192
8193       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8194       if (j > 0)
8195         count = j;
8196
8197       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8198              count, after - before, count / (after - before));
8199     }
8200   else
8201     {
8202       int ret;
8203
8204       /* Wait for a reply... */
8205       W (ret);
8206       return ret;
8207     }
8208
8209   /* Return the good/bad news */
8210   return (vam->retval);
8211 }
8212
8213 static int
8214 api_ip_mroute_add_del (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   u8 path_set = 0, prefix_set = 0, is_add = 1;
8218   vl_api_ip_mroute_add_del_t *mp;
8219   mfib_entry_flags_t eflags = 0;
8220   vl_api_mfib_path_t path;
8221   vl_api_mprefix_t pfx = { };
8222   u32 vrf_id = 0;
8223   int ret;
8224
8225   /* Parse args required to build the message */
8226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8227     {
8228       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8229         {
8230           prefix_set = 1;
8231           pfx.grp_address_length = htons (pfx.grp_address_length);
8232         }
8233       else if (unformat (i, "del"))
8234         is_add = 0;
8235       else if (unformat (i, "add"))
8236         is_add = 1;
8237       else if (unformat (i, "vrf %d", &vrf_id))
8238         ;
8239       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8240         path.itf_flags = htonl (path.itf_flags);
8241       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8242         ;
8243       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8244         path_set = 1;
8245       else
8246         {
8247           clib_warning ("parse error '%U'", format_unformat_error, i);
8248           return -99;
8249         }
8250     }
8251
8252   if (prefix_set == 0)
8253     {
8254       errmsg ("missing addresses\n");
8255       return -99;
8256     }
8257   if (path_set == 0)
8258     {
8259       errmsg ("missing path\n");
8260       return -99;
8261     }
8262
8263   /* Construct the API message */
8264   M (IP_MROUTE_ADD_DEL, mp);
8265
8266   mp->is_add = is_add;
8267   mp->is_multipath = 1;
8268
8269   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8270   mp->route.table_id = htonl (vrf_id);
8271   mp->route.n_paths = 1;
8272   mp->route.entry_flags = htonl (eflags);
8273
8274   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8275
8276   /* send it... */
8277   S (mp);
8278   /* Wait for a reply... */
8279   W (ret);
8280   return ret;
8281 }
8282
8283 static int
8284 api_mpls_table_add_del (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_mpls_table_add_del_t *mp;
8288   u32 table_id = ~0;
8289   u8 is_add = 1;
8290   int ret = 0;
8291
8292   /* Parse args required to build the message */
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "table %d", &table_id))
8296         ;
8297       else if (unformat (i, "del"))
8298         is_add = 0;
8299       else if (unformat (i, "add"))
8300         is_add = 1;
8301       else
8302         {
8303           clib_warning ("parse error '%U'", format_unformat_error, i);
8304           return -99;
8305         }
8306     }
8307
8308   if (~0 == table_id)
8309     {
8310       errmsg ("missing table-ID");
8311       return -99;
8312     }
8313
8314   /* Construct the API message */
8315   M (MPLS_TABLE_ADD_DEL, mp);
8316
8317   mp->mt_table.mt_table_id = ntohl (table_id);
8318   mp->mt_is_add = is_add;
8319
8320   /* send it... */
8321   S (mp);
8322
8323   /* Wait for a reply... */
8324   W (ret);
8325
8326   return ret;
8327 }
8328
8329 static int
8330 api_mpls_route_add_del (vat_main_t * vam)
8331 {
8332   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8333   mpls_label_t local_label = MPLS_LABEL_INVALID;
8334   unformat_input_t *i = vam->input;
8335   vl_api_mpls_route_add_del_t *mp;
8336   vl_api_fib_path_t paths[8];
8337   int count = 1, j;
8338   f64 before = 0;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "%d", &local_label))
8344         ;
8345       else if (unformat (i, "eos"))
8346         is_eos = 1;
8347       else if (unformat (i, "non-eos"))
8348         is_eos = 0;
8349       else if (unformat (i, "del"))
8350         is_add = 0;
8351       else if (unformat (i, "add"))
8352         is_add = 1;
8353       else if (unformat (i, "multipath"))
8354         is_multipath = 1;
8355       else if (unformat (i, "count %d", &count))
8356         ;
8357       else
8358         if (unformat
8359             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8360         {
8361           path_count++;
8362           if (8 == path_count)
8363             {
8364               errmsg ("max 8 paths");
8365               return -99;
8366             }
8367         }
8368       else
8369         {
8370           clib_warning ("parse error '%U'", format_unformat_error, i);
8371           return -99;
8372         }
8373     }
8374
8375   if (!path_count)
8376     {
8377       errmsg ("specify a path; via ...");
8378       return -99;
8379     }
8380
8381   if (MPLS_LABEL_INVALID == local_label)
8382     {
8383       errmsg ("missing label");
8384       return -99;
8385     }
8386
8387   if (count > 1)
8388     {
8389       /* Turn on async mode */
8390       vam->async_mode = 1;
8391       vam->async_errors = 0;
8392       before = vat_time_now (vam);
8393     }
8394
8395   for (j = 0; j < count; j++)
8396     {
8397       /* Construct the API message */
8398       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8399
8400       mp->mr_is_add = is_add;
8401       mp->mr_is_multipath = is_multipath;
8402
8403       mp->mr_route.mr_label = local_label;
8404       mp->mr_route.mr_eos = is_eos;
8405       mp->mr_route.mr_table_id = 0;
8406       mp->mr_route.mr_n_paths = path_count;
8407
8408       clib_memcpy (&mp->mr_route.mr_paths, paths,
8409                    sizeof (paths[0]) * path_count);
8410
8411       local_label++;
8412
8413       /* send it... */
8414       S (mp);
8415       /* If we receive SIGTERM, stop now... */
8416       if (vam->do_exit)
8417         break;
8418     }
8419
8420   /* When testing multiple add/del ops, use a control-ping to sync */
8421   if (count > 1)
8422     {
8423       vl_api_control_ping_t *mp_ping;
8424       f64 after;
8425       f64 timeout;
8426
8427       /* Shut off async mode */
8428       vam->async_mode = 0;
8429
8430       MPING (CONTROL_PING, mp_ping);
8431       S (mp_ping);
8432
8433       timeout = vat_time_now (vam) + 1.0;
8434       while (vat_time_now (vam) < timeout)
8435         if (vam->result_ready == 1)
8436           goto out;
8437       vam->retval = -99;
8438
8439     out:
8440       if (vam->retval == -99)
8441         errmsg ("timeout");
8442
8443       if (vam->async_errors > 0)
8444         {
8445           errmsg ("%d asynchronous errors", vam->async_errors);
8446           vam->retval = -98;
8447         }
8448       vam->async_errors = 0;
8449       after = vat_time_now (vam);
8450
8451       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8452       if (j > 0)
8453         count = j;
8454
8455       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8456              count, after - before, count / (after - before));
8457     }
8458   else
8459     {
8460       int ret;
8461
8462       /* Wait for a reply... */
8463       W (ret);
8464       return ret;
8465     }
8466
8467   /* Return the good/bad news */
8468   return (vam->retval);
8469   return (0);
8470 }
8471
8472 static int
8473 api_mpls_ip_bind_unbind (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_mpls_ip_bind_unbind_t *mp;
8477   u32 ip_table_id = 0;
8478   u8 is_bind = 1;
8479   vl_api_prefix_t pfx;
8480   u8 prefix_set = 0;
8481   mpls_label_t local_label = MPLS_LABEL_INVALID;
8482   int ret;
8483
8484   /* Parse args required to build the message */
8485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8486     {
8487       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8488         prefix_set = 1;
8489       else if (unformat (i, "%d", &local_label))
8490         ;
8491       else if (unformat (i, "table-id %d", &ip_table_id))
8492         ;
8493       else if (unformat (i, "unbind"))
8494         is_bind = 0;
8495       else if (unformat (i, "bind"))
8496         is_bind = 1;
8497       else
8498         {
8499           clib_warning ("parse error '%U'", format_unformat_error, i);
8500           return -99;
8501         }
8502     }
8503
8504   if (!prefix_set)
8505     {
8506       errmsg ("IP prefix not set");
8507       return -99;
8508     }
8509
8510   if (MPLS_LABEL_INVALID == local_label)
8511     {
8512       errmsg ("missing label");
8513       return -99;
8514     }
8515
8516   /* Construct the API message */
8517   M (MPLS_IP_BIND_UNBIND, mp);
8518
8519   mp->mb_is_bind = is_bind;
8520   mp->mb_ip_table_id = ntohl (ip_table_id);
8521   mp->mb_mpls_table_id = 0;
8522   mp->mb_label = ntohl (local_label);
8523   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8524
8525   /* send it... */
8526   S (mp);
8527
8528   /* Wait for a reply... */
8529   W (ret);
8530   return ret;
8531   return (0);
8532 }
8533
8534 static int
8535 api_sr_mpls_policy_add (vat_main_t * vam)
8536 {
8537   unformat_input_t *i = vam->input;
8538   vl_api_sr_mpls_policy_add_t *mp;
8539   u32 bsid = 0;
8540   u32 weight = 1;
8541   u8 type = 0;
8542   u8 n_segments = 0;
8543   u32 sid;
8544   u32 *segments = NULL;
8545   int ret;
8546
8547   /* Parse args required to build the message */
8548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8549     {
8550       if (unformat (i, "bsid %d", &bsid))
8551         ;
8552       else if (unformat (i, "weight %d", &weight))
8553         ;
8554       else if (unformat (i, "spray"))
8555         type = 1;
8556       else if (unformat (i, "next %d", &sid))
8557         {
8558           n_segments += 1;
8559           vec_add1 (segments, htonl (sid));
8560         }
8561       else
8562         {
8563           clib_warning ("parse error '%U'", format_unformat_error, i);
8564           return -99;
8565         }
8566     }
8567
8568   if (bsid == 0)
8569     {
8570       errmsg ("bsid not set");
8571       return -99;
8572     }
8573
8574   if (n_segments == 0)
8575     {
8576       errmsg ("no sid in segment stack");
8577       return -99;
8578     }
8579
8580   /* Construct the API message */
8581   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8582
8583   mp->bsid = htonl (bsid);
8584   mp->weight = htonl (weight);
8585   mp->is_spray = type;
8586   mp->n_segments = n_segments;
8587   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8588   vec_free (segments);
8589
8590   /* send it... */
8591   S (mp);
8592
8593   /* Wait for a reply... */
8594   W (ret);
8595   return ret;
8596 }
8597
8598 static int
8599 api_sr_mpls_policy_del (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_sr_mpls_policy_del_t *mp;
8603   u32 bsid = 0;
8604   int ret;
8605
8606   /* Parse args required to build the message */
8607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8608     {
8609       if (unformat (i, "bsid %d", &bsid))
8610         ;
8611       else
8612         {
8613           clib_warning ("parse error '%U'", format_unformat_error, i);
8614           return -99;
8615         }
8616     }
8617
8618   if (bsid == 0)
8619     {
8620       errmsg ("bsid not set");
8621       return -99;
8622     }
8623
8624   /* Construct the API message */
8625   M (SR_MPLS_POLICY_DEL, mp);
8626
8627   mp->bsid = htonl (bsid);
8628
8629   /* send it... */
8630   S (mp);
8631
8632   /* Wait for a reply... */
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_bier_table_add_del (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_bier_table_add_del_t *mp;
8642   u8 is_add = 1;
8643   u32 set = 0, sub_domain = 0, hdr_len = 3;
8644   mpls_label_t local_label = MPLS_LABEL_INVALID;
8645   int ret;
8646
8647   /* Parse args required to build the message */
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "sub-domain %d", &sub_domain))
8651         ;
8652       else if (unformat (i, "set %d", &set))
8653         ;
8654       else if (unformat (i, "label %d", &local_label))
8655         ;
8656       else if (unformat (i, "hdr-len %d", &hdr_len))
8657         ;
8658       else if (unformat (i, "add"))
8659         is_add = 1;
8660       else if (unformat (i, "del"))
8661         is_add = 0;
8662       else
8663         {
8664           clib_warning ("parse error '%U'", format_unformat_error, i);
8665           return -99;
8666         }
8667     }
8668
8669   if (MPLS_LABEL_INVALID == local_label)
8670     {
8671       errmsg ("missing label\n");
8672       return -99;
8673     }
8674
8675   /* Construct the API message */
8676   M (BIER_TABLE_ADD_DEL, mp);
8677
8678   mp->bt_is_add = is_add;
8679   mp->bt_label = ntohl (local_label);
8680   mp->bt_tbl_id.bt_set = set;
8681   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8682   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8683
8684   /* send it... */
8685   S (mp);
8686
8687   /* Wait for a reply... */
8688   W (ret);
8689
8690   return (ret);
8691 }
8692
8693 static int
8694 api_bier_route_add_del (vat_main_t * vam)
8695 {
8696   unformat_input_t *i = vam->input;
8697   vl_api_bier_route_add_del_t *mp;
8698   u8 is_add = 1;
8699   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8700   ip4_address_t v4_next_hop_address;
8701   ip6_address_t v6_next_hop_address;
8702   u8 next_hop_set = 0;
8703   u8 next_hop_proto_is_ip4 = 1;
8704   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8705   int ret;
8706
8707   /* Parse args required to build the message */
8708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8709     {
8710       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8711         {
8712           next_hop_proto_is_ip4 = 1;
8713           next_hop_set = 1;
8714         }
8715       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8716         {
8717           next_hop_proto_is_ip4 = 0;
8718           next_hop_set = 1;
8719         }
8720       if (unformat (i, "sub-domain %d", &sub_domain))
8721         ;
8722       else if (unformat (i, "set %d", &set))
8723         ;
8724       else if (unformat (i, "hdr-len %d", &hdr_len))
8725         ;
8726       else if (unformat (i, "bp %d", &bp))
8727         ;
8728       else if (unformat (i, "add"))
8729         is_add = 1;
8730       else if (unformat (i, "del"))
8731         is_add = 0;
8732       else if (unformat (i, "out-label %d", &next_hop_out_label))
8733         ;
8734       else
8735         {
8736           clib_warning ("parse error '%U'", format_unformat_error, i);
8737           return -99;
8738         }
8739     }
8740
8741   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8742     {
8743       errmsg ("next hop / label set\n");
8744       return -99;
8745     }
8746   if (0 == bp)
8747     {
8748       errmsg ("bit=position not set\n");
8749       return -99;
8750     }
8751
8752   /* Construct the API message */
8753   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8754
8755   mp->br_is_add = is_add;
8756   mp->br_route.br_tbl_id.bt_set = set;
8757   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8758   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8759   mp->br_route.br_bp = ntohs (bp);
8760   mp->br_route.br_n_paths = 1;
8761   mp->br_route.br_paths[0].n_labels = 1;
8762   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8763   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8764                                     FIB_API_PATH_NH_PROTO_IP4 :
8765                                     FIB_API_PATH_NH_PROTO_IP6);
8766
8767   if (next_hop_proto_is_ip4)
8768     {
8769       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8770                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8771     }
8772   else
8773     {
8774       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8775                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8776     }
8777
8778   /* send it... */
8779   S (mp);
8780
8781   /* Wait for a reply... */
8782   W (ret);
8783
8784   return (ret);
8785 }
8786
8787 static int
8788 api_mpls_tunnel_add_del (vat_main_t * vam)
8789 {
8790   unformat_input_t *i = vam->input;
8791   vl_api_mpls_tunnel_add_del_t *mp;
8792
8793   vl_api_fib_path_t paths[8];
8794   u32 sw_if_index = ~0;
8795   u8 path_count = 0;
8796   u8 l2_only = 0;
8797   u8 is_add = 1;
8798   int ret;
8799
8800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8801     {
8802       if (unformat (i, "add"))
8803         is_add = 1;
8804       else
8805         if (unformat
8806             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8807         is_add = 0;
8808       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8809         is_add = 0;
8810       else if (unformat (i, "l2-only"))
8811         l2_only = 1;
8812       else
8813         if (unformat
8814             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8815         {
8816           path_count++;
8817           if (8 == path_count)
8818             {
8819               errmsg ("max 8 paths");
8820               return -99;
8821             }
8822         }
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8831
8832   mp->mt_is_add = is_add;
8833   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8834   mp->mt_tunnel.mt_l2_only = l2_only;
8835   mp->mt_tunnel.mt_is_multicast = 0;
8836   mp->mt_tunnel.mt_n_paths = path_count;
8837
8838   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8839                sizeof (paths[0]) * path_count);
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_sw_interface_set_unnumbered (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_sw_interface_set_unnumbered_t *mp;
8851   u32 sw_if_index;
8852   u32 unnum_sw_index = ~0;
8853   u8 is_add = 1;
8854   u8 sw_if_index_set = 0;
8855   int ret;
8856
8857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8862         sw_if_index_set = 1;
8863       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8864         ;
8865       else if (unformat (i, "del"))
8866         is_add = 0;
8867       else
8868         {
8869           clib_warning ("parse error '%U'", format_unformat_error, i);
8870           return -99;
8871         }
8872     }
8873
8874   if (sw_if_index_set == 0)
8875     {
8876       errmsg ("missing interface name or sw_if_index");
8877       return -99;
8878     }
8879
8880   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8881
8882   mp->sw_if_index = ntohl (sw_if_index);
8883   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8884   mp->is_add = is_add;
8885
8886   S (mp);
8887   W (ret);
8888   return ret;
8889 }
8890
8891
8892 static int
8893 api_create_vlan_subif (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_create_vlan_subif_t *mp;
8897   u32 sw_if_index;
8898   u8 sw_if_index_set = 0;
8899   u32 vlan_id;
8900   u8 vlan_id_set = 0;
8901   int ret;
8902
8903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8904     {
8905       if (unformat (i, "sw_if_index %d", &sw_if_index))
8906         sw_if_index_set = 1;
8907       else
8908         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8909         sw_if_index_set = 1;
8910       else if (unformat (i, "vlan %d", &vlan_id))
8911         vlan_id_set = 1;
8912       else
8913         {
8914           clib_warning ("parse error '%U'", format_unformat_error, i);
8915           return -99;
8916         }
8917     }
8918
8919   if (sw_if_index_set == 0)
8920     {
8921       errmsg ("missing interface name or sw_if_index");
8922       return -99;
8923     }
8924
8925   if (vlan_id_set == 0)
8926     {
8927       errmsg ("missing vlan_id");
8928       return -99;
8929     }
8930   M (CREATE_VLAN_SUBIF, mp);
8931
8932   mp->sw_if_index = ntohl (sw_if_index);
8933   mp->vlan_id = ntohl (vlan_id);
8934
8935   S (mp);
8936   W (ret);
8937   return ret;
8938 }
8939
8940 #define foreach_create_subif_bit                \
8941 _(no_tags)                                      \
8942 _(one_tag)                                      \
8943 _(two_tags)                                     \
8944 _(dot1ad)                                       \
8945 _(exact_match)                                  \
8946 _(default_sub)                                  \
8947 _(outer_vlan_id_any)                            \
8948 _(inner_vlan_id_any)
8949
8950 #define foreach_create_subif_flag               \
8951 _(0, "no_tags")                                 \
8952 _(1, "one_tag")                                 \
8953 _(2, "two_tags")                                \
8954 _(3, "dot1ad")                                  \
8955 _(4, "exact_match")                             \
8956 _(5, "default_sub")                             \
8957 _(6, "outer_vlan_id_any")                       \
8958 _(7, "inner_vlan_id_any")
8959
8960 static int
8961 api_create_subif (vat_main_t * vam)
8962 {
8963   unformat_input_t *i = vam->input;
8964   vl_api_create_subif_t *mp;
8965   u32 sw_if_index;
8966   u8 sw_if_index_set = 0;
8967   u32 sub_id;
8968   u8 sub_id_set = 0;
8969   u32 __attribute__ ((unused)) no_tags = 0;
8970   u32 __attribute__ ((unused)) one_tag = 0;
8971   u32 __attribute__ ((unused)) two_tags = 0;
8972   u32 __attribute__ ((unused)) dot1ad = 0;
8973   u32 __attribute__ ((unused)) exact_match = 0;
8974   u32 __attribute__ ((unused)) default_sub = 0;
8975   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8976   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8977   u32 tmp;
8978   u16 outer_vlan_id = 0;
8979   u16 inner_vlan_id = 0;
8980   int ret;
8981
8982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8983     {
8984       if (unformat (i, "sw_if_index %d", &sw_if_index))
8985         sw_if_index_set = 1;
8986       else
8987         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8988         sw_if_index_set = 1;
8989       else if (unformat (i, "sub_id %d", &sub_id))
8990         sub_id_set = 1;
8991       else if (unformat (i, "outer_vlan_id %d", &tmp))
8992         outer_vlan_id = tmp;
8993       else if (unformat (i, "inner_vlan_id %d", &tmp))
8994         inner_vlan_id = tmp;
8995
8996 #define _(a) else if (unformat (i, #a)) a = 1 ;
8997       foreach_create_subif_bit
8998 #undef _
8999         else
9000         {
9001           clib_warning ("parse error '%U'", format_unformat_error, i);
9002           return -99;
9003         }
9004     }
9005
9006   if (sw_if_index_set == 0)
9007     {
9008       errmsg ("missing interface name or sw_if_index");
9009       return -99;
9010     }
9011
9012   if (sub_id_set == 0)
9013     {
9014       errmsg ("missing sub_id");
9015       return -99;
9016     }
9017   M (CREATE_SUBIF, mp);
9018
9019   mp->sw_if_index = ntohl (sw_if_index);
9020   mp->sub_id = ntohl (sub_id);
9021
9022 #define _(a,b) mp->sub_if_flags |= (1 << a);
9023   foreach_create_subif_flag;
9024 #undef _
9025
9026   mp->outer_vlan_id = ntohs (outer_vlan_id);
9027   mp->inner_vlan_id = ntohs (inner_vlan_id);
9028
9029   S (mp);
9030   W (ret);
9031   return ret;
9032 }
9033
9034 static int
9035 api_ip_table_replace_begin (vat_main_t * vam)
9036 {
9037   unformat_input_t *i = vam->input;
9038   vl_api_ip_table_replace_begin_t *mp;
9039   u32 table_id = 0;
9040   u8 is_ipv6 = 0;
9041
9042   int ret;
9043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9044     {
9045       if (unformat (i, "table %d", &table_id))
9046         ;
9047       else if (unformat (i, "ipv6"))
9048         is_ipv6 = 1;
9049       else
9050         {
9051           clib_warning ("parse error '%U'", format_unformat_error, i);
9052           return -99;
9053         }
9054     }
9055
9056   M (IP_TABLE_REPLACE_BEGIN, mp);
9057
9058   mp->table.table_id = ntohl (table_id);
9059   mp->table.is_ip6 = is_ipv6;
9060
9061   S (mp);
9062   W (ret);
9063   return ret;
9064 }
9065
9066 static int
9067 api_ip_table_flush (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_ip_table_flush_t *mp;
9071   u32 table_id = 0;
9072   u8 is_ipv6 = 0;
9073
9074   int ret;
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "table %d", &table_id))
9078         ;
9079       else if (unformat (i, "ipv6"))
9080         is_ipv6 = 1;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   M (IP_TABLE_FLUSH, mp);
9089
9090   mp->table.table_id = ntohl (table_id);
9091   mp->table.is_ip6 = is_ipv6;
9092
9093   S (mp);
9094   W (ret);
9095   return ret;
9096 }
9097
9098 static int
9099 api_ip_table_replace_end (vat_main_t * vam)
9100 {
9101   unformat_input_t *i = vam->input;
9102   vl_api_ip_table_replace_end_t *mp;
9103   u32 table_id = 0;
9104   u8 is_ipv6 = 0;
9105
9106   int ret;
9107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9108     {
9109       if (unformat (i, "table %d", &table_id))
9110         ;
9111       else if (unformat (i, "ipv6"))
9112         is_ipv6 = 1;
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   M (IP_TABLE_REPLACE_END, mp);
9121
9122   mp->table.table_id = ntohl (table_id);
9123   mp->table.is_ip6 = is_ipv6;
9124
9125   S (mp);
9126   W (ret);
9127   return ret;
9128 }
9129
9130 static int
9131 api_set_ip_flow_hash (vat_main_t * vam)
9132 {
9133   unformat_input_t *i = vam->input;
9134   vl_api_set_ip_flow_hash_t *mp;
9135   u32 vrf_id = 0;
9136   u8 is_ipv6 = 0;
9137   u8 vrf_id_set = 0;
9138   u8 src = 0;
9139   u8 dst = 0;
9140   u8 sport = 0;
9141   u8 dport = 0;
9142   u8 proto = 0;
9143   u8 reverse = 0;
9144   int ret;
9145
9146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (i, "vrf %d", &vrf_id))
9149         vrf_id_set = 1;
9150       else if (unformat (i, "ipv6"))
9151         is_ipv6 = 1;
9152       else if (unformat (i, "src"))
9153         src = 1;
9154       else if (unformat (i, "dst"))
9155         dst = 1;
9156       else if (unformat (i, "sport"))
9157         sport = 1;
9158       else if (unformat (i, "dport"))
9159         dport = 1;
9160       else if (unformat (i, "proto"))
9161         proto = 1;
9162       else if (unformat (i, "reverse"))
9163         reverse = 1;
9164
9165       else
9166         {
9167           clib_warning ("parse error '%U'", format_unformat_error, i);
9168           return -99;
9169         }
9170     }
9171
9172   if (vrf_id_set == 0)
9173     {
9174       errmsg ("missing vrf id");
9175       return -99;
9176     }
9177
9178   M (SET_IP_FLOW_HASH, mp);
9179   mp->src = src;
9180   mp->dst = dst;
9181   mp->sport = sport;
9182   mp->dport = dport;
9183   mp->proto = proto;
9184   mp->reverse = reverse;
9185   mp->vrf_id = ntohl (vrf_id);
9186   mp->is_ipv6 = is_ipv6;
9187
9188   S (mp);
9189   W (ret);
9190   return ret;
9191 }
9192
9193 static int
9194 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9195 {
9196   unformat_input_t *i = vam->input;
9197   vl_api_sw_interface_ip6_enable_disable_t *mp;
9198   u32 sw_if_index;
9199   u8 sw_if_index_set = 0;
9200   u8 enable = 0;
9201   int ret;
9202
9203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9204     {
9205       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9206         sw_if_index_set = 1;
9207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9208         sw_if_index_set = 1;
9209       else if (unformat (i, "enable"))
9210         enable = 1;
9211       else if (unformat (i, "disable"))
9212         enable = 0;
9213       else
9214         {
9215           clib_warning ("parse error '%U'", format_unformat_error, i);
9216           return -99;
9217         }
9218     }
9219
9220   if (sw_if_index_set == 0)
9221     {
9222       errmsg ("missing interface name or sw_if_index");
9223       return -99;
9224     }
9225
9226   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9227
9228   mp->sw_if_index = ntohl (sw_if_index);
9229   mp->enable = enable;
9230
9231   S (mp);
9232   W (ret);
9233   return ret;
9234 }
9235
9236
9237 static int
9238 api_l2_patch_add_del (vat_main_t * vam)
9239 {
9240   unformat_input_t *i = vam->input;
9241   vl_api_l2_patch_add_del_t *mp;
9242   u32 rx_sw_if_index;
9243   u8 rx_sw_if_index_set = 0;
9244   u32 tx_sw_if_index;
9245   u8 tx_sw_if_index_set = 0;
9246   u8 is_add = 1;
9247   int ret;
9248
9249   /* Parse args required to build the message */
9250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9251     {
9252       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9253         rx_sw_if_index_set = 1;
9254       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9255         tx_sw_if_index_set = 1;
9256       else if (unformat (i, "rx"))
9257         {
9258           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9259             {
9260               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9261                             &rx_sw_if_index))
9262                 rx_sw_if_index_set = 1;
9263             }
9264           else
9265             break;
9266         }
9267       else if (unformat (i, "tx"))
9268         {
9269           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270             {
9271               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9272                             &tx_sw_if_index))
9273                 tx_sw_if_index_set = 1;
9274             }
9275           else
9276             break;
9277         }
9278       else if (unformat (i, "del"))
9279         is_add = 0;
9280       else
9281         break;
9282     }
9283
9284   if (rx_sw_if_index_set == 0)
9285     {
9286       errmsg ("missing rx interface name or rx_sw_if_index");
9287       return -99;
9288     }
9289
9290   if (tx_sw_if_index_set == 0)
9291     {
9292       errmsg ("missing tx interface name or tx_sw_if_index");
9293       return -99;
9294     }
9295
9296   M (L2_PATCH_ADD_DEL, mp);
9297
9298   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9299   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9300   mp->is_add = is_add;
9301
9302   S (mp);
9303   W (ret);
9304   return ret;
9305 }
9306
9307 u8 is_del;
9308 u8 localsid_addr[16];
9309 u8 end_psp;
9310 u8 behavior;
9311 u32 sw_if_index;
9312 u32 vlan_index;
9313 u32 fib_table;
9314 u8 nh_addr[16];
9315
9316 static int
9317 api_sr_localsid_add_del (vat_main_t * vam)
9318 {
9319   unformat_input_t *i = vam->input;
9320   vl_api_sr_localsid_add_del_t *mp;
9321
9322   u8 is_del;
9323   ip6_address_t localsid;
9324   u8 end_psp = 0;
9325   u8 behavior = ~0;
9326   u32 sw_if_index;
9327   u32 fib_table = ~(u32) 0;
9328   ip6_address_t nh_addr6;
9329   ip4_address_t nh_addr4;
9330   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9331   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9332
9333   bool nexthop_set = 0;
9334
9335   int ret;
9336
9337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9338     {
9339       if (unformat (i, "del"))
9340         is_del = 1;
9341       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9342       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9343         nexthop_set = 1;
9344       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9345         nexthop_set = 1;
9346       else if (unformat (i, "behavior %u", &behavior));
9347       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9348       else if (unformat (i, "fib-table %u", &fib_table));
9349       else if (unformat (i, "end.psp %u", &behavior));
9350       else
9351         break;
9352     }
9353
9354   M (SR_LOCALSID_ADD_DEL, mp);
9355
9356   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9357
9358   if (nexthop_set)
9359     {
9360       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9361       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9362     }
9363   mp->behavior = behavior;
9364   mp->sw_if_index = ntohl (sw_if_index);
9365   mp->fib_table = ntohl (fib_table);
9366   mp->end_psp = end_psp;
9367   mp->is_del = is_del;
9368
9369   S (mp);
9370   W (ret);
9371   return ret;
9372 }
9373
9374 static int
9375 api_ioam_enable (vat_main_t * vam)
9376 {
9377   unformat_input_t *input = vam->input;
9378   vl_api_ioam_enable_t *mp;
9379   u32 id = 0;
9380   int has_trace_option = 0;
9381   int has_pot_option = 0;
9382   int has_seqno_option = 0;
9383   int has_analyse_option = 0;
9384   int ret;
9385
9386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9387     {
9388       if (unformat (input, "trace"))
9389         has_trace_option = 1;
9390       else if (unformat (input, "pot"))
9391         has_pot_option = 1;
9392       else if (unformat (input, "seqno"))
9393         has_seqno_option = 1;
9394       else if (unformat (input, "analyse"))
9395         has_analyse_option = 1;
9396       else
9397         break;
9398     }
9399   M (IOAM_ENABLE, mp);
9400   mp->id = htons (id);
9401   mp->seqno = has_seqno_option;
9402   mp->analyse = has_analyse_option;
9403   mp->pot_enable = has_pot_option;
9404   mp->trace_enable = has_trace_option;
9405
9406   S (mp);
9407   W (ret);
9408   return ret;
9409 }
9410
9411
9412 static int
9413 api_ioam_disable (vat_main_t * vam)
9414 {
9415   vl_api_ioam_disable_t *mp;
9416   int ret;
9417
9418   M (IOAM_DISABLE, mp);
9419   S (mp);
9420   W (ret);
9421   return ret;
9422 }
9423
9424 #define foreach_tcp_proto_field                 \
9425 _(src_port)                                     \
9426 _(dst_port)
9427
9428 #define foreach_udp_proto_field                 \
9429 _(src_port)                                     \
9430 _(dst_port)
9431
9432 #define foreach_ip4_proto_field                 \
9433 _(src_address)                                  \
9434 _(dst_address)                                  \
9435 _(tos)                                          \
9436 _(length)                                       \
9437 _(fragment_id)                                  \
9438 _(ttl)                                          \
9439 _(protocol)                                     \
9440 _(checksum)
9441
9442 typedef struct
9443 {
9444   u16 src_port, dst_port;
9445 } tcpudp_header_t;
9446
9447 #if VPP_API_TEST_BUILTIN == 0
9448 uword
9449 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9450 {
9451   u8 **maskp = va_arg (*args, u8 **);
9452   u8 *mask = 0;
9453   u8 found_something = 0;
9454   tcp_header_t *tcp;
9455
9456 #define _(a) u8 a=0;
9457   foreach_tcp_proto_field;
9458 #undef _
9459
9460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (0);
9463 #define _(a) else if (unformat (input, #a)) a=1;
9464       foreach_tcp_proto_field
9465 #undef _
9466         else
9467         break;
9468     }
9469
9470 #define _(a) found_something += a;
9471   foreach_tcp_proto_field;
9472 #undef _
9473
9474   if (found_something == 0)
9475     return 0;
9476
9477   vec_validate (mask, sizeof (*tcp) - 1);
9478
9479   tcp = (tcp_header_t *) mask;
9480
9481 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9482   foreach_tcp_proto_field;
9483 #undef _
9484
9485   *maskp = mask;
9486   return 1;
9487 }
9488
9489 uword
9490 unformat_udp_mask (unformat_input_t * input, va_list * args)
9491 {
9492   u8 **maskp = va_arg (*args, u8 **);
9493   u8 *mask = 0;
9494   u8 found_something = 0;
9495   udp_header_t *udp;
9496
9497 #define _(a) u8 a=0;
9498   foreach_udp_proto_field;
9499 #undef _
9500
9501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9502     {
9503       if (0);
9504 #define _(a) else if (unformat (input, #a)) a=1;
9505       foreach_udp_proto_field
9506 #undef _
9507         else
9508         break;
9509     }
9510
9511 #define _(a) found_something += a;
9512   foreach_udp_proto_field;
9513 #undef _
9514
9515   if (found_something == 0)
9516     return 0;
9517
9518   vec_validate (mask, sizeof (*udp) - 1);
9519
9520   udp = (udp_header_t *) mask;
9521
9522 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9523   foreach_udp_proto_field;
9524 #undef _
9525
9526   *maskp = mask;
9527   return 1;
9528 }
9529
9530 uword
9531 unformat_l4_mask (unformat_input_t * input, va_list * args)
9532 {
9533   u8 **maskp = va_arg (*args, u8 **);
9534   u16 src_port = 0, dst_port = 0;
9535   tcpudp_header_t *tcpudp;
9536
9537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9538     {
9539       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9540         return 1;
9541       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9542         return 1;
9543       else if (unformat (input, "src_port"))
9544         src_port = 0xFFFF;
9545       else if (unformat (input, "dst_port"))
9546         dst_port = 0xFFFF;
9547       else
9548         return 0;
9549     }
9550
9551   if (!src_port && !dst_port)
9552     return 0;
9553
9554   u8 *mask = 0;
9555   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9556
9557   tcpudp = (tcpudp_header_t *) mask;
9558   tcpudp->src_port = src_port;
9559   tcpudp->dst_port = dst_port;
9560
9561   *maskp = mask;
9562
9563   return 1;
9564 }
9565
9566 uword
9567 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9568 {
9569   u8 **maskp = va_arg (*args, u8 **);
9570   u8 *mask = 0;
9571   u8 found_something = 0;
9572   ip4_header_t *ip;
9573
9574 #define _(a) u8 a=0;
9575   foreach_ip4_proto_field;
9576 #undef _
9577   u8 version = 0;
9578   u8 hdr_length = 0;
9579
9580
9581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9582     {
9583       if (unformat (input, "version"))
9584         version = 1;
9585       else if (unformat (input, "hdr_length"))
9586         hdr_length = 1;
9587       else if (unformat (input, "src"))
9588         src_address = 1;
9589       else if (unformat (input, "dst"))
9590         dst_address = 1;
9591       else if (unformat (input, "proto"))
9592         protocol = 1;
9593
9594 #define _(a) else if (unformat (input, #a)) a=1;
9595       foreach_ip4_proto_field
9596 #undef _
9597         else
9598         break;
9599     }
9600
9601 #define _(a) found_something += a;
9602   foreach_ip4_proto_field;
9603 #undef _
9604
9605   if (found_something == 0)
9606     return 0;
9607
9608   vec_validate (mask, sizeof (*ip) - 1);
9609
9610   ip = (ip4_header_t *) mask;
9611
9612 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9613   foreach_ip4_proto_field;
9614 #undef _
9615
9616   ip->ip_version_and_header_length = 0;
9617
9618   if (version)
9619     ip->ip_version_and_header_length |= 0xF0;
9620
9621   if (hdr_length)
9622     ip->ip_version_and_header_length |= 0x0F;
9623
9624   *maskp = mask;
9625   return 1;
9626 }
9627
9628 #define foreach_ip6_proto_field                 \
9629 _(src_address)                                  \
9630 _(dst_address)                                  \
9631 _(payload_length)                               \
9632 _(hop_limit)                                    \
9633 _(protocol)
9634
9635 uword
9636 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9637 {
9638   u8 **maskp = va_arg (*args, u8 **);
9639   u8 *mask = 0;
9640   u8 found_something = 0;
9641   ip6_header_t *ip;
9642   u32 ip_version_traffic_class_and_flow_label;
9643
9644 #define _(a) u8 a=0;
9645   foreach_ip6_proto_field;
9646 #undef _
9647   u8 version = 0;
9648   u8 traffic_class = 0;
9649   u8 flow_label = 0;
9650
9651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (input, "version"))
9654         version = 1;
9655       else if (unformat (input, "traffic-class"))
9656         traffic_class = 1;
9657       else if (unformat (input, "flow-label"))
9658         flow_label = 1;
9659       else if (unformat (input, "src"))
9660         src_address = 1;
9661       else if (unformat (input, "dst"))
9662         dst_address = 1;
9663       else if (unformat (input, "proto"))
9664         protocol = 1;
9665
9666 #define _(a) else if (unformat (input, #a)) a=1;
9667       foreach_ip6_proto_field
9668 #undef _
9669         else
9670         break;
9671     }
9672
9673 #define _(a) found_something += a;
9674   foreach_ip6_proto_field;
9675 #undef _
9676
9677   if (found_something == 0)
9678     return 0;
9679
9680   vec_validate (mask, sizeof (*ip) - 1);
9681
9682   ip = (ip6_header_t *) mask;
9683
9684 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9685   foreach_ip6_proto_field;
9686 #undef _
9687
9688   ip_version_traffic_class_and_flow_label = 0;
9689
9690   if (version)
9691     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9692
9693   if (traffic_class)
9694     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9695
9696   if (flow_label)
9697     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9698
9699   ip->ip_version_traffic_class_and_flow_label =
9700     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9701
9702   *maskp = mask;
9703   return 1;
9704 }
9705
9706 uword
9707 unformat_l3_mask (unformat_input_t * input, va_list * args)
9708 {
9709   u8 **maskp = va_arg (*args, u8 **);
9710
9711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9712     {
9713       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9714         return 1;
9715       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9716         return 1;
9717       else
9718         break;
9719     }
9720   return 0;
9721 }
9722
9723 uword
9724 unformat_l2_mask (unformat_input_t * input, va_list * args)
9725 {
9726   u8 **maskp = va_arg (*args, u8 **);
9727   u8 *mask = 0;
9728   u8 src = 0;
9729   u8 dst = 0;
9730   u8 proto = 0;
9731   u8 tag1 = 0;
9732   u8 tag2 = 0;
9733   u8 ignore_tag1 = 0;
9734   u8 ignore_tag2 = 0;
9735   u8 cos1 = 0;
9736   u8 cos2 = 0;
9737   u8 dot1q = 0;
9738   u8 dot1ad = 0;
9739   int len = 14;
9740
9741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9742     {
9743       if (unformat (input, "src"))
9744         src = 1;
9745       else if (unformat (input, "dst"))
9746         dst = 1;
9747       else if (unformat (input, "proto"))
9748         proto = 1;
9749       else if (unformat (input, "tag1"))
9750         tag1 = 1;
9751       else if (unformat (input, "tag2"))
9752         tag2 = 1;
9753       else if (unformat (input, "ignore-tag1"))
9754         ignore_tag1 = 1;
9755       else if (unformat (input, "ignore-tag2"))
9756         ignore_tag2 = 1;
9757       else if (unformat (input, "cos1"))
9758         cos1 = 1;
9759       else if (unformat (input, "cos2"))
9760         cos2 = 1;
9761       else if (unformat (input, "dot1q"))
9762         dot1q = 1;
9763       else if (unformat (input, "dot1ad"))
9764         dot1ad = 1;
9765       else
9766         break;
9767     }
9768   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9769        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9770     return 0;
9771
9772   if (tag1 || ignore_tag1 || cos1 || dot1q)
9773     len = 18;
9774   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9775     len = 22;
9776
9777   vec_validate (mask, len - 1);
9778
9779   if (dst)
9780     clib_memset (mask, 0xff, 6);
9781
9782   if (src)
9783     clib_memset (mask + 6, 0xff, 6);
9784
9785   if (tag2 || dot1ad)
9786     {
9787       /* inner vlan tag */
9788       if (tag2)
9789         {
9790           mask[19] = 0xff;
9791           mask[18] = 0x0f;
9792         }
9793       if (cos2)
9794         mask[18] |= 0xe0;
9795       if (proto)
9796         mask[21] = mask[20] = 0xff;
9797       if (tag1)
9798         {
9799           mask[15] = 0xff;
9800           mask[14] = 0x0f;
9801         }
9802       if (cos1)
9803         mask[14] |= 0xe0;
9804       *maskp = mask;
9805       return 1;
9806     }
9807   if (tag1 | dot1q)
9808     {
9809       if (tag1)
9810         {
9811           mask[15] = 0xff;
9812           mask[14] = 0x0f;
9813         }
9814       if (cos1)
9815         mask[14] |= 0xe0;
9816       if (proto)
9817         mask[16] = mask[17] = 0xff;
9818
9819       *maskp = mask;
9820       return 1;
9821     }
9822   if (cos2)
9823     mask[18] |= 0xe0;
9824   if (cos1)
9825     mask[14] |= 0xe0;
9826   if (proto)
9827     mask[12] = mask[13] = 0xff;
9828
9829   *maskp = mask;
9830   return 1;
9831 }
9832
9833 uword
9834 unformat_classify_mask (unformat_input_t * input, va_list * args)
9835 {
9836   u8 **maskp = va_arg (*args, u8 **);
9837   u32 *skipp = va_arg (*args, u32 *);
9838   u32 *matchp = va_arg (*args, u32 *);
9839   u32 match;
9840   u8 *mask = 0;
9841   u8 *l2 = 0;
9842   u8 *l3 = 0;
9843   u8 *l4 = 0;
9844   int i;
9845
9846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9847     {
9848       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9849         ;
9850       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9851         ;
9852       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9853         ;
9854       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9855         ;
9856       else
9857         break;
9858     }
9859
9860   if (l4 && !l3)
9861     {
9862       vec_free (mask);
9863       vec_free (l2);
9864       vec_free (l4);
9865       return 0;
9866     }
9867
9868   if (mask || l2 || l3 || l4)
9869     {
9870       if (l2 || l3 || l4)
9871         {
9872           /* "With a free Ethernet header in every package" */
9873           if (l2 == 0)
9874             vec_validate (l2, 13);
9875           mask = l2;
9876           if (vec_len (l3))
9877             {
9878               vec_append (mask, l3);
9879               vec_free (l3);
9880             }
9881           if (vec_len (l4))
9882             {
9883               vec_append (mask, l4);
9884               vec_free (l4);
9885             }
9886         }
9887
9888       /* Scan forward looking for the first significant mask octet */
9889       for (i = 0; i < vec_len (mask); i++)
9890         if (mask[i])
9891           break;
9892
9893       /* compute (skip, match) params */
9894       *skipp = i / sizeof (u32x4);
9895       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9896
9897       /* Pad mask to an even multiple of the vector size */
9898       while (vec_len (mask) % sizeof (u32x4))
9899         vec_add1 (mask, 0);
9900
9901       match = vec_len (mask) / sizeof (u32x4);
9902
9903       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9904         {
9905           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9906           if (*tmp || *(tmp + 1))
9907             break;
9908           match--;
9909         }
9910       if (match == 0)
9911         clib_warning ("BUG: match 0");
9912
9913       _vec_len (mask) = match * sizeof (u32x4);
9914
9915       *matchp = match;
9916       *maskp = mask;
9917
9918       return 1;
9919     }
9920
9921   return 0;
9922 }
9923 #endif /* VPP_API_TEST_BUILTIN */
9924
9925 #define foreach_l2_next                         \
9926 _(drop, DROP)                                   \
9927 _(ethernet, ETHERNET_INPUT)                     \
9928 _(ip4, IP4_INPUT)                               \
9929 _(ip6, IP6_INPUT)
9930
9931 uword
9932 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9933 {
9934   u32 *miss_next_indexp = va_arg (*args, u32 *);
9935   u32 next_index = 0;
9936   u32 tmp;
9937
9938 #define _(n,N) \
9939   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9940   foreach_l2_next;
9941 #undef _
9942
9943   if (unformat (input, "%d", &tmp))
9944     {
9945       next_index = tmp;
9946       goto out;
9947     }
9948
9949   return 0;
9950
9951 out:
9952   *miss_next_indexp = next_index;
9953   return 1;
9954 }
9955
9956 #define foreach_ip_next                         \
9957 _(drop, DROP)                                   \
9958 _(local, LOCAL)                                 \
9959 _(rewrite, REWRITE)
9960
9961 uword
9962 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9963 {
9964   u32 *miss_next_indexp = va_arg (*args, u32 *);
9965   u32 next_index = 0;
9966   u32 tmp;
9967
9968 #define _(n,N) \
9969   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9970   foreach_ip_next;
9971 #undef _
9972
9973   if (unformat (input, "%d", &tmp))
9974     {
9975       next_index = tmp;
9976       goto out;
9977     }
9978
9979   return 0;
9980
9981 out:
9982   *miss_next_indexp = next_index;
9983   return 1;
9984 }
9985
9986 #define foreach_acl_next                        \
9987 _(deny, DENY)
9988
9989 uword
9990 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9991 {
9992   u32 *miss_next_indexp = va_arg (*args, u32 *);
9993   u32 next_index = 0;
9994   u32 tmp;
9995
9996 #define _(n,N) \
9997   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9998   foreach_acl_next;
9999 #undef _
10000
10001   if (unformat (input, "permit"))
10002     {
10003       next_index = ~0;
10004       goto out;
10005     }
10006   else if (unformat (input, "%d", &tmp))
10007     {
10008       next_index = tmp;
10009       goto out;
10010     }
10011
10012   return 0;
10013
10014 out:
10015   *miss_next_indexp = next_index;
10016   return 1;
10017 }
10018
10019 uword
10020 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10021 {
10022   u32 *r = va_arg (*args, u32 *);
10023
10024   if (unformat (input, "conform-color"))
10025     *r = POLICE_CONFORM;
10026   else if (unformat (input, "exceed-color"))
10027     *r = POLICE_EXCEED;
10028   else
10029     return 0;
10030
10031   return 1;
10032 }
10033
10034 static int
10035 api_classify_add_del_table (vat_main_t * vam)
10036 {
10037   unformat_input_t *i = vam->input;
10038   vl_api_classify_add_del_table_t *mp;
10039
10040   u32 nbuckets = 2;
10041   u32 skip = ~0;
10042   u32 match = ~0;
10043   int is_add = 1;
10044   int del_chain = 0;
10045   u32 table_index = ~0;
10046   u32 next_table_index = ~0;
10047   u32 miss_next_index = ~0;
10048   u32 memory_size = 32 << 20;
10049   u8 *mask = 0;
10050   u32 current_data_flag = 0;
10051   int current_data_offset = 0;
10052   int ret;
10053
10054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10055     {
10056       if (unformat (i, "del"))
10057         is_add = 0;
10058       else if (unformat (i, "del-chain"))
10059         {
10060           is_add = 0;
10061           del_chain = 1;
10062         }
10063       else if (unformat (i, "buckets %d", &nbuckets))
10064         ;
10065       else if (unformat (i, "memory_size %d", &memory_size))
10066         ;
10067       else if (unformat (i, "skip %d", &skip))
10068         ;
10069       else if (unformat (i, "match %d", &match))
10070         ;
10071       else if (unformat (i, "table %d", &table_index))
10072         ;
10073       else if (unformat (i, "mask %U", unformat_classify_mask,
10074                          &mask, &skip, &match))
10075         ;
10076       else if (unformat (i, "next-table %d", &next_table_index))
10077         ;
10078       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10079                          &miss_next_index))
10080         ;
10081       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10082                          &miss_next_index))
10083         ;
10084       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10085                          &miss_next_index))
10086         ;
10087       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10088         ;
10089       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10090         ;
10091       else
10092         break;
10093     }
10094
10095   if (is_add && mask == 0)
10096     {
10097       errmsg ("Mask required");
10098       return -99;
10099     }
10100
10101   if (is_add && skip == ~0)
10102     {
10103       errmsg ("skip count required");
10104       return -99;
10105     }
10106
10107   if (is_add && match == ~0)
10108     {
10109       errmsg ("match count required");
10110       return -99;
10111     }
10112
10113   if (!is_add && table_index == ~0)
10114     {
10115       errmsg ("table index required for delete");
10116       return -99;
10117     }
10118
10119   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10120
10121   mp->is_add = is_add;
10122   mp->del_chain = del_chain;
10123   mp->table_index = ntohl (table_index);
10124   mp->nbuckets = ntohl (nbuckets);
10125   mp->memory_size = ntohl (memory_size);
10126   mp->skip_n_vectors = ntohl (skip);
10127   mp->match_n_vectors = ntohl (match);
10128   mp->next_table_index = ntohl (next_table_index);
10129   mp->miss_next_index = ntohl (miss_next_index);
10130   mp->current_data_flag = ntohl (current_data_flag);
10131   mp->current_data_offset = ntohl (current_data_offset);
10132   mp->mask_len = ntohl (vec_len (mask));
10133   clib_memcpy (mp->mask, mask, vec_len (mask));
10134
10135   vec_free (mask);
10136
10137   S (mp);
10138   W (ret);
10139   return ret;
10140 }
10141
10142 #if VPP_API_TEST_BUILTIN == 0
10143 uword
10144 unformat_l4_match (unformat_input_t * input, va_list * args)
10145 {
10146   u8 **matchp = va_arg (*args, u8 **);
10147
10148   u8 *proto_header = 0;
10149   int src_port = 0;
10150   int dst_port = 0;
10151
10152   tcpudp_header_t h;
10153
10154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10155     {
10156       if (unformat (input, "src_port %d", &src_port))
10157         ;
10158       else if (unformat (input, "dst_port %d", &dst_port))
10159         ;
10160       else
10161         return 0;
10162     }
10163
10164   h.src_port = clib_host_to_net_u16 (src_port);
10165   h.dst_port = clib_host_to_net_u16 (dst_port);
10166   vec_validate (proto_header, sizeof (h) - 1);
10167   memcpy (proto_header, &h, sizeof (h));
10168
10169   *matchp = proto_header;
10170
10171   return 1;
10172 }
10173
10174 uword
10175 unformat_ip4_match (unformat_input_t * input, va_list * args)
10176 {
10177   u8 **matchp = va_arg (*args, u8 **);
10178   u8 *match = 0;
10179   ip4_header_t *ip;
10180   int version = 0;
10181   u32 version_val;
10182   int hdr_length = 0;
10183   u32 hdr_length_val;
10184   int src = 0, dst = 0;
10185   ip4_address_t src_val, dst_val;
10186   int proto = 0;
10187   u32 proto_val;
10188   int tos = 0;
10189   u32 tos_val;
10190   int length = 0;
10191   u32 length_val;
10192   int fragment_id = 0;
10193   u32 fragment_id_val;
10194   int ttl = 0;
10195   int ttl_val;
10196   int checksum = 0;
10197   u32 checksum_val;
10198
10199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10200     {
10201       if (unformat (input, "version %d", &version_val))
10202         version = 1;
10203       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10204         hdr_length = 1;
10205       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10206         src = 1;
10207       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10208         dst = 1;
10209       else if (unformat (input, "proto %d", &proto_val))
10210         proto = 1;
10211       else if (unformat (input, "tos %d", &tos_val))
10212         tos = 1;
10213       else if (unformat (input, "length %d", &length_val))
10214         length = 1;
10215       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10216         fragment_id = 1;
10217       else if (unformat (input, "ttl %d", &ttl_val))
10218         ttl = 1;
10219       else if (unformat (input, "checksum %d", &checksum_val))
10220         checksum = 1;
10221       else
10222         break;
10223     }
10224
10225   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10226       + ttl + checksum == 0)
10227     return 0;
10228
10229   /*
10230    * Aligned because we use the real comparison functions
10231    */
10232   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10233
10234   ip = (ip4_header_t *) match;
10235
10236   /* These are realistically matched in practice */
10237   if (src)
10238     ip->src_address.as_u32 = src_val.as_u32;
10239
10240   if (dst)
10241     ip->dst_address.as_u32 = dst_val.as_u32;
10242
10243   if (proto)
10244     ip->protocol = proto_val;
10245
10246
10247   /* These are not, but they're included for completeness */
10248   if (version)
10249     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10250
10251   if (hdr_length)
10252     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10253
10254   if (tos)
10255     ip->tos = tos_val;
10256
10257   if (length)
10258     ip->length = clib_host_to_net_u16 (length_val);
10259
10260   if (ttl)
10261     ip->ttl = ttl_val;
10262
10263   if (checksum)
10264     ip->checksum = clib_host_to_net_u16 (checksum_val);
10265
10266   *matchp = match;
10267   return 1;
10268 }
10269
10270 uword
10271 unformat_ip6_match (unformat_input_t * input, va_list * args)
10272 {
10273   u8 **matchp = va_arg (*args, u8 **);
10274   u8 *match = 0;
10275   ip6_header_t *ip;
10276   int version = 0;
10277   u32 version_val;
10278   u8 traffic_class = 0;
10279   u32 traffic_class_val = 0;
10280   u8 flow_label = 0;
10281   u8 flow_label_val;
10282   int src = 0, dst = 0;
10283   ip6_address_t src_val, dst_val;
10284   int proto = 0;
10285   u32 proto_val;
10286   int payload_length = 0;
10287   u32 payload_length_val;
10288   int hop_limit = 0;
10289   int hop_limit_val;
10290   u32 ip_version_traffic_class_and_flow_label;
10291
10292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10293     {
10294       if (unformat (input, "version %d", &version_val))
10295         version = 1;
10296       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10297         traffic_class = 1;
10298       else if (unformat (input, "flow_label %d", &flow_label_val))
10299         flow_label = 1;
10300       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10301         src = 1;
10302       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10303         dst = 1;
10304       else if (unformat (input, "proto %d", &proto_val))
10305         proto = 1;
10306       else if (unformat (input, "payload_length %d", &payload_length_val))
10307         payload_length = 1;
10308       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10309         hop_limit = 1;
10310       else
10311         break;
10312     }
10313
10314   if (version + traffic_class + flow_label + src + dst + proto +
10315       payload_length + hop_limit == 0)
10316     return 0;
10317
10318   /*
10319    * Aligned because we use the real comparison functions
10320    */
10321   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10322
10323   ip = (ip6_header_t *) match;
10324
10325   if (src)
10326     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10327
10328   if (dst)
10329     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10330
10331   if (proto)
10332     ip->protocol = proto_val;
10333
10334   ip_version_traffic_class_and_flow_label = 0;
10335
10336   if (version)
10337     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10338
10339   if (traffic_class)
10340     ip_version_traffic_class_and_flow_label |=
10341       (traffic_class_val & 0xFF) << 20;
10342
10343   if (flow_label)
10344     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10345
10346   ip->ip_version_traffic_class_and_flow_label =
10347     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10348
10349   if (payload_length)
10350     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10351
10352   if (hop_limit)
10353     ip->hop_limit = hop_limit_val;
10354
10355   *matchp = match;
10356   return 1;
10357 }
10358
10359 uword
10360 unformat_l3_match (unformat_input_t * input, va_list * args)
10361 {
10362   u8 **matchp = va_arg (*args, u8 **);
10363
10364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10365     {
10366       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10367         return 1;
10368       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10369         return 1;
10370       else
10371         break;
10372     }
10373   return 0;
10374 }
10375
10376 uword
10377 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10378 {
10379   u8 *tagp = va_arg (*args, u8 *);
10380   u32 tag;
10381
10382   if (unformat (input, "%d", &tag))
10383     {
10384       tagp[0] = (tag >> 8) & 0x0F;
10385       tagp[1] = tag & 0xFF;
10386       return 1;
10387     }
10388
10389   return 0;
10390 }
10391
10392 uword
10393 unformat_l2_match (unformat_input_t * input, va_list * args)
10394 {
10395   u8 **matchp = va_arg (*args, u8 **);
10396   u8 *match = 0;
10397   u8 src = 0;
10398   u8 src_val[6];
10399   u8 dst = 0;
10400   u8 dst_val[6];
10401   u8 proto = 0;
10402   u16 proto_val;
10403   u8 tag1 = 0;
10404   u8 tag1_val[2];
10405   u8 tag2 = 0;
10406   u8 tag2_val[2];
10407   int len = 14;
10408   u8 ignore_tag1 = 0;
10409   u8 ignore_tag2 = 0;
10410   u8 cos1 = 0;
10411   u8 cos2 = 0;
10412   u32 cos1_val = 0;
10413   u32 cos2_val = 0;
10414
10415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10416     {
10417       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10418         src = 1;
10419       else
10420         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10421         dst = 1;
10422       else if (unformat (input, "proto %U",
10423                          unformat_ethernet_type_host_byte_order, &proto_val))
10424         proto = 1;
10425       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10426         tag1 = 1;
10427       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10428         tag2 = 1;
10429       else if (unformat (input, "ignore-tag1"))
10430         ignore_tag1 = 1;
10431       else if (unformat (input, "ignore-tag2"))
10432         ignore_tag2 = 1;
10433       else if (unformat (input, "cos1 %d", &cos1_val))
10434         cos1 = 1;
10435       else if (unformat (input, "cos2 %d", &cos2_val))
10436         cos2 = 1;
10437       else
10438         break;
10439     }
10440   if ((src + dst + proto + tag1 + tag2 +
10441        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10442     return 0;
10443
10444   if (tag1 || ignore_tag1 || cos1)
10445     len = 18;
10446   if (tag2 || ignore_tag2 || cos2)
10447     len = 22;
10448
10449   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10450
10451   if (dst)
10452     clib_memcpy (match, dst_val, 6);
10453
10454   if (src)
10455     clib_memcpy (match + 6, src_val, 6);
10456
10457   if (tag2)
10458     {
10459       /* inner vlan tag */
10460       match[19] = tag2_val[1];
10461       match[18] = tag2_val[0];
10462       if (cos2)
10463         match[18] |= (cos2_val & 0x7) << 5;
10464       if (proto)
10465         {
10466           match[21] = proto_val & 0xff;
10467           match[20] = proto_val >> 8;
10468         }
10469       if (tag1)
10470         {
10471           match[15] = tag1_val[1];
10472           match[14] = tag1_val[0];
10473         }
10474       if (cos1)
10475         match[14] |= (cos1_val & 0x7) << 5;
10476       *matchp = match;
10477       return 1;
10478     }
10479   if (tag1)
10480     {
10481       match[15] = tag1_val[1];
10482       match[14] = tag1_val[0];
10483       if (proto)
10484         {
10485           match[17] = proto_val & 0xff;
10486           match[16] = proto_val >> 8;
10487         }
10488       if (cos1)
10489         match[14] |= (cos1_val & 0x7) << 5;
10490
10491       *matchp = match;
10492       return 1;
10493     }
10494   if (cos2)
10495     match[18] |= (cos2_val & 0x7) << 5;
10496   if (cos1)
10497     match[14] |= (cos1_val & 0x7) << 5;
10498   if (proto)
10499     {
10500       match[13] = proto_val & 0xff;
10501       match[12] = proto_val >> 8;
10502     }
10503
10504   *matchp = match;
10505   return 1;
10506 }
10507
10508 uword
10509 unformat_qos_source (unformat_input_t * input, va_list * args)
10510 {
10511   int *qs = va_arg (*args, int *);
10512
10513   if (unformat (input, "ip"))
10514     *qs = QOS_SOURCE_IP;
10515   else if (unformat (input, "mpls"))
10516     *qs = QOS_SOURCE_MPLS;
10517   else if (unformat (input, "ext"))
10518     *qs = QOS_SOURCE_EXT;
10519   else if (unformat (input, "vlan"))
10520     *qs = QOS_SOURCE_VLAN;
10521   else
10522     return 0;
10523
10524   return 1;
10525 }
10526 #endif
10527
10528 uword
10529 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10530 {
10531   u8 **matchp = va_arg (*args, u8 **);
10532   u32 skip_n_vectors = va_arg (*args, u32);
10533   u32 match_n_vectors = va_arg (*args, u32);
10534
10535   u8 *match = 0;
10536   u8 *l2 = 0;
10537   u8 *l3 = 0;
10538   u8 *l4 = 0;
10539
10540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (input, "hex %U", unformat_hex_string, &match))
10543         ;
10544       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10545         ;
10546       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10547         ;
10548       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10549         ;
10550       else
10551         break;
10552     }
10553
10554   if (l4 && !l3)
10555     {
10556       vec_free (match);
10557       vec_free (l2);
10558       vec_free (l4);
10559       return 0;
10560     }
10561
10562   if (match || l2 || l3 || l4)
10563     {
10564       if (l2 || l3 || l4)
10565         {
10566           /* "Win a free Ethernet header in every packet" */
10567           if (l2 == 0)
10568             vec_validate_aligned (l2, 13, sizeof (u32x4));
10569           match = l2;
10570           if (vec_len (l3))
10571             {
10572               vec_append_aligned (match, l3, sizeof (u32x4));
10573               vec_free (l3);
10574             }
10575           if (vec_len (l4))
10576             {
10577               vec_append_aligned (match, l4, sizeof (u32x4));
10578               vec_free (l4);
10579             }
10580         }
10581
10582       /* Make sure the vector is big enough even if key is all 0's */
10583       vec_validate_aligned
10584         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10585          sizeof (u32x4));
10586
10587       /* Set size, include skipped vectors */
10588       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10589
10590       *matchp = match;
10591
10592       return 1;
10593     }
10594
10595   return 0;
10596 }
10597
10598 static int
10599 api_classify_add_del_session (vat_main_t * vam)
10600 {
10601   unformat_input_t *i = vam->input;
10602   vl_api_classify_add_del_session_t *mp;
10603   int is_add = 1;
10604   u32 table_index = ~0;
10605   u32 hit_next_index = ~0;
10606   u32 opaque_index = ~0;
10607   u8 *match = 0;
10608   i32 advance = 0;
10609   u32 skip_n_vectors = 0;
10610   u32 match_n_vectors = 0;
10611   u32 action = 0;
10612   u32 metadata = 0;
10613   int ret;
10614
10615   /*
10616    * Warning: you have to supply skip_n and match_n
10617    * because the API client cant simply look at the classify
10618    * table object.
10619    */
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "del"))
10624         is_add = 0;
10625       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10626                          &hit_next_index))
10627         ;
10628       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10629                          &hit_next_index))
10630         ;
10631       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10632                          &hit_next_index))
10633         ;
10634       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10635         ;
10636       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10637         ;
10638       else if (unformat (i, "opaque-index %d", &opaque_index))
10639         ;
10640       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10641         ;
10642       else if (unformat (i, "match_n %d", &match_n_vectors))
10643         ;
10644       else if (unformat (i, "match %U", api_unformat_classify_match,
10645                          &match, skip_n_vectors, match_n_vectors))
10646         ;
10647       else if (unformat (i, "advance %d", &advance))
10648         ;
10649       else if (unformat (i, "table-index %d", &table_index))
10650         ;
10651       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10652         action = 1;
10653       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10654         action = 2;
10655       else if (unformat (i, "action %d", &action))
10656         ;
10657       else if (unformat (i, "metadata %d", &metadata))
10658         ;
10659       else
10660         break;
10661     }
10662
10663   if (table_index == ~0)
10664     {
10665       errmsg ("Table index required");
10666       return -99;
10667     }
10668
10669   if (is_add && match == 0)
10670     {
10671       errmsg ("Match value required");
10672       return -99;
10673     }
10674
10675   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10676
10677   mp->is_add = is_add;
10678   mp->table_index = ntohl (table_index);
10679   mp->hit_next_index = ntohl (hit_next_index);
10680   mp->opaque_index = ntohl (opaque_index);
10681   mp->advance = ntohl (advance);
10682   mp->action = action;
10683   mp->metadata = ntohl (metadata);
10684   mp->match_len = ntohl (vec_len (match));
10685   clib_memcpy (mp->match, match, vec_len (match));
10686   vec_free (match);
10687
10688   S (mp);
10689   W (ret);
10690   return ret;
10691 }
10692
10693 static int
10694 api_classify_set_interface_ip_table (vat_main_t * vam)
10695 {
10696   unformat_input_t *i = vam->input;
10697   vl_api_classify_set_interface_ip_table_t *mp;
10698   u32 sw_if_index;
10699   int sw_if_index_set;
10700   u32 table_index = ~0;
10701   u8 is_ipv6 = 0;
10702   int ret;
10703
10704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "table %d", &table_index))
10711         ;
10712       else
10713         {
10714           clib_warning ("parse error '%U'", format_unformat_error, i);
10715           return -99;
10716         }
10717     }
10718
10719   if (sw_if_index_set == 0)
10720     {
10721       errmsg ("missing interface name or sw_if_index");
10722       return -99;
10723     }
10724
10725
10726   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10727
10728   mp->sw_if_index = ntohl (sw_if_index);
10729   mp->table_index = ntohl (table_index);
10730   mp->is_ipv6 = is_ipv6;
10731
10732   S (mp);
10733   W (ret);
10734   return ret;
10735 }
10736
10737 static int
10738 api_classify_set_interface_l2_tables (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_classify_set_interface_l2_tables_t *mp;
10742   u32 sw_if_index;
10743   int sw_if_index_set;
10744   u32 ip4_table_index = ~0;
10745   u32 ip6_table_index = ~0;
10746   u32 other_table_index = ~0;
10747   u32 is_input = 1;
10748   int ret;
10749
10750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10751     {
10752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10755         sw_if_index_set = 1;
10756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10757         ;
10758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10759         ;
10760       else if (unformat (i, "other-table %d", &other_table_index))
10761         ;
10762       else if (unformat (i, "is-input %d", &is_input))
10763         ;
10764       else
10765         {
10766           clib_warning ("parse error '%U'", format_unformat_error, i);
10767           return -99;
10768         }
10769     }
10770
10771   if (sw_if_index_set == 0)
10772     {
10773       errmsg ("missing interface name or sw_if_index");
10774       return -99;
10775     }
10776
10777
10778   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10779
10780   mp->sw_if_index = ntohl (sw_if_index);
10781   mp->ip4_table_index = ntohl (ip4_table_index);
10782   mp->ip6_table_index = ntohl (ip6_table_index);
10783   mp->other_table_index = ntohl (other_table_index);
10784   mp->is_input = (u8) is_input;
10785
10786   S (mp);
10787   W (ret);
10788   return ret;
10789 }
10790
10791 static int
10792 api_set_ipfix_exporter (vat_main_t * vam)
10793 {
10794   unformat_input_t *i = vam->input;
10795   vl_api_set_ipfix_exporter_t *mp;
10796   ip4_address_t collector_address;
10797   u8 collector_address_set = 0;
10798   u32 collector_port = ~0;
10799   ip4_address_t src_address;
10800   u8 src_address_set = 0;
10801   u32 vrf_id = ~0;
10802   u32 path_mtu = ~0;
10803   u32 template_interval = ~0;
10804   u8 udp_checksum = 0;
10805   int ret;
10806
10807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10808     {
10809       if (unformat (i, "collector_address %U", unformat_ip4_address,
10810                     &collector_address))
10811         collector_address_set = 1;
10812       else if (unformat (i, "collector_port %d", &collector_port))
10813         ;
10814       else if (unformat (i, "src_address %U", unformat_ip4_address,
10815                          &src_address))
10816         src_address_set = 1;
10817       else if (unformat (i, "vrf_id %d", &vrf_id))
10818         ;
10819       else if (unformat (i, "path_mtu %d", &path_mtu))
10820         ;
10821       else if (unformat (i, "template_interval %d", &template_interval))
10822         ;
10823       else if (unformat (i, "udp_checksum"))
10824         udp_checksum = 1;
10825       else
10826         break;
10827     }
10828
10829   if (collector_address_set == 0)
10830     {
10831       errmsg ("collector_address required");
10832       return -99;
10833     }
10834
10835   if (src_address_set == 0)
10836     {
10837       errmsg ("src_address required");
10838       return -99;
10839     }
10840
10841   M (SET_IPFIX_EXPORTER, mp);
10842
10843   memcpy (mp->collector_address.un.ip4, collector_address.data,
10844           sizeof (collector_address.data));
10845   mp->collector_port = htons ((u16) collector_port);
10846   memcpy (mp->src_address.un.ip4, src_address.data,
10847           sizeof (src_address.data));
10848   mp->vrf_id = htonl (vrf_id);
10849   mp->path_mtu = htonl (path_mtu);
10850   mp->template_interval = htonl (template_interval);
10851   mp->udp_checksum = udp_checksum;
10852
10853   S (mp);
10854   W (ret);
10855   return ret;
10856 }
10857
10858 static int
10859 api_set_ipfix_classify_stream (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_set_ipfix_classify_stream_t *mp;
10863   u32 domain_id = 0;
10864   u32 src_port = UDP_DST_PORT_ipfix;
10865   int ret;
10866
10867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (i, "domain %d", &domain_id))
10870         ;
10871       else if (unformat (i, "src_port %d", &src_port))
10872         ;
10873       else
10874         {
10875           errmsg ("unknown input `%U'", format_unformat_error, i);
10876           return -99;
10877         }
10878     }
10879
10880   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10881
10882   mp->domain_id = htonl (domain_id);
10883   mp->src_port = htons ((u16) src_port);
10884
10885   S (mp);
10886   W (ret);
10887   return ret;
10888 }
10889
10890 static int
10891 api_ipfix_classify_table_add_del (vat_main_t * vam)
10892 {
10893   unformat_input_t *i = vam->input;
10894   vl_api_ipfix_classify_table_add_del_t *mp;
10895   int is_add = -1;
10896   u32 classify_table_index = ~0;
10897   u8 ip_version = 0;
10898   u8 transport_protocol = 255;
10899   int ret;
10900
10901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902     {
10903       if (unformat (i, "add"))
10904         is_add = 1;
10905       else if (unformat (i, "del"))
10906         is_add = 0;
10907       else if (unformat (i, "table %d", &classify_table_index))
10908         ;
10909       else if (unformat (i, "ip4"))
10910         ip_version = 4;
10911       else if (unformat (i, "ip6"))
10912         ip_version = 6;
10913       else if (unformat (i, "tcp"))
10914         transport_protocol = 6;
10915       else if (unformat (i, "udp"))
10916         transport_protocol = 17;
10917       else
10918         {
10919           errmsg ("unknown input `%U'", format_unformat_error, i);
10920           return -99;
10921         }
10922     }
10923
10924   if (is_add == -1)
10925     {
10926       errmsg ("expecting: add|del");
10927       return -99;
10928     }
10929   if (classify_table_index == ~0)
10930     {
10931       errmsg ("classifier table not specified");
10932       return -99;
10933     }
10934   if (ip_version == 0)
10935     {
10936       errmsg ("IP version not specified");
10937       return -99;
10938     }
10939
10940   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10941
10942   mp->is_add = is_add;
10943   mp->table_id = htonl (classify_table_index);
10944   mp->ip_version = ip_version;
10945   mp->transport_protocol = transport_protocol;
10946
10947   S (mp);
10948   W (ret);
10949   return ret;
10950 }
10951
10952 static int
10953 api_get_node_index (vat_main_t * vam)
10954 {
10955   unformat_input_t *i = vam->input;
10956   vl_api_get_node_index_t *mp;
10957   u8 *name = 0;
10958   int ret;
10959
10960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (i, "node %s", &name))
10963         ;
10964       else
10965         break;
10966     }
10967   if (name == 0)
10968     {
10969       errmsg ("node name required");
10970       return -99;
10971     }
10972   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10973     {
10974       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10975       return -99;
10976     }
10977
10978   M (GET_NODE_INDEX, mp);
10979   clib_memcpy (mp->node_name, name, vec_len (name));
10980   vec_free (name);
10981
10982   S (mp);
10983   W (ret);
10984   return ret;
10985 }
10986
10987 static int
10988 api_get_next_index (vat_main_t * vam)
10989 {
10990   unformat_input_t *i = vam->input;
10991   vl_api_get_next_index_t *mp;
10992   u8 *node_name = 0, *next_node_name = 0;
10993   int ret;
10994
10995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10996     {
10997       if (unformat (i, "node-name %s", &node_name))
10998         ;
10999       else if (unformat (i, "next-node-name %s", &next_node_name))
11000         break;
11001     }
11002
11003   if (node_name == 0)
11004     {
11005       errmsg ("node name required");
11006       return -99;
11007     }
11008   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11009     {
11010       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11011       return -99;
11012     }
11013
11014   if (next_node_name == 0)
11015     {
11016       errmsg ("next node name required");
11017       return -99;
11018     }
11019   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11020     {
11021       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11022       return -99;
11023     }
11024
11025   M (GET_NEXT_INDEX, mp);
11026   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11027   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11028   vec_free (node_name);
11029   vec_free (next_node_name);
11030
11031   S (mp);
11032   W (ret);
11033   return ret;
11034 }
11035
11036 static int
11037 api_add_node_next (vat_main_t * vam)
11038 {
11039   unformat_input_t *i = vam->input;
11040   vl_api_add_node_next_t *mp;
11041   u8 *name = 0;
11042   u8 *next = 0;
11043   int ret;
11044
11045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11046     {
11047       if (unformat (i, "node %s", &name))
11048         ;
11049       else if (unformat (i, "next %s", &next))
11050         ;
11051       else
11052         break;
11053     }
11054   if (name == 0)
11055     {
11056       errmsg ("node name required");
11057       return -99;
11058     }
11059   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11060     {
11061       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11062       return -99;
11063     }
11064   if (next == 0)
11065     {
11066       errmsg ("next node required");
11067       return -99;
11068     }
11069   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11070     {
11071       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11072       return -99;
11073     }
11074
11075   M (ADD_NODE_NEXT, mp);
11076   clib_memcpy (mp->node_name, name, vec_len (name));
11077   clib_memcpy (mp->next_name, next, vec_len (next));
11078   vec_free (name);
11079   vec_free (next);
11080
11081   S (mp);
11082   W (ret);
11083   return ret;
11084 }
11085
11086 static int
11087 api_l2tpv3_create_tunnel (vat_main_t * vam)
11088 {
11089   unformat_input_t *i = vam->input;
11090   ip6_address_t client_address, our_address;
11091   int client_address_set = 0;
11092   int our_address_set = 0;
11093   u32 local_session_id = 0;
11094   u32 remote_session_id = 0;
11095   u64 local_cookie = 0;
11096   u64 remote_cookie = 0;
11097   u8 l2_sublayer_present = 0;
11098   vl_api_l2tpv3_create_tunnel_t *mp;
11099   int ret;
11100
11101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (i, "client_address %U", unformat_ip6_address,
11104                     &client_address))
11105         client_address_set = 1;
11106       else if (unformat (i, "our_address %U", unformat_ip6_address,
11107                          &our_address))
11108         our_address_set = 1;
11109       else if (unformat (i, "local_session_id %d", &local_session_id))
11110         ;
11111       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11112         ;
11113       else if (unformat (i, "local_cookie %lld", &local_cookie))
11114         ;
11115       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11116         ;
11117       else if (unformat (i, "l2-sublayer-present"))
11118         l2_sublayer_present = 1;
11119       else
11120         break;
11121     }
11122
11123   if (client_address_set == 0)
11124     {
11125       errmsg ("client_address required");
11126       return -99;
11127     }
11128
11129   if (our_address_set == 0)
11130     {
11131       errmsg ("our_address required");
11132       return -99;
11133     }
11134
11135   M (L2TPV3_CREATE_TUNNEL, mp);
11136
11137   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11138                sizeof (ip6_address_t));
11139
11140   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11141                sizeof (ip6_address_t));
11142
11143   mp->local_session_id = ntohl (local_session_id);
11144   mp->remote_session_id = ntohl (remote_session_id);
11145   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11146   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11147   mp->l2_sublayer_present = l2_sublayer_present;
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   u32 sw_if_index;
11159   u8 sw_if_index_set = 0;
11160   u64 new_local_cookie = 0;
11161   u64 new_remote_cookie = 0;
11162   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11163   int ret;
11164
11165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11166     {
11167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11170         sw_if_index_set = 1;
11171       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11172         ;
11173       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11174         ;
11175       else
11176         break;
11177     }
11178
11179   if (sw_if_index_set == 0)
11180     {
11181       errmsg ("missing interface name or sw_if_index");
11182       return -99;
11183     }
11184
11185   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11186
11187   mp->sw_if_index = ntohl (sw_if_index);
11188   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11189   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11190
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 static int
11197 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11198 {
11199   unformat_input_t *i = vam->input;
11200   vl_api_l2tpv3_interface_enable_disable_t *mp;
11201   u32 sw_if_index;
11202   u8 sw_if_index_set = 0;
11203   u8 enable_disable = 1;
11204   int ret;
11205
11206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11209         sw_if_index_set = 1;
11210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11211         sw_if_index_set = 1;
11212       else if (unformat (i, "enable"))
11213         enable_disable = 1;
11214       else if (unformat (i, "disable"))
11215         enable_disable = 0;
11216       else
11217         break;
11218     }
11219
11220   if (sw_if_index_set == 0)
11221     {
11222       errmsg ("missing interface name or sw_if_index");
11223       return -99;
11224     }
11225
11226   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11227
11228   mp->sw_if_index = ntohl (sw_if_index);
11229   mp->enable_disable = enable_disable;
11230
11231   S (mp);
11232   W (ret);
11233   return ret;
11234 }
11235
11236 static int
11237 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11238 {
11239   unformat_input_t *i = vam->input;
11240   vl_api_l2tpv3_set_lookup_key_t *mp;
11241   u8 key = ~0;
11242   int ret;
11243
11244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11245     {
11246       if (unformat (i, "lookup_v6_src"))
11247         key = L2T_LOOKUP_SRC_ADDRESS;
11248       else if (unformat (i, "lookup_v6_dst"))
11249         key = L2T_LOOKUP_DST_ADDRESS;
11250       else if (unformat (i, "lookup_session_id"))
11251         key = L2T_LOOKUP_SESSION_ID;
11252       else
11253         break;
11254     }
11255
11256   if (key == (u8) ~ 0)
11257     {
11258       errmsg ("l2tp session lookup key unset");
11259       return -99;
11260     }
11261
11262   M (L2TPV3_SET_LOOKUP_KEY, mp);
11263
11264   mp->key = key;
11265
11266   S (mp);
11267   W (ret);
11268   return ret;
11269 }
11270
11271 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11272   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11273 {
11274   vat_main_t *vam = &vat_main;
11275
11276   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11277          format_ip6_address, mp->our_address,
11278          format_ip6_address, mp->client_address,
11279          clib_net_to_host_u32 (mp->sw_if_index));
11280
11281   print (vam->ofp,
11282          "   local cookies %016llx %016llx remote cookie %016llx",
11283          clib_net_to_host_u64 (mp->local_cookie[0]),
11284          clib_net_to_host_u64 (mp->local_cookie[1]),
11285          clib_net_to_host_u64 (mp->remote_cookie));
11286
11287   print (vam->ofp, "   local session-id %d remote session-id %d",
11288          clib_net_to_host_u32 (mp->local_session_id),
11289          clib_net_to_host_u32 (mp->remote_session_id));
11290
11291   print (vam->ofp, "   l2 specific sublayer %s\n",
11292          mp->l2_sublayer_present ? "preset" : "absent");
11293
11294 }
11295
11296 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11297   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11298 {
11299   vat_main_t *vam = &vat_main;
11300   vat_json_node_t *node = NULL;
11301   struct in6_addr addr;
11302
11303   if (VAT_JSON_ARRAY != vam->json_tree.type)
11304     {
11305       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11306       vat_json_init_array (&vam->json_tree);
11307     }
11308   node = vat_json_array_add (&vam->json_tree);
11309
11310   vat_json_init_object (node);
11311
11312   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11313   vat_json_object_add_ip6 (node, "our_address", addr);
11314   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11315   vat_json_object_add_ip6 (node, "client_address", addr);
11316
11317   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11318   vat_json_init_array (lc);
11319   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11320   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11321   vat_json_object_add_uint (node, "remote_cookie",
11322                             clib_net_to_host_u64 (mp->remote_cookie));
11323
11324   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11325   vat_json_object_add_uint (node, "local_session_id",
11326                             clib_net_to_host_u32 (mp->local_session_id));
11327   vat_json_object_add_uint (node, "remote_session_id",
11328                             clib_net_to_host_u32 (mp->remote_session_id));
11329   vat_json_object_add_string_copy (node, "l2_sublayer",
11330                                    mp->l2_sublayer_present ? (u8 *) "present"
11331                                    : (u8 *) "absent");
11332 }
11333
11334 static int
11335 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11336 {
11337   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11338   vl_api_control_ping_t *mp_ping;
11339   int ret;
11340
11341   /* Get list of l2tpv3-tunnel interfaces */
11342   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11343   S (mp);
11344
11345   /* Use a control ping for synchronization */
11346   MPING (CONTROL_PING, mp_ping);
11347   S (mp_ping);
11348
11349   W (ret);
11350   return ret;
11351 }
11352
11353
11354 static void vl_api_sw_interface_tap_v2_details_t_handler
11355   (vl_api_sw_interface_tap_v2_details_t * mp)
11356 {
11357   vat_main_t *vam = &vat_main;
11358
11359   u8 *ip4 =
11360     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11361             mp->host_ip4_prefix.len);
11362   u8 *ip6 =
11363     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11364             mp->host_ip6_prefix.len);
11365
11366   print (vam->ofp,
11367          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11368          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11369          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11370          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11371          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11372
11373   vec_free (ip4);
11374   vec_free (ip6);
11375 }
11376
11377 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11378   (vl_api_sw_interface_tap_v2_details_t * mp)
11379 {
11380   vat_main_t *vam = &vat_main;
11381   vat_json_node_t *node = NULL;
11382
11383   if (VAT_JSON_ARRAY != vam->json_tree.type)
11384     {
11385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11386       vat_json_init_array (&vam->json_tree);
11387     }
11388   node = vat_json_array_add (&vam->json_tree);
11389
11390   vat_json_init_object (node);
11391   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11393   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11394   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11395   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11396   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11397   vat_json_object_add_string_copy (node, "host_mac_addr",
11398                                    format (0, "%U", format_ethernet_address,
11399                                            &mp->host_mac_addr));
11400   vat_json_object_add_string_copy (node, "host_namespace",
11401                                    mp->host_namespace);
11402   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11403   vat_json_object_add_string_copy (node, "host_ip4_addr",
11404                                    format (0, "%U/%d", format_ip4_address,
11405                                            mp->host_ip4_prefix.address,
11406                                            mp->host_ip4_prefix.len));
11407   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11408                                    format (0, "%U/%d", format_ip6_address,
11409                                            mp->host_ip6_prefix.address,
11410                                            mp->host_ip6_prefix.len));
11411
11412 }
11413
11414 static int
11415 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11416 {
11417   vl_api_sw_interface_tap_v2_dump_t *mp;
11418   vl_api_control_ping_t *mp_ping;
11419   int ret;
11420
11421   print (vam->ofp,
11422          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11423          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11424          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11425          "host_ip6_addr");
11426
11427   /* Get list of tap interfaces */
11428   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11429   S (mp);
11430
11431   /* Use a control ping for synchronization */
11432   MPING (CONTROL_PING, mp_ping);
11433   S (mp_ping);
11434
11435   W (ret);
11436   return ret;
11437 }
11438
11439 static void vl_api_sw_interface_virtio_pci_details_t_handler
11440   (vl_api_sw_interface_virtio_pci_details_t * mp)
11441 {
11442   vat_main_t *vam = &vat_main;
11443
11444   typedef union
11445   {
11446     struct
11447     {
11448       u16 domain;
11449       u8 bus;
11450       u8 slot:5;
11451       u8 function:3;
11452     };
11453     u32 as_u32;
11454   } pci_addr_t;
11455   pci_addr_t addr;
11456
11457   addr.domain = ntohs (mp->pci_addr.domain);
11458   addr.bus = mp->pci_addr.bus;
11459   addr.slot = mp->pci_addr.slot;
11460   addr.function = mp->pci_addr.function;
11461
11462   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11463                          addr.slot, addr.function);
11464
11465   print (vam->ofp,
11466          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11467          pci_addr, ntohl (mp->sw_if_index),
11468          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11469          format_ethernet_address, mp->mac_addr,
11470          clib_net_to_host_u64 (mp->features));
11471   vec_free (pci_addr);
11472 }
11473
11474 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11475   (vl_api_sw_interface_virtio_pci_details_t * mp)
11476 {
11477   vat_main_t *vam = &vat_main;
11478   vat_json_node_t *node = NULL;
11479   vlib_pci_addr_t pci_addr;
11480
11481   if (VAT_JSON_ARRAY != vam->json_tree.type)
11482     {
11483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11484       vat_json_init_array (&vam->json_tree);
11485     }
11486   node = vat_json_array_add (&vam->json_tree);
11487
11488   pci_addr.domain = ntohs (mp->pci_addr.domain);
11489   pci_addr.bus = mp->pci_addr.bus;
11490   pci_addr.slot = mp->pci_addr.slot;
11491   pci_addr.function = mp->pci_addr.function;
11492
11493   vat_json_init_object (node);
11494   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11495   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11496   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11497   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11498   vat_json_object_add_uint (node, "features",
11499                             clib_net_to_host_u64 (mp->features));
11500   vat_json_object_add_string_copy (node, "mac_addr",
11501                                    format (0, "%U", format_ethernet_address,
11502                                            &mp->mac_addr));
11503 }
11504
11505 static int
11506 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11507 {
11508   vl_api_sw_interface_virtio_pci_dump_t *mp;
11509   vl_api_control_ping_t *mp_ping;
11510   int ret;
11511
11512   print (vam->ofp,
11513          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11514          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11515          "mac_addr", "features");
11516
11517   /* Get list of tap interfaces */
11518   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11519   S (mp);
11520
11521   /* Use a control ping for synchronization */
11522   MPING (CONTROL_PING, mp_ping);
11523   S (mp_ping);
11524
11525   W (ret);
11526   return ret;
11527 }
11528
11529 static int
11530 api_vxlan_offload_rx (vat_main_t * vam)
11531 {
11532   unformat_input_t *line_input = vam->input;
11533   vl_api_vxlan_offload_rx_t *mp;
11534   u32 hw_if_index = ~0, rx_if_index = ~0;
11535   u8 is_add = 1;
11536   int ret;
11537
11538   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11539     {
11540       if (unformat (line_input, "del"))
11541         is_add = 0;
11542       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11543                          &hw_if_index))
11544         ;
11545       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11546         ;
11547       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11548                          &rx_if_index))
11549         ;
11550       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11551         ;
11552       else
11553         {
11554           errmsg ("parse error '%U'", format_unformat_error, line_input);
11555           return -99;
11556         }
11557     }
11558
11559   if (hw_if_index == ~0)
11560     {
11561       errmsg ("no hw interface");
11562       return -99;
11563     }
11564
11565   if (rx_if_index == ~0)
11566     {
11567       errmsg ("no rx tunnel");
11568       return -99;
11569     }
11570
11571   M (VXLAN_OFFLOAD_RX, mp);
11572
11573   mp->hw_if_index = ntohl (hw_if_index);
11574   mp->sw_if_index = ntohl (rx_if_index);
11575   mp->enable = is_add;
11576
11577   S (mp);
11578   W (ret);
11579   return ret;
11580 }
11581
11582 static uword unformat_vxlan_decap_next
11583   (unformat_input_t * input, va_list * args)
11584 {
11585   u32 *result = va_arg (*args, u32 *);
11586   u32 tmp;
11587
11588   if (unformat (input, "l2"))
11589     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11590   else if (unformat (input, "%d", &tmp))
11591     *result = tmp;
11592   else
11593     return 0;
11594   return 1;
11595 }
11596
11597 static int
11598 api_vxlan_add_del_tunnel (vat_main_t * vam)
11599 {
11600   unformat_input_t *line_input = vam->input;
11601   vl_api_vxlan_add_del_tunnel_t *mp;
11602   ip46_address_t src, dst;
11603   u8 is_add = 1;
11604   u8 ipv4_set = 0, ipv6_set = 0;
11605   u8 src_set = 0;
11606   u8 dst_set = 0;
11607   u8 grp_set = 0;
11608   u32 instance = ~0;
11609   u32 mcast_sw_if_index = ~0;
11610   u32 encap_vrf_id = 0;
11611   u32 decap_next_index = ~0;
11612   u32 vni = 0;
11613   int ret;
11614
11615   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11616   clib_memset (&src, 0, sizeof src);
11617   clib_memset (&dst, 0, sizeof dst);
11618
11619   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11620     {
11621       if (unformat (line_input, "del"))
11622         is_add = 0;
11623       else if (unformat (line_input, "instance %d", &instance))
11624         ;
11625       else
11626         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11627         {
11628           ipv4_set = 1;
11629           src_set = 1;
11630         }
11631       else
11632         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11633         {
11634           ipv4_set = 1;
11635           dst_set = 1;
11636         }
11637       else
11638         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11639         {
11640           ipv6_set = 1;
11641           src_set = 1;
11642         }
11643       else
11644         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11645         {
11646           ipv6_set = 1;
11647           dst_set = 1;
11648         }
11649       else if (unformat (line_input, "group %U %U",
11650                          unformat_ip4_address, &dst.ip4,
11651                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11652         {
11653           grp_set = dst_set = 1;
11654           ipv4_set = 1;
11655         }
11656       else if (unformat (line_input, "group %U",
11657                          unformat_ip4_address, &dst.ip4))
11658         {
11659           grp_set = dst_set = 1;
11660           ipv4_set = 1;
11661         }
11662       else if (unformat (line_input, "group %U %U",
11663                          unformat_ip6_address, &dst.ip6,
11664                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11665         {
11666           grp_set = dst_set = 1;
11667           ipv6_set = 1;
11668         }
11669       else if (unformat (line_input, "group %U",
11670                          unformat_ip6_address, &dst.ip6))
11671         {
11672           grp_set = dst_set = 1;
11673           ipv6_set = 1;
11674         }
11675       else
11676         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11677         ;
11678       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11679         ;
11680       else if (unformat (line_input, "decap-next %U",
11681                          unformat_vxlan_decap_next, &decap_next_index))
11682         ;
11683       else if (unformat (line_input, "vni %d", &vni))
11684         ;
11685       else
11686         {
11687           errmsg ("parse error '%U'", format_unformat_error, line_input);
11688           return -99;
11689         }
11690     }
11691
11692   if (src_set == 0)
11693     {
11694       errmsg ("tunnel src address not specified");
11695       return -99;
11696     }
11697   if (dst_set == 0)
11698     {
11699       errmsg ("tunnel dst address not specified");
11700       return -99;
11701     }
11702
11703   if (grp_set && !ip46_address_is_multicast (&dst))
11704     {
11705       errmsg ("tunnel group address not multicast");
11706       return -99;
11707     }
11708   if (grp_set && mcast_sw_if_index == ~0)
11709     {
11710       errmsg ("tunnel nonexistent multicast device");
11711       return -99;
11712     }
11713   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11714     {
11715       errmsg ("tunnel dst address must be unicast");
11716       return -99;
11717     }
11718
11719
11720   if (ipv4_set && ipv6_set)
11721     {
11722       errmsg ("both IPv4 and IPv6 addresses specified");
11723       return -99;
11724     }
11725
11726   if ((vni == 0) || (vni >> 24))
11727     {
11728       errmsg ("vni not specified or out of range");
11729       return -99;
11730     }
11731
11732   M (VXLAN_ADD_DEL_TUNNEL, mp);
11733
11734   if (ipv6_set)
11735     {
11736       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11737       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11738     }
11739   else
11740     {
11741       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11742       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11743     }
11744
11745   mp->instance = htonl (instance);
11746   mp->encap_vrf_id = ntohl (encap_vrf_id);
11747   mp->decap_next_index = ntohl (decap_next_index);
11748   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11749   mp->vni = ntohl (vni);
11750   mp->is_add = is_add;
11751   mp->is_ipv6 = ipv6_set;
11752
11753   S (mp);
11754   W (ret);
11755   return ret;
11756 }
11757
11758 static void vl_api_vxlan_tunnel_details_t_handler
11759   (vl_api_vxlan_tunnel_details_t * mp)
11760 {
11761   vat_main_t *vam = &vat_main;
11762   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11763   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11764
11765   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11766          ntohl (mp->sw_if_index),
11767          ntohl (mp->instance),
11768          format_ip46_address, &src, IP46_TYPE_ANY,
11769          format_ip46_address, &dst, IP46_TYPE_ANY,
11770          ntohl (mp->encap_vrf_id),
11771          ntohl (mp->decap_next_index), ntohl (mp->vni),
11772          ntohl (mp->mcast_sw_if_index));
11773 }
11774
11775 static void vl_api_vxlan_tunnel_details_t_handler_json
11776   (vl_api_vxlan_tunnel_details_t * mp)
11777 {
11778   vat_main_t *vam = &vat_main;
11779   vat_json_node_t *node = NULL;
11780
11781   if (VAT_JSON_ARRAY != vam->json_tree.type)
11782     {
11783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11784       vat_json_init_array (&vam->json_tree);
11785     }
11786   node = vat_json_array_add (&vam->json_tree);
11787
11788   vat_json_init_object (node);
11789   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11790
11791   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11792
11793   if (mp->is_ipv6)
11794     {
11795       struct in6_addr ip6;
11796
11797       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11798       vat_json_object_add_ip6 (node, "src_address", ip6);
11799       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11800       vat_json_object_add_ip6 (node, "dst_address", ip6);
11801     }
11802   else
11803     {
11804       struct in_addr ip4;
11805
11806       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11807       vat_json_object_add_ip4 (node, "src_address", ip4);
11808       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11809       vat_json_object_add_ip4 (node, "dst_address", ip4);
11810     }
11811   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11812   vat_json_object_add_uint (node, "decap_next_index",
11813                             ntohl (mp->decap_next_index));
11814   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11815   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11816   vat_json_object_add_uint (node, "mcast_sw_if_index",
11817                             ntohl (mp->mcast_sw_if_index));
11818 }
11819
11820 static int
11821 api_vxlan_tunnel_dump (vat_main_t * vam)
11822 {
11823   unformat_input_t *i = vam->input;
11824   vl_api_vxlan_tunnel_dump_t *mp;
11825   vl_api_control_ping_t *mp_ping;
11826   u32 sw_if_index;
11827   u8 sw_if_index_set = 0;
11828   int ret;
11829
11830   /* Parse args required to build the message */
11831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (i, "sw_if_index %d", &sw_if_index))
11834         sw_if_index_set = 1;
11835       else
11836         break;
11837     }
11838
11839   if (sw_if_index_set == 0)
11840     {
11841       sw_if_index = ~0;
11842     }
11843
11844   if (!vam->json_output)
11845     {
11846       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11847              "sw_if_index", "instance", "src_address", "dst_address",
11848              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11849     }
11850
11851   /* Get list of vxlan-tunnel interfaces */
11852   M (VXLAN_TUNNEL_DUMP, mp);
11853
11854   mp->sw_if_index = htonl (sw_if_index);
11855
11856   S (mp);
11857
11858   /* Use a control ping for synchronization */
11859   MPING (CONTROL_PING, mp_ping);
11860   S (mp_ping);
11861
11862   W (ret);
11863   return ret;
11864 }
11865
11866 static uword unformat_geneve_decap_next
11867   (unformat_input_t * input, va_list * args)
11868 {
11869   u32 *result = va_arg (*args, u32 *);
11870   u32 tmp;
11871
11872   if (unformat (input, "l2"))
11873     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11874   else if (unformat (input, "%d", &tmp))
11875     *result = tmp;
11876   else
11877     return 0;
11878   return 1;
11879 }
11880
11881 static int
11882 api_geneve_add_del_tunnel (vat_main_t * vam)
11883 {
11884   unformat_input_t *line_input = vam->input;
11885   vl_api_geneve_add_del_tunnel_t *mp;
11886   ip46_address_t src, dst;
11887   u8 is_add = 1;
11888   u8 ipv4_set = 0, ipv6_set = 0;
11889   u8 src_set = 0;
11890   u8 dst_set = 0;
11891   u8 grp_set = 0;
11892   u32 mcast_sw_if_index = ~0;
11893   u32 encap_vrf_id = 0;
11894   u32 decap_next_index = ~0;
11895   u32 vni = 0;
11896   int ret;
11897
11898   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11899   clib_memset (&src, 0, sizeof src);
11900   clib_memset (&dst, 0, sizeof dst);
11901
11902   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11903     {
11904       if (unformat (line_input, "del"))
11905         is_add = 0;
11906       else
11907         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11908         {
11909           ipv4_set = 1;
11910           src_set = 1;
11911         }
11912       else
11913         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11914         {
11915           ipv4_set = 1;
11916           dst_set = 1;
11917         }
11918       else
11919         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11920         {
11921           ipv6_set = 1;
11922           src_set = 1;
11923         }
11924       else
11925         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11926         {
11927           ipv6_set = 1;
11928           dst_set = 1;
11929         }
11930       else if (unformat (line_input, "group %U %U",
11931                          unformat_ip4_address, &dst.ip4,
11932                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11933         {
11934           grp_set = dst_set = 1;
11935           ipv4_set = 1;
11936         }
11937       else if (unformat (line_input, "group %U",
11938                          unformat_ip4_address, &dst.ip4))
11939         {
11940           grp_set = dst_set = 1;
11941           ipv4_set = 1;
11942         }
11943       else if (unformat (line_input, "group %U %U",
11944                          unformat_ip6_address, &dst.ip6,
11945                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11946         {
11947           grp_set = dst_set = 1;
11948           ipv6_set = 1;
11949         }
11950       else if (unformat (line_input, "group %U",
11951                          unformat_ip6_address, &dst.ip6))
11952         {
11953           grp_set = dst_set = 1;
11954           ipv6_set = 1;
11955         }
11956       else
11957         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11958         ;
11959       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11960         ;
11961       else if (unformat (line_input, "decap-next %U",
11962                          unformat_geneve_decap_next, &decap_next_index))
11963         ;
11964       else if (unformat (line_input, "vni %d", &vni))
11965         ;
11966       else
11967         {
11968           errmsg ("parse error '%U'", format_unformat_error, line_input);
11969           return -99;
11970         }
11971     }
11972
11973   if (src_set == 0)
11974     {
11975       errmsg ("tunnel src address not specified");
11976       return -99;
11977     }
11978   if (dst_set == 0)
11979     {
11980       errmsg ("tunnel dst address not specified");
11981       return -99;
11982     }
11983
11984   if (grp_set && !ip46_address_is_multicast (&dst))
11985     {
11986       errmsg ("tunnel group address not multicast");
11987       return -99;
11988     }
11989   if (grp_set && mcast_sw_if_index == ~0)
11990     {
11991       errmsg ("tunnel nonexistent multicast device");
11992       return -99;
11993     }
11994   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11995     {
11996       errmsg ("tunnel dst address must be unicast");
11997       return -99;
11998     }
11999
12000
12001   if (ipv4_set && ipv6_set)
12002     {
12003       errmsg ("both IPv4 and IPv6 addresses specified");
12004       return -99;
12005     }
12006
12007   if ((vni == 0) || (vni >> 24))
12008     {
12009       errmsg ("vni not specified or out of range");
12010       return -99;
12011     }
12012
12013   M (GENEVE_ADD_DEL_TUNNEL, mp);
12014
12015   if (ipv6_set)
12016     {
12017       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12018       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12019     }
12020   else
12021     {
12022       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12023       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12024     }
12025   mp->encap_vrf_id = ntohl (encap_vrf_id);
12026   mp->decap_next_index = ntohl (decap_next_index);
12027   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12028   mp->vni = ntohl (vni);
12029   mp->is_add = is_add;
12030
12031   S (mp);
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static void vl_api_geneve_tunnel_details_t_handler
12037   (vl_api_geneve_tunnel_details_t * mp)
12038 {
12039   vat_main_t *vam = &vat_main;
12040   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12041   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12042
12043   if (mp->src_address.af == ADDRESS_IP6)
12044     {
12045       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12046       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12047     }
12048   else
12049     {
12050       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12051       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12052     }
12053
12054   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12055          ntohl (mp->sw_if_index),
12056          format_ip46_address, &src, IP46_TYPE_ANY,
12057          format_ip46_address, &dst, IP46_TYPE_ANY,
12058          ntohl (mp->encap_vrf_id),
12059          ntohl (mp->decap_next_index), ntohl (mp->vni),
12060          ntohl (mp->mcast_sw_if_index));
12061 }
12062
12063 static void vl_api_geneve_tunnel_details_t_handler_json
12064   (vl_api_geneve_tunnel_details_t * mp)
12065 {
12066   vat_main_t *vam = &vat_main;
12067   vat_json_node_t *node = NULL;
12068   bool is_ipv6;
12069
12070   if (VAT_JSON_ARRAY != vam->json_tree.type)
12071     {
12072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12073       vat_json_init_array (&vam->json_tree);
12074     }
12075   node = vat_json_array_add (&vam->json_tree);
12076
12077   vat_json_init_object (node);
12078   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12079   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12080   if (is_ipv6)
12081     {
12082       struct in6_addr ip6;
12083
12084       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12085       vat_json_object_add_ip6 (node, "src_address", ip6);
12086       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12087       vat_json_object_add_ip6 (node, "dst_address", ip6);
12088     }
12089   else
12090     {
12091       struct in_addr ip4;
12092
12093       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12094       vat_json_object_add_ip4 (node, "src_address", ip4);
12095       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12096       vat_json_object_add_ip4 (node, "dst_address", ip4);
12097     }
12098   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12099   vat_json_object_add_uint (node, "decap_next_index",
12100                             ntohl (mp->decap_next_index));
12101   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12102   vat_json_object_add_uint (node, "mcast_sw_if_index",
12103                             ntohl (mp->mcast_sw_if_index));
12104 }
12105
12106 static int
12107 api_geneve_tunnel_dump (vat_main_t * vam)
12108 {
12109   unformat_input_t *i = vam->input;
12110   vl_api_geneve_tunnel_dump_t *mp;
12111   vl_api_control_ping_t *mp_ping;
12112   u32 sw_if_index;
12113   u8 sw_if_index_set = 0;
12114   int ret;
12115
12116   /* Parse args required to build the message */
12117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12118     {
12119       if (unformat (i, "sw_if_index %d", &sw_if_index))
12120         sw_if_index_set = 1;
12121       else
12122         break;
12123     }
12124
12125   if (sw_if_index_set == 0)
12126     {
12127       sw_if_index = ~0;
12128     }
12129
12130   if (!vam->json_output)
12131     {
12132       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12133              "sw_if_index", "local_address", "remote_address",
12134              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12135     }
12136
12137   /* Get list of geneve-tunnel interfaces */
12138   M (GENEVE_TUNNEL_DUMP, mp);
12139
12140   mp->sw_if_index = htonl (sw_if_index);
12141
12142   S (mp);
12143
12144   /* Use a control ping for synchronization */
12145   M (CONTROL_PING, mp_ping);
12146   S (mp_ping);
12147
12148   W (ret);
12149   return ret;
12150 }
12151
12152 static int
12153 api_gre_tunnel_add_del (vat_main_t * vam)
12154 {
12155   unformat_input_t *line_input = vam->input;
12156   vl_api_address_t src = { }, dst =
12157   {
12158   };
12159   vl_api_gre_tunnel_add_del_t *mp;
12160   vl_api_gre_tunnel_type_t t_type;
12161   u8 is_add = 1;
12162   u8 src_set = 0;
12163   u8 dst_set = 0;
12164   u32 outer_table_id = 0;
12165   u32 session_id = 0;
12166   u32 instance = ~0;
12167   int ret;
12168
12169   t_type = GRE_API_TUNNEL_TYPE_L3;
12170
12171   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (line_input, "del"))
12174         is_add = 0;
12175       else if (unformat (line_input, "instance %d", &instance))
12176         ;
12177       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12178         {
12179           src_set = 1;
12180         }
12181       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12182         {
12183           dst_set = 1;
12184         }
12185       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12186         ;
12187       else if (unformat (line_input, "teb"))
12188         t_type = GRE_API_TUNNEL_TYPE_TEB;
12189       else if (unformat (line_input, "erspan %d", &session_id))
12190         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12191       else
12192         {
12193           errmsg ("parse error '%U'", format_unformat_error, line_input);
12194           return -99;
12195         }
12196     }
12197
12198   if (src_set == 0)
12199     {
12200       errmsg ("tunnel src address not specified");
12201       return -99;
12202     }
12203   if (dst_set == 0)
12204     {
12205       errmsg ("tunnel dst address not specified");
12206       return -99;
12207     }
12208
12209   M (GRE_TUNNEL_ADD_DEL, mp);
12210
12211   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12212   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12213
12214   mp->tunnel.instance = htonl (instance);
12215   mp->tunnel.outer_table_id = htonl (outer_table_id);
12216   mp->is_add = is_add;
12217   mp->tunnel.session_id = htons ((u16) session_id);
12218   mp->tunnel.type = htonl (t_type);
12219
12220   S (mp);
12221   W (ret);
12222   return ret;
12223 }
12224
12225 static void vl_api_gre_tunnel_details_t_handler
12226   (vl_api_gre_tunnel_details_t * mp)
12227 {
12228   vat_main_t *vam = &vat_main;
12229
12230   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12231          ntohl (mp->tunnel.sw_if_index),
12232          ntohl (mp->tunnel.instance),
12233          format_vl_api_address, &mp->tunnel.src,
12234          format_vl_api_address, &mp->tunnel.dst,
12235          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12236          ntohl (mp->tunnel.session_id));
12237 }
12238
12239 static void vl_api_gre_tunnel_details_t_handler_json
12240   (vl_api_gre_tunnel_details_t * mp)
12241 {
12242   vat_main_t *vam = &vat_main;
12243   vat_json_node_t *node = NULL;
12244
12245   if (VAT_JSON_ARRAY != vam->json_tree.type)
12246     {
12247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12248       vat_json_init_array (&vam->json_tree);
12249     }
12250   node = vat_json_array_add (&vam->json_tree);
12251
12252   vat_json_init_object (node);
12253   vat_json_object_add_uint (node, "sw_if_index",
12254                             ntohl (mp->tunnel.sw_if_index));
12255   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12256
12257   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12258   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12259   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12260   vat_json_object_add_uint (node, "outer_table_id",
12261                             ntohl (mp->tunnel.outer_table_id));
12262   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12263 }
12264
12265 static int
12266 api_gre_tunnel_dump (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_gre_tunnel_dump_t *mp;
12270   vl_api_control_ping_t *mp_ping;
12271   u32 sw_if_index;
12272   u8 sw_if_index_set = 0;
12273   int ret;
12274
12275   /* Parse args required to build the message */
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "sw_if_index %d", &sw_if_index))
12279         sw_if_index_set = 1;
12280       else
12281         break;
12282     }
12283
12284   if (sw_if_index_set == 0)
12285     {
12286       sw_if_index = ~0;
12287     }
12288
12289   if (!vam->json_output)
12290     {
12291       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12292              "sw_if_index", "instance", "src_address", "dst_address",
12293              "tunnel_type", "outer_fib_id", "session_id");
12294     }
12295
12296   /* Get list of gre-tunnel interfaces */
12297   M (GRE_TUNNEL_DUMP, mp);
12298
12299   mp->sw_if_index = htonl (sw_if_index);
12300
12301   S (mp);
12302
12303   /* Use a control ping for synchronization */
12304   MPING (CONTROL_PING, mp_ping);
12305   S (mp_ping);
12306
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static int
12312 api_l2_fib_clear_table (vat_main_t * vam)
12313 {
12314 //  unformat_input_t * i = vam->input;
12315   vl_api_l2_fib_clear_table_t *mp;
12316   int ret;
12317
12318   M (L2_FIB_CLEAR_TABLE, mp);
12319
12320   S (mp);
12321   W (ret);
12322   return ret;
12323 }
12324
12325 static int
12326 api_l2_interface_efp_filter (vat_main_t * vam)
12327 {
12328   unformat_input_t *i = vam->input;
12329   vl_api_l2_interface_efp_filter_t *mp;
12330   u32 sw_if_index;
12331   u8 enable = 1;
12332   u8 sw_if_index_set = 0;
12333   int ret;
12334
12335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12338         sw_if_index_set = 1;
12339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12340         sw_if_index_set = 1;
12341       else if (unformat (i, "enable"))
12342         enable = 1;
12343       else if (unformat (i, "disable"))
12344         enable = 0;
12345       else
12346         {
12347           clib_warning ("parse error '%U'", format_unformat_error, i);
12348           return -99;
12349         }
12350     }
12351
12352   if (sw_if_index_set == 0)
12353     {
12354       errmsg ("missing sw_if_index");
12355       return -99;
12356     }
12357
12358   M (L2_INTERFACE_EFP_FILTER, mp);
12359
12360   mp->sw_if_index = ntohl (sw_if_index);
12361   mp->enable_disable = enable;
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 #define foreach_vtr_op                          \
12369 _("disable",  L2_VTR_DISABLED)                  \
12370 _("push-1",  L2_VTR_PUSH_1)                     \
12371 _("push-2",  L2_VTR_PUSH_2)                     \
12372 _("pop-1",  L2_VTR_POP_1)                       \
12373 _("pop-2",  L2_VTR_POP_2)                       \
12374 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12375 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12376 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12377 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12378
12379 static int
12380 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12384   u32 sw_if_index;
12385   u8 sw_if_index_set = 0;
12386   u8 vtr_op_set = 0;
12387   u32 vtr_op = 0;
12388   u32 push_dot1q = 1;
12389   u32 tag1 = ~0;
12390   u32 tag2 = ~0;
12391   int ret;
12392
12393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12394     {
12395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12398         sw_if_index_set = 1;
12399       else if (unformat (i, "vtr_op %d", &vtr_op))
12400         vtr_op_set = 1;
12401 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12402       foreach_vtr_op
12403 #undef _
12404         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12405         ;
12406       else if (unformat (i, "tag1 %d", &tag1))
12407         ;
12408       else if (unformat (i, "tag2 %d", &tag2))
12409         ;
12410       else
12411         {
12412           clib_warning ("parse error '%U'", format_unformat_error, i);
12413           return -99;
12414         }
12415     }
12416
12417   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12418     {
12419       errmsg ("missing vtr operation or sw_if_index");
12420       return -99;
12421     }
12422
12423   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12424   mp->sw_if_index = ntohl (sw_if_index);
12425   mp->vtr_op = ntohl (vtr_op);
12426   mp->push_dot1q = ntohl (push_dot1q);
12427   mp->tag1 = ntohl (tag1);
12428   mp->tag2 = ntohl (tag2);
12429
12430   S (mp);
12431   W (ret);
12432   return ret;
12433 }
12434
12435 static int
12436 api_create_vhost_user_if (vat_main_t * vam)
12437 {
12438   unformat_input_t *i = vam->input;
12439   vl_api_create_vhost_user_if_t *mp;
12440   u8 *file_name;
12441   u8 is_server = 0;
12442   u8 file_name_set = 0;
12443   u32 custom_dev_instance = ~0;
12444   u8 hwaddr[6];
12445   u8 use_custom_mac = 0;
12446   u8 disable_mrg_rxbuf = 0;
12447   u8 disable_indirect_desc = 0;
12448   u8 *tag = 0;
12449   u8 enable_gso = 0;
12450   int ret;
12451
12452   /* Shut up coverity */
12453   clib_memset (hwaddr, 0, sizeof (hwaddr));
12454
12455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12456     {
12457       if (unformat (i, "socket %s", &file_name))
12458         {
12459           file_name_set = 1;
12460         }
12461       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12462         ;
12463       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12464         use_custom_mac = 1;
12465       else if (unformat (i, "server"))
12466         is_server = 1;
12467       else if (unformat (i, "disable_mrg_rxbuf"))
12468         disable_mrg_rxbuf = 1;
12469       else if (unformat (i, "disable_indirect_desc"))
12470         disable_indirect_desc = 1;
12471       else if (unformat (i, "gso"))
12472         enable_gso = 1;
12473       else if (unformat (i, "tag %s", &tag))
12474         ;
12475       else
12476         break;
12477     }
12478
12479   if (file_name_set == 0)
12480     {
12481       errmsg ("missing socket file name");
12482       return -99;
12483     }
12484
12485   if (vec_len (file_name) > 255)
12486     {
12487       errmsg ("socket file name too long");
12488       return -99;
12489     }
12490   vec_add1 (file_name, 0);
12491
12492   M (CREATE_VHOST_USER_IF, mp);
12493
12494   mp->is_server = is_server;
12495   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12496   mp->disable_indirect_desc = disable_indirect_desc;
12497   mp->enable_gso = enable_gso;
12498   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12499   vec_free (file_name);
12500   if (custom_dev_instance != ~0)
12501     {
12502       mp->renumber = 1;
12503       mp->custom_dev_instance = ntohl (custom_dev_instance);
12504     }
12505
12506   mp->use_custom_mac = use_custom_mac;
12507   clib_memcpy (mp->mac_address, hwaddr, 6);
12508   if (tag)
12509     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12510   vec_free (tag);
12511
12512   S (mp);
12513   W (ret);
12514   return ret;
12515 }
12516
12517 static int
12518 api_modify_vhost_user_if (vat_main_t * vam)
12519 {
12520   unformat_input_t *i = vam->input;
12521   vl_api_modify_vhost_user_if_t *mp;
12522   u8 *file_name;
12523   u8 is_server = 0;
12524   u8 file_name_set = 0;
12525   u32 custom_dev_instance = ~0;
12526   u8 sw_if_index_set = 0;
12527   u32 sw_if_index = (u32) ~ 0;
12528   u8 enable_gso = 0;
12529   int ret;
12530
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12534         sw_if_index_set = 1;
12535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12536         sw_if_index_set = 1;
12537       else if (unformat (i, "socket %s", &file_name))
12538         {
12539           file_name_set = 1;
12540         }
12541       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12542         ;
12543       else if (unformat (i, "server"))
12544         is_server = 1;
12545       else if (unformat (i, "gso"))
12546         enable_gso = 1;
12547       else
12548         break;
12549     }
12550
12551   if (sw_if_index_set == 0)
12552     {
12553       errmsg ("missing sw_if_index or interface name");
12554       return -99;
12555     }
12556
12557   if (file_name_set == 0)
12558     {
12559       errmsg ("missing socket file name");
12560       return -99;
12561     }
12562
12563   if (vec_len (file_name) > 255)
12564     {
12565       errmsg ("socket file name too long");
12566       return -99;
12567     }
12568   vec_add1 (file_name, 0);
12569
12570   M (MODIFY_VHOST_USER_IF, mp);
12571
12572   mp->sw_if_index = ntohl (sw_if_index);
12573   mp->is_server = is_server;
12574   mp->enable_gso = enable_gso;
12575   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12576   vec_free (file_name);
12577   if (custom_dev_instance != ~0)
12578     {
12579       mp->renumber = 1;
12580       mp->custom_dev_instance = ntohl (custom_dev_instance);
12581     }
12582
12583   S (mp);
12584   W (ret);
12585   return ret;
12586 }
12587
12588 static int
12589 api_delete_vhost_user_if (vat_main_t * vam)
12590 {
12591   unformat_input_t *i = vam->input;
12592   vl_api_delete_vhost_user_if_t *mp;
12593   u32 sw_if_index = ~0;
12594   u8 sw_if_index_set = 0;
12595   int ret;
12596
12597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12598     {
12599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12600         sw_if_index_set = 1;
12601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12602         sw_if_index_set = 1;
12603       else
12604         break;
12605     }
12606
12607   if (sw_if_index_set == 0)
12608     {
12609       errmsg ("missing sw_if_index or interface name");
12610       return -99;
12611     }
12612
12613
12614   M (DELETE_VHOST_USER_IF, mp);
12615
12616   mp->sw_if_index = ntohl (sw_if_index);
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static void vl_api_sw_interface_vhost_user_details_t_handler
12624   (vl_api_sw_interface_vhost_user_details_t * mp)
12625 {
12626   vat_main_t *vam = &vat_main;
12627   u64 features;
12628
12629   features =
12630     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12631                                                     clib_net_to_host_u32
12632                                                     (mp->features_last_32) <<
12633                                                     32);
12634
12635   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12636          (char *) mp->interface_name,
12637          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12638          features, mp->is_server,
12639          ntohl (mp->num_regions), (char *) mp->sock_filename);
12640   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12641 }
12642
12643 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12644   (vl_api_sw_interface_vhost_user_details_t * mp)
12645 {
12646   vat_main_t *vam = &vat_main;
12647   vat_json_node_t *node = NULL;
12648
12649   if (VAT_JSON_ARRAY != vam->json_tree.type)
12650     {
12651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12652       vat_json_init_array (&vam->json_tree);
12653     }
12654   node = vat_json_array_add (&vam->json_tree);
12655
12656   vat_json_init_object (node);
12657   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12658   vat_json_object_add_string_copy (node, "interface_name",
12659                                    mp->interface_name);
12660   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12661                             ntohl (mp->virtio_net_hdr_sz));
12662   vat_json_object_add_uint (node, "features_first_32",
12663                             clib_net_to_host_u32 (mp->features_first_32));
12664   vat_json_object_add_uint (node, "features_last_32",
12665                             clib_net_to_host_u32 (mp->features_last_32));
12666   vat_json_object_add_uint (node, "is_server", mp->is_server);
12667   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12668   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12669   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12670 }
12671
12672 static int
12673 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12674 {
12675   vl_api_sw_interface_vhost_user_dump_t *mp;
12676   vl_api_control_ping_t *mp_ping;
12677   int ret;
12678   print (vam->ofp,
12679          "Interface name            idx hdr_sz features server regions filename");
12680
12681   /* Get list of vhost-user interfaces */
12682   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12683   mp->sw_if_index = ntohl (~0);
12684   S (mp);
12685
12686   /* Use a control ping for synchronization */
12687   MPING (CONTROL_PING, mp_ping);
12688   S (mp_ping);
12689
12690   W (ret);
12691   return ret;
12692 }
12693
12694 static int
12695 api_show_version (vat_main_t * vam)
12696 {
12697   vl_api_show_version_t *mp;
12698   int ret;
12699
12700   M (SHOW_VERSION, mp);
12701
12702   S (mp);
12703   W (ret);
12704   return ret;
12705 }
12706
12707
12708 static int
12709 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12710 {
12711   unformat_input_t *line_input = vam->input;
12712   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12713   ip46_address_t local, remote;
12714   u8 is_add = 1;
12715   u8 local_set = 0;
12716   u8 remote_set = 0;
12717   u8 grp_set = 0;
12718   u32 mcast_sw_if_index = ~0;
12719   u32 encap_vrf_id = 0;
12720   u32 decap_vrf_id = 0;
12721   u8 protocol = ~0;
12722   u32 vni;
12723   u8 vni_set = 0;
12724   int ret;
12725
12726   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12727     {
12728       if (unformat (line_input, "del"))
12729         is_add = 0;
12730       else if (unformat (line_input, "local %U",
12731                          unformat_ip46_address, &local))
12732         {
12733           local_set = 1;
12734         }
12735       else if (unformat (line_input, "remote %U",
12736                          unformat_ip46_address, &remote))
12737         {
12738           remote_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U %U",
12741                          unformat_ip46_address, &remote,
12742                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12743         {
12744           grp_set = remote_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U",
12747                          unformat_ip46_address, &remote))
12748         {
12749           grp_set = remote_set = 1;
12750         }
12751       else
12752         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12753         ;
12754       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12755         ;
12756       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12757         ;
12758       else if (unformat (line_input, "vni %d", &vni))
12759         vni_set = 1;
12760       else if (unformat (line_input, "next-ip4"))
12761         protocol = 1;
12762       else if (unformat (line_input, "next-ip6"))
12763         protocol = 2;
12764       else if (unformat (line_input, "next-ethernet"))
12765         protocol = 3;
12766       else if (unformat (line_input, "next-nsh"))
12767         protocol = 4;
12768       else
12769         {
12770           errmsg ("parse error '%U'", format_unformat_error, line_input);
12771           return -99;
12772         }
12773     }
12774
12775   if (local_set == 0)
12776     {
12777       errmsg ("tunnel local address not specified");
12778       return -99;
12779     }
12780   if (remote_set == 0)
12781     {
12782       errmsg ("tunnel remote address not specified");
12783       return -99;
12784     }
12785   if (grp_set && mcast_sw_if_index == ~0)
12786     {
12787       errmsg ("tunnel nonexistent multicast device");
12788       return -99;
12789     }
12790   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12791     {
12792       errmsg ("both IPv4 and IPv6 addresses specified");
12793       return -99;
12794     }
12795
12796   if (vni_set == 0)
12797     {
12798       errmsg ("vni not specified");
12799       return -99;
12800     }
12801
12802   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12803
12804   ip_address_encode (&local,
12805                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12806                      IP46_TYPE_IP6, &mp->local);
12807   ip_address_encode (&remote,
12808                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12809                      IP46_TYPE_IP6, &mp->remote);
12810
12811   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12812   mp->encap_vrf_id = ntohl (encap_vrf_id);
12813   mp->decap_vrf_id = ntohl (decap_vrf_id);
12814   mp->protocol = protocol;
12815   mp->vni = ntohl (vni);
12816   mp->is_add = is_add;
12817
12818   S (mp);
12819   W (ret);
12820   return ret;
12821 }
12822
12823 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12824   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12825 {
12826   vat_main_t *vam = &vat_main;
12827   ip46_address_t local, remote;
12828
12829   ip_address_decode (&mp->local, &local);
12830   ip_address_decode (&mp->remote, &remote);
12831
12832   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12833          ntohl (mp->sw_if_index),
12834          format_ip46_address, &local, IP46_TYPE_ANY,
12835          format_ip46_address, &remote, IP46_TYPE_ANY,
12836          ntohl (mp->vni), mp->protocol,
12837          ntohl (mp->mcast_sw_if_index),
12838          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12839 }
12840
12841
12842 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12843   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12844 {
12845   vat_main_t *vam = &vat_main;
12846   vat_json_node_t *node = NULL;
12847   struct in_addr ip4;
12848   struct in6_addr ip6;
12849   ip46_address_t local, remote;
12850
12851   ip_address_decode (&mp->local, &local);
12852   ip_address_decode (&mp->remote, &remote);
12853
12854   if (VAT_JSON_ARRAY != vam->json_tree.type)
12855     {
12856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12857       vat_json_init_array (&vam->json_tree);
12858     }
12859   node = vat_json_array_add (&vam->json_tree);
12860
12861   vat_json_init_object (node);
12862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12863   if (ip46_address_is_ip4 (&local))
12864     {
12865       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12866       vat_json_object_add_ip4 (node, "local", ip4);
12867       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12868       vat_json_object_add_ip4 (node, "remote", ip4);
12869     }
12870   else
12871     {
12872       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12873       vat_json_object_add_ip6 (node, "local", ip6);
12874       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12875       vat_json_object_add_ip6 (node, "remote", ip6);
12876     }
12877   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12878   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12879   vat_json_object_add_uint (node, "mcast_sw_if_index",
12880                             ntohl (mp->mcast_sw_if_index));
12881   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12882   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12883   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12884 }
12885
12886 static int
12887 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12888 {
12889   unformat_input_t *i = vam->input;
12890   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12891   vl_api_control_ping_t *mp_ping;
12892   u32 sw_if_index;
12893   u8 sw_if_index_set = 0;
12894   int ret;
12895
12896   /* Parse args required to build the message */
12897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12898     {
12899       if (unformat (i, "sw_if_index %d", &sw_if_index))
12900         sw_if_index_set = 1;
12901       else
12902         break;
12903     }
12904
12905   if (sw_if_index_set == 0)
12906     {
12907       sw_if_index = ~0;
12908     }
12909
12910   if (!vam->json_output)
12911     {
12912       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12913              "sw_if_index", "local", "remote", "vni",
12914              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12915     }
12916
12917   /* Get list of vxlan-tunnel interfaces */
12918   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12919
12920   mp->sw_if_index = htonl (sw_if_index);
12921
12922   S (mp);
12923
12924   /* Use a control ping for synchronization */
12925   MPING (CONTROL_PING, mp_ping);
12926   S (mp_ping);
12927
12928   W (ret);
12929   return ret;
12930 }
12931
12932 static void vl_api_l2_fib_table_details_t_handler
12933   (vl_api_l2_fib_table_details_t * mp)
12934 {
12935   vat_main_t *vam = &vat_main;
12936
12937   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12938          "       %d       %d     %d",
12939          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12940          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12941          mp->bvi_mac);
12942 }
12943
12944 static void vl_api_l2_fib_table_details_t_handler_json
12945   (vl_api_l2_fib_table_details_t * mp)
12946 {
12947   vat_main_t *vam = &vat_main;
12948   vat_json_node_t *node = NULL;
12949
12950   if (VAT_JSON_ARRAY != vam->json_tree.type)
12951     {
12952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12953       vat_json_init_array (&vam->json_tree);
12954     }
12955   node = vat_json_array_add (&vam->json_tree);
12956
12957   vat_json_init_object (node);
12958   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12959   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12960   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12961   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12962   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12963   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12964 }
12965
12966 static int
12967 api_l2_fib_table_dump (vat_main_t * vam)
12968 {
12969   unformat_input_t *i = vam->input;
12970   vl_api_l2_fib_table_dump_t *mp;
12971   vl_api_control_ping_t *mp_ping;
12972   u32 bd_id;
12973   u8 bd_id_set = 0;
12974   int ret;
12975
12976   /* Parse args required to build the message */
12977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (i, "bd_id %d", &bd_id))
12980         bd_id_set = 1;
12981       else
12982         break;
12983     }
12984
12985   if (bd_id_set == 0)
12986     {
12987       errmsg ("missing bridge domain");
12988       return -99;
12989     }
12990
12991   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12992
12993   /* Get list of l2 fib entries */
12994   M (L2_FIB_TABLE_DUMP, mp);
12995
12996   mp->bd_id = ntohl (bd_id);
12997   S (mp);
12998
12999   /* Use a control ping for synchronization */
13000   MPING (CONTROL_PING, mp_ping);
13001   S (mp_ping);
13002
13003   W (ret);
13004   return ret;
13005 }
13006
13007
13008 static int
13009 api_interface_name_renumber (vat_main_t * vam)
13010 {
13011   unformat_input_t *line_input = vam->input;
13012   vl_api_interface_name_renumber_t *mp;
13013   u32 sw_if_index = ~0;
13014   u32 new_show_dev_instance = ~0;
13015   int ret;
13016
13017   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13018     {
13019       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13020                     &sw_if_index))
13021         ;
13022       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13023         ;
13024       else if (unformat (line_input, "new_show_dev_instance %d",
13025                          &new_show_dev_instance))
13026         ;
13027       else
13028         break;
13029     }
13030
13031   if (sw_if_index == ~0)
13032     {
13033       errmsg ("missing interface name or sw_if_index");
13034       return -99;
13035     }
13036
13037   if (new_show_dev_instance == ~0)
13038     {
13039       errmsg ("missing new_show_dev_instance");
13040       return -99;
13041     }
13042
13043   M (INTERFACE_NAME_RENUMBER, mp);
13044
13045   mp->sw_if_index = ntohl (sw_if_index);
13046   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13047
13048   S (mp);
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_want_l2_macs_events (vat_main_t * vam)
13055 {
13056   unformat_input_t *line_input = vam->input;
13057   vl_api_want_l2_macs_events_t *mp;
13058   u8 enable_disable = 1;
13059   u32 scan_delay = 0;
13060   u32 max_macs_in_event = 0;
13061   u32 learn_limit = 0;
13062   int ret;
13063
13064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13065     {
13066       if (unformat (line_input, "learn-limit %d", &learn_limit))
13067         ;
13068       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13069         ;
13070       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13071         ;
13072       else if (unformat (line_input, "disable"))
13073         enable_disable = 0;
13074       else
13075         break;
13076     }
13077
13078   M (WANT_L2_MACS_EVENTS, mp);
13079   mp->enable_disable = enable_disable;
13080   mp->pid = htonl (getpid ());
13081   mp->learn_limit = htonl (learn_limit);
13082   mp->scan_delay = (u8) scan_delay;
13083   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13084   S (mp);
13085   W (ret);
13086   return ret;
13087 }
13088
13089 static int
13090 api_input_acl_set_interface (vat_main_t * vam)
13091 {
13092   unformat_input_t *i = vam->input;
13093   vl_api_input_acl_set_interface_t *mp;
13094   u32 sw_if_index;
13095   int sw_if_index_set;
13096   u32 ip4_table_index = ~0;
13097   u32 ip6_table_index = ~0;
13098   u32 l2_table_index = ~0;
13099   u8 is_add = 1;
13100   int ret;
13101
13102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13105         sw_if_index_set = 1;
13106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13107         sw_if_index_set = 1;
13108       else if (unformat (i, "del"))
13109         is_add = 0;
13110       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13111         ;
13112       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13113         ;
13114       else if (unformat (i, "l2-table %d", &l2_table_index))
13115         ;
13116       else
13117         {
13118           clib_warning ("parse error '%U'", format_unformat_error, i);
13119           return -99;
13120         }
13121     }
13122
13123   if (sw_if_index_set == 0)
13124     {
13125       errmsg ("missing interface name or sw_if_index");
13126       return -99;
13127     }
13128
13129   M (INPUT_ACL_SET_INTERFACE, mp);
13130
13131   mp->sw_if_index = ntohl (sw_if_index);
13132   mp->ip4_table_index = ntohl (ip4_table_index);
13133   mp->ip6_table_index = ntohl (ip6_table_index);
13134   mp->l2_table_index = ntohl (l2_table_index);
13135   mp->is_add = is_add;
13136
13137   S (mp);
13138   W (ret);
13139   return ret;
13140 }
13141
13142 static int
13143 api_output_acl_set_interface (vat_main_t * vam)
13144 {
13145   unformat_input_t *i = vam->input;
13146   vl_api_output_acl_set_interface_t *mp;
13147   u32 sw_if_index;
13148   int sw_if_index_set;
13149   u32 ip4_table_index = ~0;
13150   u32 ip6_table_index = ~0;
13151   u32 l2_table_index = ~0;
13152   u8 is_add = 1;
13153   int ret;
13154
13155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13156     {
13157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13158         sw_if_index_set = 1;
13159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13160         sw_if_index_set = 1;
13161       else if (unformat (i, "del"))
13162         is_add = 0;
13163       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13164         ;
13165       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13166         ;
13167       else if (unformat (i, "l2-table %d", &l2_table_index))
13168         ;
13169       else
13170         {
13171           clib_warning ("parse error '%U'", format_unformat_error, i);
13172           return -99;
13173         }
13174     }
13175
13176   if (sw_if_index_set == 0)
13177     {
13178       errmsg ("missing interface name or sw_if_index");
13179       return -99;
13180     }
13181
13182   M (OUTPUT_ACL_SET_INTERFACE, mp);
13183
13184   mp->sw_if_index = ntohl (sw_if_index);
13185   mp->ip4_table_index = ntohl (ip4_table_index);
13186   mp->ip6_table_index = ntohl (ip6_table_index);
13187   mp->l2_table_index = ntohl (l2_table_index);
13188   mp->is_add = is_add;
13189
13190   S (mp);
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_ip_address_dump (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_ip_address_dump_t *mp;
13200   vl_api_control_ping_t *mp_ping;
13201   u32 sw_if_index = ~0;
13202   u8 sw_if_index_set = 0;
13203   u8 ipv4_set = 0;
13204   u8 ipv6_set = 0;
13205   int ret;
13206
13207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13208     {
13209       if (unformat (i, "sw_if_index %d", &sw_if_index))
13210         sw_if_index_set = 1;
13211       else
13212         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13213         sw_if_index_set = 1;
13214       else if (unformat (i, "ipv4"))
13215         ipv4_set = 1;
13216       else if (unformat (i, "ipv6"))
13217         ipv6_set = 1;
13218       else
13219         break;
13220     }
13221
13222   if (ipv4_set && ipv6_set)
13223     {
13224       errmsg ("ipv4 and ipv6 flags cannot be both set");
13225       return -99;
13226     }
13227
13228   if ((!ipv4_set) && (!ipv6_set))
13229     {
13230       errmsg ("no ipv4 nor ipv6 flag set");
13231       return -99;
13232     }
13233
13234   if (sw_if_index_set == 0)
13235     {
13236       errmsg ("missing interface name or sw_if_index");
13237       return -99;
13238     }
13239
13240   vam->current_sw_if_index = sw_if_index;
13241   vam->is_ipv6 = ipv6_set;
13242
13243   M (IP_ADDRESS_DUMP, mp);
13244   mp->sw_if_index = ntohl (sw_if_index);
13245   mp->is_ipv6 = ipv6_set;
13246   S (mp);
13247
13248   /* Use a control ping for synchronization */
13249   MPING (CONTROL_PING, mp_ping);
13250   S (mp_ping);
13251
13252   W (ret);
13253   return ret;
13254 }
13255
13256 static int
13257 api_ip_dump (vat_main_t * vam)
13258 {
13259   vl_api_ip_dump_t *mp;
13260   vl_api_control_ping_t *mp_ping;
13261   unformat_input_t *in = vam->input;
13262   int ipv4_set = 0;
13263   int ipv6_set = 0;
13264   int is_ipv6;
13265   int i;
13266   int ret;
13267
13268   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (in, "ipv4"))
13271         ipv4_set = 1;
13272       else if (unformat (in, "ipv6"))
13273         ipv6_set = 1;
13274       else
13275         break;
13276     }
13277
13278   if (ipv4_set && ipv6_set)
13279     {
13280       errmsg ("ipv4 and ipv6 flags cannot be both set");
13281       return -99;
13282     }
13283
13284   if ((!ipv4_set) && (!ipv6_set))
13285     {
13286       errmsg ("no ipv4 nor ipv6 flag set");
13287       return -99;
13288     }
13289
13290   is_ipv6 = ipv6_set;
13291   vam->is_ipv6 = is_ipv6;
13292
13293   /* free old data */
13294   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13295     {
13296       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13297     }
13298   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13299
13300   M (IP_DUMP, mp);
13301   mp->is_ipv6 = ipv6_set;
13302   S (mp);
13303
13304   /* Use a control ping for synchronization */
13305   MPING (CONTROL_PING, mp_ping);
13306   S (mp_ping);
13307
13308   W (ret);
13309   return ret;
13310 }
13311
13312 static int
13313 api_ipsec_spd_add_del (vat_main_t * vam)
13314 {
13315   unformat_input_t *i = vam->input;
13316   vl_api_ipsec_spd_add_del_t *mp;
13317   u32 spd_id = ~0;
13318   u8 is_add = 1;
13319   int ret;
13320
13321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (i, "spd_id %d", &spd_id))
13324         ;
13325       else if (unformat (i, "del"))
13326         is_add = 0;
13327       else
13328         {
13329           clib_warning ("parse error '%U'", format_unformat_error, i);
13330           return -99;
13331         }
13332     }
13333   if (spd_id == ~0)
13334     {
13335       errmsg ("spd_id must be set");
13336       return -99;
13337     }
13338
13339   M (IPSEC_SPD_ADD_DEL, mp);
13340
13341   mp->spd_id = ntohl (spd_id);
13342   mp->is_add = is_add;
13343
13344   S (mp);
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_ipsec_interface_add_del_spd_t *mp;
13354   u32 sw_if_index;
13355   u8 sw_if_index_set = 0;
13356   u32 spd_id = (u32) ~ 0;
13357   u8 is_add = 1;
13358   int ret;
13359
13360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13361     {
13362       if (unformat (i, "del"))
13363         is_add = 0;
13364       else if (unformat (i, "spd_id %d", &spd_id))
13365         ;
13366       else
13367         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13368         sw_if_index_set = 1;
13369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13370         sw_if_index_set = 1;
13371       else
13372         {
13373           clib_warning ("parse error '%U'", format_unformat_error, i);
13374           return -99;
13375         }
13376
13377     }
13378
13379   if (spd_id == (u32) ~ 0)
13380     {
13381       errmsg ("spd_id must be set");
13382       return -99;
13383     }
13384
13385   if (sw_if_index_set == 0)
13386     {
13387       errmsg ("missing interface name or sw_if_index");
13388       return -99;
13389     }
13390
13391   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13392
13393   mp->spd_id = ntohl (spd_id);
13394   mp->sw_if_index = ntohl (sw_if_index);
13395   mp->is_add = is_add;
13396
13397   S (mp);
13398   W (ret);
13399   return ret;
13400 }
13401
13402 static int
13403 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13404 {
13405   unformat_input_t *i = vam->input;
13406   vl_api_ipsec_spd_entry_add_del_t *mp;
13407   u8 is_add = 1, is_outbound = 0;
13408   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13409   i32 priority = 0;
13410   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13411   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13412   vl_api_address_t laddr_start = { }, laddr_stop =
13413   {
13414   }, raddr_start =
13415   {
13416   }, raddr_stop =
13417   {
13418   };
13419   int ret;
13420
13421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (i, "del"))
13424         is_add = 0;
13425       if (unformat (i, "outbound"))
13426         is_outbound = 1;
13427       if (unformat (i, "inbound"))
13428         is_outbound = 0;
13429       else if (unformat (i, "spd_id %d", &spd_id))
13430         ;
13431       else if (unformat (i, "sa_id %d", &sa_id))
13432         ;
13433       else if (unformat (i, "priority %d", &priority))
13434         ;
13435       else if (unformat (i, "protocol %d", &protocol))
13436         ;
13437       else if (unformat (i, "lport_start %d", &lport_start))
13438         ;
13439       else if (unformat (i, "lport_stop %d", &lport_stop))
13440         ;
13441       else if (unformat (i, "rport_start %d", &rport_start))
13442         ;
13443       else if (unformat (i, "rport_stop %d", &rport_stop))
13444         ;
13445       else if (unformat (i, "laddr_start %U",
13446                          unformat_vl_api_address, &laddr_start))
13447         ;
13448       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13449                          &laddr_stop))
13450         ;
13451       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13452                          &raddr_start))
13453         ;
13454       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13455                          &raddr_stop))
13456         ;
13457       else
13458         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13459         {
13460           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13461             {
13462               clib_warning ("unsupported action: 'resolve'");
13463               return -99;
13464             }
13465         }
13466       else
13467         {
13468           clib_warning ("parse error '%U'", format_unformat_error, i);
13469           return -99;
13470         }
13471
13472     }
13473
13474   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13475
13476   mp->is_add = is_add;
13477
13478   mp->entry.spd_id = ntohl (spd_id);
13479   mp->entry.priority = ntohl (priority);
13480   mp->entry.is_outbound = is_outbound;
13481
13482   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13483                sizeof (vl_api_address_t));
13484   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13485                sizeof (vl_api_address_t));
13486   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13487                sizeof (vl_api_address_t));
13488   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13489                sizeof (vl_api_address_t));
13490
13491   mp->entry.protocol = (u8) protocol;
13492   mp->entry.local_port_start = ntohs ((u16) lport_start);
13493   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13494   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13495   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13496   mp->entry.policy = (u8) policy;
13497   mp->entry.sa_id = ntohl (sa_id);
13498
13499   S (mp);
13500   W (ret);
13501   return ret;
13502 }
13503
13504 static int
13505 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13506 {
13507   unformat_input_t *i = vam->input;
13508   vl_api_ipsec_sad_entry_add_del_t *mp;
13509   u32 sad_id = 0, spi = 0;
13510   u8 *ck = 0, *ik = 0;
13511   u8 is_add = 1;
13512
13513   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13514   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13515   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13516   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13517   vl_api_address_t tun_src, tun_dst;
13518   int ret;
13519
13520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13521     {
13522       if (unformat (i, "del"))
13523         is_add = 0;
13524       else if (unformat (i, "sad_id %d", &sad_id))
13525         ;
13526       else if (unformat (i, "spi %d", &spi))
13527         ;
13528       else if (unformat (i, "esp"))
13529         protocol = IPSEC_API_PROTO_ESP;
13530       else
13531         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13532         {
13533           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13534           if (ADDRESS_IP6 == tun_src.af)
13535             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13536         }
13537       else
13538         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13539         {
13540           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13541           if (ADDRESS_IP6 == tun_src.af)
13542             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13543         }
13544       else
13545         if (unformat (i, "crypto_alg %U",
13546                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13547         ;
13548       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13549         ;
13550       else if (unformat (i, "integ_alg %U",
13551                          unformat_ipsec_api_integ_alg, &integ_alg))
13552         ;
13553       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13554         ;
13555       else
13556         {
13557           clib_warning ("parse error '%U'", format_unformat_error, i);
13558           return -99;
13559         }
13560
13561     }
13562
13563   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13564
13565   mp->is_add = is_add;
13566   mp->entry.sad_id = ntohl (sad_id);
13567   mp->entry.protocol = protocol;
13568   mp->entry.spi = ntohl (spi);
13569   mp->entry.flags = flags;
13570
13571   mp->entry.crypto_algorithm = crypto_alg;
13572   mp->entry.integrity_algorithm = integ_alg;
13573   mp->entry.crypto_key.length = vec_len (ck);
13574   mp->entry.integrity_key.length = vec_len (ik);
13575
13576   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13577     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13578
13579   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13580     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13581
13582   if (ck)
13583     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13584   if (ik)
13585     clib_memcpy (mp->entry.integrity_key.data, ik,
13586                  mp->entry.integrity_key.length);
13587
13588   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13589     {
13590       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13591                    sizeof (mp->entry.tunnel_src));
13592       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13593                    sizeof (mp->entry.tunnel_dst));
13594     }
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13603 {
13604   unformat_input_t *i = vam->input;
13605   vl_api_ipsec_tunnel_if_add_del_t *mp;
13606   u32 local_spi = 0, remote_spi = 0;
13607   u32 crypto_alg = 0, integ_alg = 0;
13608   u8 *lck = NULL, *rck = NULL;
13609   u8 *lik = NULL, *rik = NULL;
13610   vl_api_address_t local_ip = { 0 };
13611   vl_api_address_t remote_ip = { 0 };
13612   f64 before = 0;
13613   u8 is_add = 1;
13614   u8 esn = 0;
13615   u8 anti_replay = 0;
13616   u8 renumber = 0;
13617   u32 instance = ~0;
13618   u32 count = 1, jj;
13619   int ret = -1;
13620
13621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (i, "del"))
13624         is_add = 0;
13625       else if (unformat (i, "esn"))
13626         esn = 1;
13627       else if (unformat (i, "anti-replay"))
13628         anti_replay = 1;
13629       else if (unformat (i, "count %d", &count))
13630         ;
13631       else if (unformat (i, "local_spi %d", &local_spi))
13632         ;
13633       else if (unformat (i, "remote_spi %d", &remote_spi))
13634         ;
13635       else
13636         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13637         ;
13638       else
13639         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13640         ;
13641       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13642         ;
13643       else
13644         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13645         ;
13646       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13647         ;
13648       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13649         ;
13650       else
13651         if (unformat
13652             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13653         {
13654           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13655             {
13656               errmsg ("unsupported crypto-alg: '%U'\n",
13657                       format_ipsec_crypto_alg, crypto_alg);
13658               return -99;
13659             }
13660         }
13661       else
13662         if (unformat
13663             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13664         {
13665           if (integ_alg >= IPSEC_INTEG_N_ALG)
13666             {
13667               errmsg ("unsupported integ-alg: '%U'\n",
13668                       format_ipsec_integ_alg, integ_alg);
13669               return -99;
13670             }
13671         }
13672       else if (unformat (i, "instance %u", &instance))
13673         renumber = 1;
13674       else
13675         {
13676           errmsg ("parse error '%U'\n", format_unformat_error, i);
13677           return -99;
13678         }
13679     }
13680
13681   if (count > 1)
13682     {
13683       /* Turn on async mode */
13684       vam->async_mode = 1;
13685       vam->async_errors = 0;
13686       before = vat_time_now (vam);
13687     }
13688
13689   for (jj = 0; jj < count; jj++)
13690     {
13691       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13692
13693       mp->is_add = is_add;
13694       mp->esn = esn;
13695       mp->anti_replay = anti_replay;
13696
13697       if (jj > 0)
13698         increment_address (&remote_ip);
13699
13700       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13701       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13702
13703       mp->local_spi = htonl (local_spi + jj);
13704       mp->remote_spi = htonl (remote_spi + jj);
13705       mp->crypto_alg = (u8) crypto_alg;
13706
13707       mp->local_crypto_key_len = 0;
13708       if (lck)
13709         {
13710           mp->local_crypto_key_len = vec_len (lck);
13711           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13712             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13713           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13714         }
13715
13716       mp->remote_crypto_key_len = 0;
13717       if (rck)
13718         {
13719           mp->remote_crypto_key_len = vec_len (rck);
13720           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13721             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13722           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13723         }
13724
13725       mp->integ_alg = (u8) integ_alg;
13726
13727       mp->local_integ_key_len = 0;
13728       if (lik)
13729         {
13730           mp->local_integ_key_len = vec_len (lik);
13731           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13732             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13733           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13734         }
13735
13736       mp->remote_integ_key_len = 0;
13737       if (rik)
13738         {
13739           mp->remote_integ_key_len = vec_len (rik);
13740           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13741             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13742           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13743         }
13744
13745       if (renumber)
13746         {
13747           mp->renumber = renumber;
13748           mp->show_instance = ntohl (instance);
13749         }
13750       S (mp);
13751     }
13752
13753   /* When testing multiple add/del ops, use a control-ping to sync */
13754   if (count > 1)
13755     {
13756       vl_api_control_ping_t *mp_ping;
13757       f64 after;
13758       f64 timeout;
13759
13760       /* Shut off async mode */
13761       vam->async_mode = 0;
13762
13763       MPING (CONTROL_PING, mp_ping);
13764       S (mp_ping);
13765
13766       timeout = vat_time_now (vam) + 1.0;
13767       while (vat_time_now (vam) < timeout)
13768         if (vam->result_ready == 1)
13769           goto out;
13770       vam->retval = -99;
13771
13772     out:
13773       if (vam->retval == -99)
13774         errmsg ("timeout");
13775
13776       if (vam->async_errors > 0)
13777         {
13778           errmsg ("%d asynchronous errors", vam->async_errors);
13779           vam->retval = -98;
13780         }
13781       vam->async_errors = 0;
13782       after = vat_time_now (vam);
13783
13784       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13785       if (jj > 0)
13786         count = jj;
13787
13788       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13789              count, after - before, count / (after - before));
13790     }
13791   else
13792     {
13793       /* Wait for a reply... */
13794       W (ret);
13795       return ret;
13796     }
13797
13798   return ret;
13799 }
13800
13801 static void
13802 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805
13806   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13807          "crypto_key %U integ_alg %u integ_key %U flags %x "
13808          "tunnel_src_addr %U tunnel_dst_addr %U "
13809          "salt %u seq_outbound %lu last_seq_inbound %lu "
13810          "replay_window %lu\n",
13811          ntohl (mp->entry.sad_id),
13812          ntohl (mp->sw_if_index),
13813          ntohl (mp->entry.spi),
13814          ntohl (mp->entry.protocol),
13815          ntohl (mp->entry.crypto_algorithm),
13816          format_hex_bytes, mp->entry.crypto_key.data,
13817          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13818          format_hex_bytes, mp->entry.integrity_key.data,
13819          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13820          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13821          &mp->entry.tunnel_dst, ntohl (mp->salt),
13822          clib_net_to_host_u64 (mp->seq_outbound),
13823          clib_net_to_host_u64 (mp->last_seq_inbound),
13824          clib_net_to_host_u64 (mp->replay_window));
13825 }
13826
13827 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13828 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13829
13830 static void vl_api_ipsec_sa_details_t_handler_json
13831   (vl_api_ipsec_sa_details_t * mp)
13832 {
13833   vat_main_t *vam = &vat_main;
13834   vat_json_node_t *node = NULL;
13835   vl_api_ipsec_sad_flags_t flags;
13836
13837   if (VAT_JSON_ARRAY != vam->json_tree.type)
13838     {
13839       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13840       vat_json_init_array (&vam->json_tree);
13841     }
13842   node = vat_json_array_add (&vam->json_tree);
13843
13844   vat_json_init_object (node);
13845   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13847   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13848   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13849   vat_json_object_add_uint (node, "crypto_alg",
13850                             ntohl (mp->entry.crypto_algorithm));
13851   vat_json_object_add_uint (node, "integ_alg",
13852                             ntohl (mp->entry.integrity_algorithm));
13853   flags = ntohl (mp->entry.flags);
13854   vat_json_object_add_uint (node, "use_esn",
13855                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13856   vat_json_object_add_uint (node, "use_anti_replay",
13857                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13858   vat_json_object_add_uint (node, "is_tunnel",
13859                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13860   vat_json_object_add_uint (node, "is_tunnel_ip6",
13861                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13862   vat_json_object_add_uint (node, "udp_encap",
13863                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13864   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13865                              mp->entry.crypto_key.length);
13866   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13867                              mp->entry.integrity_key.length);
13868   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13869   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13870   vat_json_object_add_uint (node, "replay_window",
13871                             clib_net_to_host_u64 (mp->replay_window));
13872 }
13873
13874 static int
13875 api_ipsec_sa_dump (vat_main_t * vam)
13876 {
13877   unformat_input_t *i = vam->input;
13878   vl_api_ipsec_sa_dump_t *mp;
13879   vl_api_control_ping_t *mp_ping;
13880   u32 sa_id = ~0;
13881   int ret;
13882
13883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (i, "sa_id %d", &sa_id))
13886         ;
13887       else
13888         {
13889           clib_warning ("parse error '%U'", format_unformat_error, i);
13890           return -99;
13891         }
13892     }
13893
13894   M (IPSEC_SA_DUMP, mp);
13895
13896   mp->sa_id = ntohl (sa_id);
13897
13898   S (mp);
13899
13900   /* Use a control ping for synchronization */
13901   M (CONTROL_PING, mp_ping);
13902   S (mp_ping);
13903
13904   W (ret);
13905   return ret;
13906 }
13907
13908 static int
13909 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13910 {
13911   unformat_input_t *i = vam->input;
13912   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13913   u32 sw_if_index = ~0;
13914   u32 sa_id = ~0;
13915   u8 is_outbound = (u8) ~ 0;
13916   int ret;
13917
13918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13919     {
13920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13921         ;
13922       else if (unformat (i, "sa_id %d", &sa_id))
13923         ;
13924       else if (unformat (i, "outbound"))
13925         is_outbound = 1;
13926       else if (unformat (i, "inbound"))
13927         is_outbound = 0;
13928       else
13929         {
13930           clib_warning ("parse error '%U'", format_unformat_error, i);
13931           return -99;
13932         }
13933     }
13934
13935   if (sw_if_index == ~0)
13936     {
13937       errmsg ("interface must be specified");
13938       return -99;
13939     }
13940
13941   if (sa_id == ~0)
13942     {
13943       errmsg ("SA ID must be specified");
13944       return -99;
13945     }
13946
13947   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13948
13949   mp->sw_if_index = htonl (sw_if_index);
13950   mp->sa_id = htonl (sa_id);
13951   mp->is_outbound = is_outbound;
13952
13953   S (mp);
13954   W (ret);
13955
13956   return ret;
13957 }
13958
13959 static int
13960 api_get_first_msg_id (vat_main_t * vam)
13961 {
13962   vl_api_get_first_msg_id_t *mp;
13963   unformat_input_t *i = vam->input;
13964   u8 *name;
13965   u8 name_set = 0;
13966   int ret;
13967
13968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (unformat (i, "client %s", &name))
13971         name_set = 1;
13972       else
13973         break;
13974     }
13975
13976   if (name_set == 0)
13977     {
13978       errmsg ("missing client name");
13979       return -99;
13980     }
13981   vec_add1 (name, 0);
13982
13983   if (vec_len (name) > 63)
13984     {
13985       errmsg ("client name too long");
13986       return -99;
13987     }
13988
13989   M (GET_FIRST_MSG_ID, mp);
13990   clib_memcpy (mp->name, name, vec_len (name));
13991   S (mp);
13992   W (ret);
13993   return ret;
13994 }
13995
13996 static int
13997 api_cop_interface_enable_disable (vat_main_t * vam)
13998 {
13999   unformat_input_t *line_input = vam->input;
14000   vl_api_cop_interface_enable_disable_t *mp;
14001   u32 sw_if_index = ~0;
14002   u8 enable_disable = 1;
14003   int ret;
14004
14005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (line_input, "disable"))
14008         enable_disable = 0;
14009       if (unformat (line_input, "enable"))
14010         enable_disable = 1;
14011       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14012                          vam, &sw_if_index))
14013         ;
14014       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14015         ;
14016       else
14017         break;
14018     }
14019
14020   if (sw_if_index == ~0)
14021     {
14022       errmsg ("missing interface name or sw_if_index");
14023       return -99;
14024     }
14025
14026   /* Construct the API message */
14027   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14028   mp->sw_if_index = ntohl (sw_if_index);
14029   mp->enable_disable = enable_disable;
14030
14031   /* send it... */
14032   S (mp);
14033   /* Wait for the reply */
14034   W (ret);
14035   return ret;
14036 }
14037
14038 static int
14039 api_cop_whitelist_enable_disable (vat_main_t * vam)
14040 {
14041   unformat_input_t *line_input = vam->input;
14042   vl_api_cop_whitelist_enable_disable_t *mp;
14043   u32 sw_if_index = ~0;
14044   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14045   u32 fib_id = 0;
14046   int ret;
14047
14048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (line_input, "ip4"))
14051         ip4 = 1;
14052       else if (unformat (line_input, "ip6"))
14053         ip6 = 1;
14054       else if (unformat (line_input, "default"))
14055         default_cop = 1;
14056       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14057                          vam, &sw_if_index))
14058         ;
14059       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14060         ;
14061       else if (unformat (line_input, "fib-id %d", &fib_id))
14062         ;
14063       else
14064         break;
14065     }
14066
14067   if (sw_if_index == ~0)
14068     {
14069       errmsg ("missing interface name or sw_if_index");
14070       return -99;
14071     }
14072
14073   /* Construct the API message */
14074   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14075   mp->sw_if_index = ntohl (sw_if_index);
14076   mp->fib_id = ntohl (fib_id);
14077   mp->ip4 = ip4;
14078   mp->ip6 = ip6;
14079   mp->default_cop = default_cop;
14080
14081   /* send it... */
14082   S (mp);
14083   /* Wait for the reply */
14084   W (ret);
14085   return ret;
14086 }
14087
14088 static int
14089 api_get_node_graph (vat_main_t * vam)
14090 {
14091   vl_api_get_node_graph_t *mp;
14092   int ret;
14093
14094   M (GET_NODE_GRAPH, mp);
14095
14096   /* send it... */
14097   S (mp);
14098   /* Wait for the reply */
14099   W (ret);
14100   return ret;
14101 }
14102
14103 /* *INDENT-OFF* */
14104 /** Used for parsing LISP eids */
14105 typedef CLIB_PACKED(struct{
14106   u8 addr[16];   /**< eid address */
14107   u32 len;       /**< prefix length if IP */
14108   u8 type;      /**< type of eid */
14109 }) lisp_eid_vat_t;
14110 /* *INDENT-ON* */
14111
14112 static uword
14113 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14114 {
14115   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14116
14117   clib_memset (a, 0, sizeof (a[0]));
14118
14119   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14120     {
14121       a->type = 0;              /* ipv4 type */
14122     }
14123   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14124     {
14125       a->type = 1;              /* ipv6 type */
14126     }
14127   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14128     {
14129       a->type = 2;              /* mac type */
14130     }
14131   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14132     {
14133       a->type = 3;              /* NSH type */
14134       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14135       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14136     }
14137   else
14138     {
14139       return 0;
14140     }
14141
14142   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14143     {
14144       return 0;
14145     }
14146
14147   return 1;
14148 }
14149
14150 static int
14151 lisp_eid_size_vat (u8 type)
14152 {
14153   switch (type)
14154     {
14155     case 0:
14156       return 4;
14157     case 1:
14158       return 16;
14159     case 2:
14160       return 6;
14161     case 3:
14162       return 5;
14163     }
14164   return 0;
14165 }
14166
14167 static void
14168 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14169 {
14170   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14171 }
14172
14173 static int
14174 api_one_add_del_locator_set (vat_main_t * vam)
14175 {
14176   unformat_input_t *input = vam->input;
14177   vl_api_one_add_del_locator_set_t *mp;
14178   u8 is_add = 1;
14179   u8 *locator_set_name = NULL;
14180   u8 locator_set_name_set = 0;
14181   vl_api_local_locator_t locator, *locators = 0;
14182   u32 sw_if_index, priority, weight;
14183   u32 data_len = 0;
14184
14185   int ret;
14186   /* Parse args required to build the message */
14187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (input, "del"))
14190         {
14191           is_add = 0;
14192         }
14193       else if (unformat (input, "locator-set %s", &locator_set_name))
14194         {
14195           locator_set_name_set = 1;
14196         }
14197       else if (unformat (input, "sw_if_index %u p %u w %u",
14198                          &sw_if_index, &priority, &weight))
14199         {
14200           locator.sw_if_index = htonl (sw_if_index);
14201           locator.priority = priority;
14202           locator.weight = weight;
14203           vec_add1 (locators, locator);
14204         }
14205       else
14206         if (unformat
14207             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14208              &sw_if_index, &priority, &weight))
14209         {
14210           locator.sw_if_index = htonl (sw_if_index);
14211           locator.priority = priority;
14212           locator.weight = weight;
14213           vec_add1 (locators, locator);
14214         }
14215       else
14216         break;
14217     }
14218
14219   if (locator_set_name_set == 0)
14220     {
14221       errmsg ("missing locator-set name");
14222       vec_free (locators);
14223       return -99;
14224     }
14225
14226   if (vec_len (locator_set_name) > 64)
14227     {
14228       errmsg ("locator-set name too long");
14229       vec_free (locator_set_name);
14230       vec_free (locators);
14231       return -99;
14232     }
14233   vec_add1 (locator_set_name, 0);
14234
14235   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14236
14237   /* Construct the API message */
14238   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14239
14240   mp->is_add = is_add;
14241   clib_memcpy (mp->locator_set_name, locator_set_name,
14242                vec_len (locator_set_name));
14243   vec_free (locator_set_name);
14244
14245   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14246   if (locators)
14247     clib_memcpy (mp->locators, locators, data_len);
14248   vec_free (locators);
14249
14250   /* send it... */
14251   S (mp);
14252
14253   /* Wait for a reply... */
14254   W (ret);
14255   return ret;
14256 }
14257
14258 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14259
14260 static int
14261 api_one_add_del_locator (vat_main_t * vam)
14262 {
14263   unformat_input_t *input = vam->input;
14264   vl_api_one_add_del_locator_t *mp;
14265   u32 tmp_if_index = ~0;
14266   u32 sw_if_index = ~0;
14267   u8 sw_if_index_set = 0;
14268   u8 sw_if_index_if_name_set = 0;
14269   u32 priority = ~0;
14270   u8 priority_set = 0;
14271   u32 weight = ~0;
14272   u8 weight_set = 0;
14273   u8 is_add = 1;
14274   u8 *locator_set_name = NULL;
14275   u8 locator_set_name_set = 0;
14276   int ret;
14277
14278   /* Parse args required to build the message */
14279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14280     {
14281       if (unformat (input, "del"))
14282         {
14283           is_add = 0;
14284         }
14285       else if (unformat (input, "locator-set %s", &locator_set_name))
14286         {
14287           locator_set_name_set = 1;
14288         }
14289       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14290                          &tmp_if_index))
14291         {
14292           sw_if_index_if_name_set = 1;
14293           sw_if_index = tmp_if_index;
14294         }
14295       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14296         {
14297           sw_if_index_set = 1;
14298           sw_if_index = tmp_if_index;
14299         }
14300       else if (unformat (input, "p %d", &priority))
14301         {
14302           priority_set = 1;
14303         }
14304       else if (unformat (input, "w %d", &weight))
14305         {
14306           weight_set = 1;
14307         }
14308       else
14309         break;
14310     }
14311
14312   if (locator_set_name_set == 0)
14313     {
14314       errmsg ("missing locator-set name");
14315       return -99;
14316     }
14317
14318   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14319     {
14320       errmsg ("missing sw_if_index");
14321       vec_free (locator_set_name);
14322       return -99;
14323     }
14324
14325   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14326     {
14327       errmsg ("cannot use both params interface name and sw_if_index");
14328       vec_free (locator_set_name);
14329       return -99;
14330     }
14331
14332   if (priority_set == 0)
14333     {
14334       errmsg ("missing locator-set priority");
14335       vec_free (locator_set_name);
14336       return -99;
14337     }
14338
14339   if (weight_set == 0)
14340     {
14341       errmsg ("missing locator-set weight");
14342       vec_free (locator_set_name);
14343       return -99;
14344     }
14345
14346   if (vec_len (locator_set_name) > 64)
14347     {
14348       errmsg ("locator-set name too long");
14349       vec_free (locator_set_name);
14350       return -99;
14351     }
14352   vec_add1 (locator_set_name, 0);
14353
14354   /* Construct the API message */
14355   M (ONE_ADD_DEL_LOCATOR, mp);
14356
14357   mp->is_add = is_add;
14358   mp->sw_if_index = ntohl (sw_if_index);
14359   mp->priority = priority;
14360   mp->weight = weight;
14361   clib_memcpy (mp->locator_set_name, locator_set_name,
14362                vec_len (locator_set_name));
14363   vec_free (locator_set_name);
14364
14365   /* send it... */
14366   S (mp);
14367
14368   /* Wait for a reply... */
14369   W (ret);
14370   return ret;
14371 }
14372
14373 #define api_lisp_add_del_locator api_one_add_del_locator
14374
14375 uword
14376 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14377 {
14378   u32 *key_id = va_arg (*args, u32 *);
14379   u8 *s = 0;
14380
14381   if (unformat (input, "%s", &s))
14382     {
14383       if (!strcmp ((char *) s, "sha1"))
14384         key_id[0] = HMAC_SHA_1_96;
14385       else if (!strcmp ((char *) s, "sha256"))
14386         key_id[0] = HMAC_SHA_256_128;
14387       else
14388         {
14389           clib_warning ("invalid key_id: '%s'", s);
14390           key_id[0] = HMAC_NO_KEY;
14391         }
14392     }
14393   else
14394     return 0;
14395
14396   vec_free (s);
14397   return 1;
14398 }
14399
14400 static int
14401 api_one_add_del_local_eid (vat_main_t * vam)
14402 {
14403   unformat_input_t *input = vam->input;
14404   vl_api_one_add_del_local_eid_t *mp;
14405   u8 is_add = 1;
14406   u8 eid_set = 0;
14407   lisp_eid_vat_t _eid, *eid = &_eid;
14408   u8 *locator_set_name = 0;
14409   u8 locator_set_name_set = 0;
14410   u32 vni = 0;
14411   u16 key_id = 0;
14412   u8 *key = 0;
14413   int ret;
14414
14415   /* Parse args required to build the message */
14416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14417     {
14418       if (unformat (input, "del"))
14419         {
14420           is_add = 0;
14421         }
14422       else if (unformat (input, "vni %d", &vni))
14423         {
14424           ;
14425         }
14426       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14427         {
14428           eid_set = 1;
14429         }
14430       else if (unformat (input, "locator-set %s", &locator_set_name))
14431         {
14432           locator_set_name_set = 1;
14433         }
14434       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14435         ;
14436       else if (unformat (input, "secret-key %_%v%_", &key))
14437         ;
14438       else
14439         break;
14440     }
14441
14442   if (locator_set_name_set == 0)
14443     {
14444       errmsg ("missing locator-set name");
14445       return -99;
14446     }
14447
14448   if (0 == eid_set)
14449     {
14450       errmsg ("EID address not set!");
14451       vec_free (locator_set_name);
14452       return -99;
14453     }
14454
14455   if (key && (0 == key_id))
14456     {
14457       errmsg ("invalid key_id!");
14458       return -99;
14459     }
14460
14461   if (vec_len (key) > 64)
14462     {
14463       errmsg ("key too long");
14464       vec_free (key);
14465       return -99;
14466     }
14467
14468   if (vec_len (locator_set_name) > 64)
14469     {
14470       errmsg ("locator-set name too long");
14471       vec_free (locator_set_name);
14472       return -99;
14473     }
14474   vec_add1 (locator_set_name, 0);
14475
14476   /* Construct the API message */
14477   M (ONE_ADD_DEL_LOCAL_EID, mp);
14478
14479   mp->is_add = is_add;
14480   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14481   mp->eid_type = eid->type;
14482   mp->prefix_len = eid->len;
14483   mp->vni = clib_host_to_net_u32 (vni);
14484   mp->key_id = clib_host_to_net_u16 (key_id);
14485   clib_memcpy (mp->locator_set_name, locator_set_name,
14486                vec_len (locator_set_name));
14487   clib_memcpy (mp->key, key, vec_len (key));
14488
14489   vec_free (locator_set_name);
14490   vec_free (key);
14491
14492   /* send it... */
14493   S (mp);
14494
14495   /* Wait for a reply... */
14496   W (ret);
14497   return ret;
14498 }
14499
14500 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14501
14502 static int
14503 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14504 {
14505   u32 dp_table = 0, vni = 0;;
14506   unformat_input_t *input = vam->input;
14507   vl_api_gpe_add_del_fwd_entry_t *mp;
14508   u8 is_add = 1;
14509   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14510   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14511   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14512   u32 action = ~0, w;
14513   ip4_address_t rmt_rloc4, lcl_rloc4;
14514   ip6_address_t rmt_rloc6, lcl_rloc6;
14515   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14516   int ret;
14517
14518   clib_memset (&rloc, 0, sizeof (rloc));
14519
14520   /* Parse args required to build the message */
14521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14522     {
14523       if (unformat (input, "del"))
14524         is_add = 0;
14525       else if (unformat (input, "add"))
14526         is_add = 1;
14527       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14528         {
14529           rmt_eid_set = 1;
14530         }
14531       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14532         {
14533           lcl_eid_set = 1;
14534         }
14535       else if (unformat (input, "vrf %d", &dp_table))
14536         ;
14537       else if (unformat (input, "bd %d", &dp_table))
14538         ;
14539       else if (unformat (input, "vni %d", &vni))
14540         ;
14541       else if (unformat (input, "w %d", &w))
14542         {
14543           if (!curr_rloc)
14544             {
14545               errmsg ("No RLOC configured for setting priority/weight!");
14546               return -99;
14547             }
14548           curr_rloc->weight = w;
14549         }
14550       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14551                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14552         {
14553           rloc.is_ip4 = 1;
14554
14555           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14556           rloc.weight = 0;
14557           vec_add1 (lcl_locs, rloc);
14558
14559           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14560           vec_add1 (rmt_locs, rloc);
14561           /* weight saved in rmt loc */
14562           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14563         }
14564       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14565                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14566         {
14567           rloc.is_ip4 = 0;
14568           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14569           rloc.weight = 0;
14570           vec_add1 (lcl_locs, rloc);
14571
14572           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14573           vec_add1 (rmt_locs, rloc);
14574           /* weight saved in rmt loc */
14575           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14576         }
14577       else if (unformat (input, "action %d", &action))
14578         {
14579           ;
14580         }
14581       else
14582         {
14583           clib_warning ("parse error '%U'", format_unformat_error, input);
14584           return -99;
14585         }
14586     }
14587
14588   if (!rmt_eid_set)
14589     {
14590       errmsg ("remote eid addresses not set");
14591       return -99;
14592     }
14593
14594   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14595     {
14596       errmsg ("eid types don't match");
14597       return -99;
14598     }
14599
14600   if (0 == rmt_locs && (u32) ~ 0 == action)
14601     {
14602       errmsg ("action not set for negative mapping");
14603       return -99;
14604     }
14605
14606   /* Construct the API message */
14607   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14608       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14609
14610   mp->is_add = is_add;
14611   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14612   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14613   mp->eid_type = rmt_eid->type;
14614   mp->dp_table = clib_host_to_net_u32 (dp_table);
14615   mp->vni = clib_host_to_net_u32 (vni);
14616   mp->rmt_len = rmt_eid->len;
14617   mp->lcl_len = lcl_eid->len;
14618   mp->action = action;
14619
14620   if (0 != rmt_locs && 0 != lcl_locs)
14621     {
14622       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14623       clib_memcpy (mp->locs, lcl_locs,
14624                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14625
14626       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14627       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14628                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14629     }
14630   vec_free (lcl_locs);
14631   vec_free (rmt_locs);
14632
14633   /* send it... */
14634   S (mp);
14635
14636   /* Wait for a reply... */
14637   W (ret);
14638   return ret;
14639 }
14640
14641 static int
14642 api_one_add_del_map_server (vat_main_t * vam)
14643 {
14644   unformat_input_t *input = vam->input;
14645   vl_api_one_add_del_map_server_t *mp;
14646   u8 is_add = 1;
14647   u8 ipv4_set = 0;
14648   u8 ipv6_set = 0;
14649   ip4_address_t ipv4;
14650   ip6_address_t ipv6;
14651   int ret;
14652
14653   /* Parse args required to build the message */
14654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14655     {
14656       if (unformat (input, "del"))
14657         {
14658           is_add = 0;
14659         }
14660       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14661         {
14662           ipv4_set = 1;
14663         }
14664       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14665         {
14666           ipv6_set = 1;
14667         }
14668       else
14669         break;
14670     }
14671
14672   if (ipv4_set && ipv6_set)
14673     {
14674       errmsg ("both eid v4 and v6 addresses set");
14675       return -99;
14676     }
14677
14678   if (!ipv4_set && !ipv6_set)
14679     {
14680       errmsg ("eid addresses not set");
14681       return -99;
14682     }
14683
14684   /* Construct the API message */
14685   M (ONE_ADD_DEL_MAP_SERVER, mp);
14686
14687   mp->is_add = is_add;
14688   if (ipv6_set)
14689     {
14690       mp->is_ipv6 = 1;
14691       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14692     }
14693   else
14694     {
14695       mp->is_ipv6 = 0;
14696       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14697     }
14698
14699   /* send it... */
14700   S (mp);
14701
14702   /* Wait for a reply... */
14703   W (ret);
14704   return ret;
14705 }
14706
14707 #define api_lisp_add_del_map_server api_one_add_del_map_server
14708
14709 static int
14710 api_one_add_del_map_resolver (vat_main_t * vam)
14711 {
14712   unformat_input_t *input = vam->input;
14713   vl_api_one_add_del_map_resolver_t *mp;
14714   u8 is_add = 1;
14715   u8 ipv4_set = 0;
14716   u8 ipv6_set = 0;
14717   ip4_address_t ipv4;
14718   ip6_address_t ipv6;
14719   int ret;
14720
14721   /* Parse args required to build the message */
14722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14723     {
14724       if (unformat (input, "del"))
14725         {
14726           is_add = 0;
14727         }
14728       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14729         {
14730           ipv4_set = 1;
14731         }
14732       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14733         {
14734           ipv6_set = 1;
14735         }
14736       else
14737         break;
14738     }
14739
14740   if (ipv4_set && ipv6_set)
14741     {
14742       errmsg ("both eid v4 and v6 addresses set");
14743       return -99;
14744     }
14745
14746   if (!ipv4_set && !ipv6_set)
14747     {
14748       errmsg ("eid addresses not set");
14749       return -99;
14750     }
14751
14752   /* Construct the API message */
14753   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14754
14755   mp->is_add = is_add;
14756   if (ipv6_set)
14757     {
14758       mp->is_ipv6 = 1;
14759       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14760     }
14761   else
14762     {
14763       mp->is_ipv6 = 0;
14764       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14765     }
14766
14767   /* send it... */
14768   S (mp);
14769
14770   /* Wait for a reply... */
14771   W (ret);
14772   return ret;
14773 }
14774
14775 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14776
14777 static int
14778 api_lisp_gpe_enable_disable (vat_main_t * vam)
14779 {
14780   unformat_input_t *input = vam->input;
14781   vl_api_gpe_enable_disable_t *mp;
14782   u8 is_set = 0;
14783   u8 is_en = 1;
14784   int ret;
14785
14786   /* Parse args required to build the message */
14787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14788     {
14789       if (unformat (input, "enable"))
14790         {
14791           is_set = 1;
14792           is_en = 1;
14793         }
14794       else if (unformat (input, "disable"))
14795         {
14796           is_set = 1;
14797           is_en = 0;
14798         }
14799       else
14800         break;
14801     }
14802
14803   if (is_set == 0)
14804     {
14805       errmsg ("Value not set");
14806       return -99;
14807     }
14808
14809   /* Construct the API message */
14810   M (GPE_ENABLE_DISABLE, mp);
14811
14812   mp->is_en = is_en;
14813
14814   /* send it... */
14815   S (mp);
14816
14817   /* Wait for a reply... */
14818   W (ret);
14819   return ret;
14820 }
14821
14822 static int
14823 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14824 {
14825   unformat_input_t *input = vam->input;
14826   vl_api_one_rloc_probe_enable_disable_t *mp;
14827   u8 is_set = 0;
14828   u8 is_en = 0;
14829   int ret;
14830
14831   /* Parse args required to build the message */
14832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14833     {
14834       if (unformat (input, "enable"))
14835         {
14836           is_set = 1;
14837           is_en = 1;
14838         }
14839       else if (unformat (input, "disable"))
14840         is_set = 1;
14841       else
14842         break;
14843     }
14844
14845   if (!is_set)
14846     {
14847       errmsg ("Value not set");
14848       return -99;
14849     }
14850
14851   /* Construct the API message */
14852   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14853
14854   mp->is_enabled = is_en;
14855
14856   /* send it... */
14857   S (mp);
14858
14859   /* Wait for a reply... */
14860   W (ret);
14861   return ret;
14862 }
14863
14864 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14865
14866 static int
14867 api_one_map_register_enable_disable (vat_main_t * vam)
14868 {
14869   unformat_input_t *input = vam->input;
14870   vl_api_one_map_register_enable_disable_t *mp;
14871   u8 is_set = 0;
14872   u8 is_en = 0;
14873   int ret;
14874
14875   /* Parse args required to build the message */
14876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14877     {
14878       if (unformat (input, "enable"))
14879         {
14880           is_set = 1;
14881           is_en = 1;
14882         }
14883       else if (unformat (input, "disable"))
14884         is_set = 1;
14885       else
14886         break;
14887     }
14888
14889   if (!is_set)
14890     {
14891       errmsg ("Value not set");
14892       return -99;
14893     }
14894
14895   /* Construct the API message */
14896   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14897
14898   mp->is_enabled = is_en;
14899
14900   /* send it... */
14901   S (mp);
14902
14903   /* Wait for a reply... */
14904   W (ret);
14905   return ret;
14906 }
14907
14908 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14909
14910 static int
14911 api_one_enable_disable (vat_main_t * vam)
14912 {
14913   unformat_input_t *input = vam->input;
14914   vl_api_one_enable_disable_t *mp;
14915   u8 is_set = 0;
14916   u8 is_en = 0;
14917   int ret;
14918
14919   /* Parse args required to build the message */
14920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14921     {
14922       if (unformat (input, "enable"))
14923         {
14924           is_set = 1;
14925           is_en = 1;
14926         }
14927       else if (unformat (input, "disable"))
14928         {
14929           is_set = 1;
14930         }
14931       else
14932         break;
14933     }
14934
14935   if (!is_set)
14936     {
14937       errmsg ("Value not set");
14938       return -99;
14939     }
14940
14941   /* Construct the API message */
14942   M (ONE_ENABLE_DISABLE, mp);
14943
14944   mp->is_en = is_en;
14945
14946   /* send it... */
14947   S (mp);
14948
14949   /* Wait for a reply... */
14950   W (ret);
14951   return ret;
14952 }
14953
14954 #define api_lisp_enable_disable api_one_enable_disable
14955
14956 static int
14957 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14958 {
14959   unformat_input_t *input = vam->input;
14960   vl_api_one_enable_disable_xtr_mode_t *mp;
14961   u8 is_set = 0;
14962   u8 is_en = 0;
14963   int ret;
14964
14965   /* Parse args required to build the message */
14966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14967     {
14968       if (unformat (input, "enable"))
14969         {
14970           is_set = 1;
14971           is_en = 1;
14972         }
14973       else if (unformat (input, "disable"))
14974         {
14975           is_set = 1;
14976         }
14977       else
14978         break;
14979     }
14980
14981   if (!is_set)
14982     {
14983       errmsg ("Value not set");
14984       return -99;
14985     }
14986
14987   /* Construct the API message */
14988   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14989
14990   mp->is_en = is_en;
14991
14992   /* send it... */
14993   S (mp);
14994
14995   /* Wait for a reply... */
14996   W (ret);
14997   return ret;
14998 }
14999
15000 static int
15001 api_one_show_xtr_mode (vat_main_t * vam)
15002 {
15003   vl_api_one_show_xtr_mode_t *mp;
15004   int ret;
15005
15006   /* Construct the API message */
15007   M (ONE_SHOW_XTR_MODE, mp);
15008
15009   /* send it... */
15010   S (mp);
15011
15012   /* Wait for a reply... */
15013   W (ret);
15014   return ret;
15015 }
15016
15017 static int
15018 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15019 {
15020   unformat_input_t *input = vam->input;
15021   vl_api_one_enable_disable_pitr_mode_t *mp;
15022   u8 is_set = 0;
15023   u8 is_en = 0;
15024   int ret;
15025
15026   /* Parse args required to build the message */
15027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15028     {
15029       if (unformat (input, "enable"))
15030         {
15031           is_set = 1;
15032           is_en = 1;
15033         }
15034       else if (unformat (input, "disable"))
15035         {
15036           is_set = 1;
15037         }
15038       else
15039         break;
15040     }
15041
15042   if (!is_set)
15043     {
15044       errmsg ("Value not set");
15045       return -99;
15046     }
15047
15048   /* Construct the API message */
15049   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15050
15051   mp->is_en = is_en;
15052
15053   /* send it... */
15054   S (mp);
15055
15056   /* Wait for a reply... */
15057   W (ret);
15058   return ret;
15059 }
15060
15061 static int
15062 api_one_show_pitr_mode (vat_main_t * vam)
15063 {
15064   vl_api_one_show_pitr_mode_t *mp;
15065   int ret;
15066
15067   /* Construct the API message */
15068   M (ONE_SHOW_PITR_MODE, mp);
15069
15070   /* send it... */
15071   S (mp);
15072
15073   /* Wait for a reply... */
15074   W (ret);
15075   return ret;
15076 }
15077
15078 static int
15079 api_one_enable_disable_petr_mode (vat_main_t * vam)
15080 {
15081   unformat_input_t *input = vam->input;
15082   vl_api_one_enable_disable_petr_mode_t *mp;
15083   u8 is_set = 0;
15084   u8 is_en = 0;
15085   int ret;
15086
15087   /* Parse args required to build the message */
15088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15089     {
15090       if (unformat (input, "enable"))
15091         {
15092           is_set = 1;
15093           is_en = 1;
15094         }
15095       else if (unformat (input, "disable"))
15096         {
15097           is_set = 1;
15098         }
15099       else
15100         break;
15101     }
15102
15103   if (!is_set)
15104     {
15105       errmsg ("Value not set");
15106       return -99;
15107     }
15108
15109   /* Construct the API message */
15110   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15111
15112   mp->is_en = is_en;
15113
15114   /* send it... */
15115   S (mp);
15116
15117   /* Wait for a reply... */
15118   W (ret);
15119   return ret;
15120 }
15121
15122 static int
15123 api_one_show_petr_mode (vat_main_t * vam)
15124 {
15125   vl_api_one_show_petr_mode_t *mp;
15126   int ret;
15127
15128   /* Construct the API message */
15129   M (ONE_SHOW_PETR_MODE, mp);
15130
15131   /* send it... */
15132   S (mp);
15133
15134   /* Wait for a reply... */
15135   W (ret);
15136   return ret;
15137 }
15138
15139 static int
15140 api_show_one_map_register_state (vat_main_t * vam)
15141 {
15142   vl_api_show_one_map_register_state_t *mp;
15143   int ret;
15144
15145   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15146
15147   /* send */
15148   S (mp);
15149
15150   /* wait for reply */
15151   W (ret);
15152   return ret;
15153 }
15154
15155 #define api_show_lisp_map_register_state api_show_one_map_register_state
15156
15157 static int
15158 api_show_one_rloc_probe_state (vat_main_t * vam)
15159 {
15160   vl_api_show_one_rloc_probe_state_t *mp;
15161   int ret;
15162
15163   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15164
15165   /* send */
15166   S (mp);
15167
15168   /* wait for reply */
15169   W (ret);
15170   return ret;
15171 }
15172
15173 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15174
15175 static int
15176 api_one_add_del_ndp_entry (vat_main_t * vam)
15177 {
15178   vl_api_one_add_del_ndp_entry_t *mp;
15179   unformat_input_t *input = vam->input;
15180   u8 is_add = 1;
15181   u8 mac_set = 0;
15182   u8 bd_set = 0;
15183   u8 ip_set = 0;
15184   u8 mac[6] = { 0, };
15185   u8 ip6[16] = { 0, };
15186   u32 bd = ~0;
15187   int ret;
15188
15189   /* Parse args required to build the message */
15190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15191     {
15192       if (unformat (input, "del"))
15193         is_add = 0;
15194       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15195         mac_set = 1;
15196       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15197         ip_set = 1;
15198       else if (unformat (input, "bd %d", &bd))
15199         bd_set = 1;
15200       else
15201         {
15202           errmsg ("parse error '%U'", format_unformat_error, input);
15203           return -99;
15204         }
15205     }
15206
15207   if (!bd_set || !ip_set || (!mac_set && is_add))
15208     {
15209       errmsg ("Missing BD, IP or MAC!");
15210       return -99;
15211     }
15212
15213   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15214   mp->is_add = is_add;
15215   clib_memcpy (mp->mac, mac, 6);
15216   mp->bd = clib_host_to_net_u32 (bd);
15217   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15218
15219   /* send */
15220   S (mp);
15221
15222   /* wait for reply */
15223   W (ret);
15224   return ret;
15225 }
15226
15227 static int
15228 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15229 {
15230   vl_api_one_add_del_l2_arp_entry_t *mp;
15231   unformat_input_t *input = vam->input;
15232   u8 is_add = 1;
15233   u8 mac_set = 0;
15234   u8 bd_set = 0;
15235   u8 ip_set = 0;
15236   u8 mac[6] = { 0, };
15237   u32 ip4 = 0, bd = ~0;
15238   int ret;
15239
15240   /* Parse args required to build the message */
15241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15242     {
15243       if (unformat (input, "del"))
15244         is_add = 0;
15245       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15246         mac_set = 1;
15247       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15248         ip_set = 1;
15249       else if (unformat (input, "bd %d", &bd))
15250         bd_set = 1;
15251       else
15252         {
15253           errmsg ("parse error '%U'", format_unformat_error, input);
15254           return -99;
15255         }
15256     }
15257
15258   if (!bd_set || !ip_set || (!mac_set && is_add))
15259     {
15260       errmsg ("Missing BD, IP or MAC!");
15261       return -99;
15262     }
15263
15264   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15265   mp->is_add = is_add;
15266   clib_memcpy (mp->mac, mac, 6);
15267   mp->bd = clib_host_to_net_u32 (bd);
15268   mp->ip4 = ip4;
15269
15270   /* send */
15271   S (mp);
15272
15273   /* wait for reply */
15274   W (ret);
15275   return ret;
15276 }
15277
15278 static int
15279 api_one_ndp_bd_get (vat_main_t * vam)
15280 {
15281   vl_api_one_ndp_bd_get_t *mp;
15282   int ret;
15283
15284   M (ONE_NDP_BD_GET, mp);
15285
15286   /* send */
15287   S (mp);
15288
15289   /* wait for reply */
15290   W (ret);
15291   return ret;
15292 }
15293
15294 static int
15295 api_one_ndp_entries_get (vat_main_t * vam)
15296 {
15297   vl_api_one_ndp_entries_get_t *mp;
15298   unformat_input_t *input = vam->input;
15299   u8 bd_set = 0;
15300   u32 bd = ~0;
15301   int ret;
15302
15303   /* Parse args required to build the message */
15304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15305     {
15306       if (unformat (input, "bd %d", &bd))
15307         bd_set = 1;
15308       else
15309         {
15310           errmsg ("parse error '%U'", format_unformat_error, input);
15311           return -99;
15312         }
15313     }
15314
15315   if (!bd_set)
15316     {
15317       errmsg ("Expected bridge domain!");
15318       return -99;
15319     }
15320
15321   M (ONE_NDP_ENTRIES_GET, mp);
15322   mp->bd = clib_host_to_net_u32 (bd);
15323
15324   /* send */
15325   S (mp);
15326
15327   /* wait for reply */
15328   W (ret);
15329   return ret;
15330 }
15331
15332 static int
15333 api_one_l2_arp_bd_get (vat_main_t * vam)
15334 {
15335   vl_api_one_l2_arp_bd_get_t *mp;
15336   int ret;
15337
15338   M (ONE_L2_ARP_BD_GET, mp);
15339
15340   /* send */
15341   S (mp);
15342
15343   /* wait for reply */
15344   W (ret);
15345   return ret;
15346 }
15347
15348 static int
15349 api_one_l2_arp_entries_get (vat_main_t * vam)
15350 {
15351   vl_api_one_l2_arp_entries_get_t *mp;
15352   unformat_input_t *input = vam->input;
15353   u8 bd_set = 0;
15354   u32 bd = ~0;
15355   int ret;
15356
15357   /* Parse args required to build the message */
15358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15359     {
15360       if (unformat (input, "bd %d", &bd))
15361         bd_set = 1;
15362       else
15363         {
15364           errmsg ("parse error '%U'", format_unformat_error, input);
15365           return -99;
15366         }
15367     }
15368
15369   if (!bd_set)
15370     {
15371       errmsg ("Expected bridge domain!");
15372       return -99;
15373     }
15374
15375   M (ONE_L2_ARP_ENTRIES_GET, mp);
15376   mp->bd = clib_host_to_net_u32 (bd);
15377
15378   /* send */
15379   S (mp);
15380
15381   /* wait for reply */
15382   W (ret);
15383   return ret;
15384 }
15385
15386 static int
15387 api_one_stats_enable_disable (vat_main_t * vam)
15388 {
15389   vl_api_one_stats_enable_disable_t *mp;
15390   unformat_input_t *input = vam->input;
15391   u8 is_set = 0;
15392   u8 is_en = 0;
15393   int ret;
15394
15395   /* Parse args required to build the message */
15396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15397     {
15398       if (unformat (input, "enable"))
15399         {
15400           is_set = 1;
15401           is_en = 1;
15402         }
15403       else if (unformat (input, "disable"))
15404         {
15405           is_set = 1;
15406         }
15407       else
15408         break;
15409     }
15410
15411   if (!is_set)
15412     {
15413       errmsg ("Value not set");
15414       return -99;
15415     }
15416
15417   M (ONE_STATS_ENABLE_DISABLE, mp);
15418   mp->is_en = is_en;
15419
15420   /* send */
15421   S (mp);
15422
15423   /* wait for reply */
15424   W (ret);
15425   return ret;
15426 }
15427
15428 static int
15429 api_show_one_stats_enable_disable (vat_main_t * vam)
15430 {
15431   vl_api_show_one_stats_enable_disable_t *mp;
15432   int ret;
15433
15434   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15435
15436   /* send */
15437   S (mp);
15438
15439   /* wait for reply */
15440   W (ret);
15441   return ret;
15442 }
15443
15444 static int
15445 api_show_one_map_request_mode (vat_main_t * vam)
15446 {
15447   vl_api_show_one_map_request_mode_t *mp;
15448   int ret;
15449
15450   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15451
15452   /* send */
15453   S (mp);
15454
15455   /* wait for reply */
15456   W (ret);
15457   return ret;
15458 }
15459
15460 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15461
15462 static int
15463 api_one_map_request_mode (vat_main_t * vam)
15464 {
15465   unformat_input_t *input = vam->input;
15466   vl_api_one_map_request_mode_t *mp;
15467   u8 mode = 0;
15468   int ret;
15469
15470   /* Parse args required to build the message */
15471   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15472     {
15473       if (unformat (input, "dst-only"))
15474         mode = 0;
15475       else if (unformat (input, "src-dst"))
15476         mode = 1;
15477       else
15478         {
15479           errmsg ("parse error '%U'", format_unformat_error, input);
15480           return -99;
15481         }
15482     }
15483
15484   M (ONE_MAP_REQUEST_MODE, mp);
15485
15486   mp->mode = mode;
15487
15488   /* send */
15489   S (mp);
15490
15491   /* wait for reply */
15492   W (ret);
15493   return ret;
15494 }
15495
15496 #define api_lisp_map_request_mode api_one_map_request_mode
15497
15498 /**
15499  * Enable/disable ONE proxy ITR.
15500  *
15501  * @param vam vpp API test context
15502  * @return return code
15503  */
15504 static int
15505 api_one_pitr_set_locator_set (vat_main_t * vam)
15506 {
15507   u8 ls_name_set = 0;
15508   unformat_input_t *input = vam->input;
15509   vl_api_one_pitr_set_locator_set_t *mp;
15510   u8 is_add = 1;
15511   u8 *ls_name = 0;
15512   int ret;
15513
15514   /* Parse args required to build the message */
15515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15516     {
15517       if (unformat (input, "del"))
15518         is_add = 0;
15519       else if (unformat (input, "locator-set %s", &ls_name))
15520         ls_name_set = 1;
15521       else
15522         {
15523           errmsg ("parse error '%U'", format_unformat_error, input);
15524           return -99;
15525         }
15526     }
15527
15528   if (!ls_name_set)
15529     {
15530       errmsg ("locator-set name not set!");
15531       return -99;
15532     }
15533
15534   M (ONE_PITR_SET_LOCATOR_SET, mp);
15535
15536   mp->is_add = is_add;
15537   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15538   vec_free (ls_name);
15539
15540   /* send */
15541   S (mp);
15542
15543   /* wait for reply */
15544   W (ret);
15545   return ret;
15546 }
15547
15548 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15549
15550 static int
15551 api_one_nsh_set_locator_set (vat_main_t * vam)
15552 {
15553   u8 ls_name_set = 0;
15554   unformat_input_t *input = vam->input;
15555   vl_api_one_nsh_set_locator_set_t *mp;
15556   u8 is_add = 1;
15557   u8 *ls_name = 0;
15558   int ret;
15559
15560   /* Parse args required to build the message */
15561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15562     {
15563       if (unformat (input, "del"))
15564         is_add = 0;
15565       else if (unformat (input, "ls %s", &ls_name))
15566         ls_name_set = 1;
15567       else
15568         {
15569           errmsg ("parse error '%U'", format_unformat_error, input);
15570           return -99;
15571         }
15572     }
15573
15574   if (!ls_name_set && is_add)
15575     {
15576       errmsg ("locator-set name not set!");
15577       return -99;
15578     }
15579
15580   M (ONE_NSH_SET_LOCATOR_SET, mp);
15581
15582   mp->is_add = is_add;
15583   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15584   vec_free (ls_name);
15585
15586   /* send */
15587   S (mp);
15588
15589   /* wait for reply */
15590   W (ret);
15591   return ret;
15592 }
15593
15594 static int
15595 api_show_one_pitr (vat_main_t * vam)
15596 {
15597   vl_api_show_one_pitr_t *mp;
15598   int ret;
15599
15600   if (!vam->json_output)
15601     {
15602       print (vam->ofp, "%=20s", "lisp status:");
15603     }
15604
15605   M (SHOW_ONE_PITR, mp);
15606   /* send it... */
15607   S (mp);
15608
15609   /* Wait for a reply... */
15610   W (ret);
15611   return ret;
15612 }
15613
15614 #define api_show_lisp_pitr api_show_one_pitr
15615
15616 static int
15617 api_one_use_petr (vat_main_t * vam)
15618 {
15619   unformat_input_t *input = vam->input;
15620   vl_api_one_use_petr_t *mp;
15621   u8 is_add = 0;
15622   ip_address_t ip;
15623   int ret;
15624
15625   clib_memset (&ip, 0, sizeof (ip));
15626
15627   /* Parse args required to build the message */
15628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15629     {
15630       if (unformat (input, "disable"))
15631         is_add = 0;
15632       else
15633         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15634         {
15635           is_add = 1;
15636           ip_addr_version (&ip) = AF_IP4;
15637         }
15638       else
15639         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15640         {
15641           is_add = 1;
15642           ip_addr_version (&ip) = AF_IP6;
15643         }
15644       else
15645         {
15646           errmsg ("parse error '%U'", format_unformat_error, input);
15647           return -99;
15648         }
15649     }
15650
15651   M (ONE_USE_PETR, mp);
15652
15653   mp->is_add = is_add;
15654   if (is_add)
15655     {
15656       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15657       if (mp->is_ip4)
15658         clib_memcpy (mp->address, &ip, 4);
15659       else
15660         clib_memcpy (mp->address, &ip, 16);
15661     }
15662
15663   /* send */
15664   S (mp);
15665
15666   /* wait for reply */
15667   W (ret);
15668   return ret;
15669 }
15670
15671 #define api_lisp_use_petr api_one_use_petr
15672
15673 static int
15674 api_show_one_nsh_mapping (vat_main_t * vam)
15675 {
15676   vl_api_show_one_use_petr_t *mp;
15677   int ret;
15678
15679   if (!vam->json_output)
15680     {
15681       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15682     }
15683
15684   M (SHOW_ONE_NSH_MAPPING, mp);
15685   /* send it... */
15686   S (mp);
15687
15688   /* Wait for a reply... */
15689   W (ret);
15690   return ret;
15691 }
15692
15693 static int
15694 api_show_one_use_petr (vat_main_t * vam)
15695 {
15696   vl_api_show_one_use_petr_t *mp;
15697   int ret;
15698
15699   if (!vam->json_output)
15700     {
15701       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15702     }
15703
15704   M (SHOW_ONE_USE_PETR, mp);
15705   /* send it... */
15706   S (mp);
15707
15708   /* Wait for a reply... */
15709   W (ret);
15710   return ret;
15711 }
15712
15713 #define api_show_lisp_use_petr api_show_one_use_petr
15714
15715 /**
15716  * Add/delete mapping between vni and vrf
15717  */
15718 static int
15719 api_one_eid_table_add_del_map (vat_main_t * vam)
15720 {
15721   unformat_input_t *input = vam->input;
15722   vl_api_one_eid_table_add_del_map_t *mp;
15723   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15724   u32 vni, vrf, bd_index;
15725   int ret;
15726
15727   /* Parse args required to build the message */
15728   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15729     {
15730       if (unformat (input, "del"))
15731         is_add = 0;
15732       else if (unformat (input, "vrf %d", &vrf))
15733         vrf_set = 1;
15734       else if (unformat (input, "bd_index %d", &bd_index))
15735         bd_index_set = 1;
15736       else if (unformat (input, "vni %d", &vni))
15737         vni_set = 1;
15738       else
15739         break;
15740     }
15741
15742   if (!vni_set || (!vrf_set && !bd_index_set))
15743     {
15744       errmsg ("missing arguments!");
15745       return -99;
15746     }
15747
15748   if (vrf_set && bd_index_set)
15749     {
15750       errmsg ("error: both vrf and bd entered!");
15751       return -99;
15752     }
15753
15754   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15755
15756   mp->is_add = is_add;
15757   mp->vni = htonl (vni);
15758   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15759   mp->is_l2 = bd_index_set;
15760
15761   /* send */
15762   S (mp);
15763
15764   /* wait for reply */
15765   W (ret);
15766   return ret;
15767 }
15768
15769 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15770
15771 uword
15772 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15773 {
15774   u32 *action = va_arg (*args, u32 *);
15775   u8 *s = 0;
15776
15777   if (unformat (input, "%s", &s))
15778     {
15779       if (!strcmp ((char *) s, "no-action"))
15780         action[0] = 0;
15781       else if (!strcmp ((char *) s, "natively-forward"))
15782         action[0] = 1;
15783       else if (!strcmp ((char *) s, "send-map-request"))
15784         action[0] = 2;
15785       else if (!strcmp ((char *) s, "drop"))
15786         action[0] = 3;
15787       else
15788         {
15789           clib_warning ("invalid action: '%s'", s);
15790           action[0] = 3;
15791         }
15792     }
15793   else
15794     return 0;
15795
15796   vec_free (s);
15797   return 1;
15798 }
15799
15800 /**
15801  * Add/del remote mapping to/from ONE control plane
15802  *
15803  * @param vam vpp API test context
15804  * @return return code
15805  */
15806 static int
15807 api_one_add_del_remote_mapping (vat_main_t * vam)
15808 {
15809   unformat_input_t *input = vam->input;
15810   vl_api_one_add_del_remote_mapping_t *mp;
15811   u32 vni = 0;
15812   lisp_eid_vat_t _eid, *eid = &_eid;
15813   lisp_eid_vat_t _seid, *seid = &_seid;
15814   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15815   u32 action = ~0, p, w, data_len;
15816   ip4_address_t rloc4;
15817   ip6_address_t rloc6;
15818   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15819   int ret;
15820
15821   clib_memset (&rloc, 0, sizeof (rloc));
15822
15823   /* Parse args required to build the message */
15824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (input, "del-all"))
15827         {
15828           del_all = 1;
15829         }
15830       else if (unformat (input, "del"))
15831         {
15832           is_add = 0;
15833         }
15834       else if (unformat (input, "add"))
15835         {
15836           is_add = 1;
15837         }
15838       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15839         {
15840           eid_set = 1;
15841         }
15842       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15843         {
15844           seid_set = 1;
15845         }
15846       else if (unformat (input, "vni %d", &vni))
15847         {
15848           ;
15849         }
15850       else if (unformat (input, "p %d w %d", &p, &w))
15851         {
15852           if (!curr_rloc)
15853             {
15854               errmsg ("No RLOC configured for setting priority/weight!");
15855               return -99;
15856             }
15857           curr_rloc->priority = p;
15858           curr_rloc->weight = w;
15859         }
15860       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15861         {
15862           rloc.is_ip4 = 1;
15863           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15864           vec_add1 (rlocs, rloc);
15865           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15866         }
15867       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15868         {
15869           rloc.is_ip4 = 0;
15870           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15871           vec_add1 (rlocs, rloc);
15872           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15873         }
15874       else if (unformat (input, "action %U",
15875                          unformat_negative_mapping_action, &action))
15876         {
15877           ;
15878         }
15879       else
15880         {
15881           clib_warning ("parse error '%U'", format_unformat_error, input);
15882           return -99;
15883         }
15884     }
15885
15886   if (0 == eid_set)
15887     {
15888       errmsg ("missing params!");
15889       return -99;
15890     }
15891
15892   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15893     {
15894       errmsg ("no action set for negative map-reply!");
15895       return -99;
15896     }
15897
15898   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15899
15900   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15901   mp->is_add = is_add;
15902   mp->vni = htonl (vni);
15903   mp->action = (u8) action;
15904   mp->is_src_dst = seid_set;
15905   mp->eid_len = eid->len;
15906   mp->seid_len = seid->len;
15907   mp->del_all = del_all;
15908   mp->eid_type = eid->type;
15909   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15910   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15911
15912   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15913   clib_memcpy (mp->rlocs, rlocs, data_len);
15914   vec_free (rlocs);
15915
15916   /* send it... */
15917   S (mp);
15918
15919   /* Wait for a reply... */
15920   W (ret);
15921   return ret;
15922 }
15923
15924 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15925
15926 /**
15927  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15928  * forwarding entries in data-plane accordingly.
15929  *
15930  * @param vam vpp API test context
15931  * @return return code
15932  */
15933 static int
15934 api_one_add_del_adjacency (vat_main_t * vam)
15935 {
15936   unformat_input_t *input = vam->input;
15937   vl_api_one_add_del_adjacency_t *mp;
15938   u32 vni = 0;
15939   ip4_address_t leid4, reid4;
15940   ip6_address_t leid6, reid6;
15941   u8 reid_mac[6] = { 0 };
15942   u8 leid_mac[6] = { 0 };
15943   u8 reid_type, leid_type;
15944   u32 leid_len = 0, reid_len = 0, len;
15945   u8 is_add = 1;
15946   int ret;
15947
15948   leid_type = reid_type = (u8) ~ 0;
15949
15950   /* Parse args required to build the message */
15951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15952     {
15953       if (unformat (input, "del"))
15954         {
15955           is_add = 0;
15956         }
15957       else if (unformat (input, "add"))
15958         {
15959           is_add = 1;
15960         }
15961       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15962                          &reid4, &len))
15963         {
15964           reid_type = 0;        /* ipv4 */
15965           reid_len = len;
15966         }
15967       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15968                          &reid6, &len))
15969         {
15970           reid_type = 1;        /* ipv6 */
15971           reid_len = len;
15972         }
15973       else if (unformat (input, "reid %U", unformat_ethernet_address,
15974                          reid_mac))
15975         {
15976           reid_type = 2;        /* mac */
15977         }
15978       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15979                          &leid4, &len))
15980         {
15981           leid_type = 0;        /* ipv4 */
15982           leid_len = len;
15983         }
15984       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15985                          &leid6, &len))
15986         {
15987           leid_type = 1;        /* ipv6 */
15988           leid_len = len;
15989         }
15990       else if (unformat (input, "leid %U", unformat_ethernet_address,
15991                          leid_mac))
15992         {
15993           leid_type = 2;        /* mac */
15994         }
15995       else if (unformat (input, "vni %d", &vni))
15996         {
15997           ;
15998         }
15999       else
16000         {
16001           errmsg ("parse error '%U'", format_unformat_error, input);
16002           return -99;
16003         }
16004     }
16005
16006   if ((u8) ~ 0 == reid_type)
16007     {
16008       errmsg ("missing params!");
16009       return -99;
16010     }
16011
16012   if (leid_type != reid_type)
16013     {
16014       errmsg ("remote and local EIDs are of different types!");
16015       return -99;
16016     }
16017
16018   M (ONE_ADD_DEL_ADJACENCY, mp);
16019   mp->is_add = is_add;
16020   mp->vni = htonl (vni);
16021   mp->leid_len = leid_len;
16022   mp->reid_len = reid_len;
16023   mp->eid_type = reid_type;
16024
16025   switch (mp->eid_type)
16026     {
16027     case 0:
16028       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16029       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16030       break;
16031     case 1:
16032       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16033       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16034       break;
16035     case 2:
16036       clib_memcpy (mp->leid, leid_mac, 6);
16037       clib_memcpy (mp->reid, reid_mac, 6);
16038       break;
16039     default:
16040       errmsg ("unknown EID type %d!", mp->eid_type);
16041       return 0;
16042     }
16043
16044   /* send it... */
16045   S (mp);
16046
16047   /* Wait for a reply... */
16048   W (ret);
16049   return ret;
16050 }
16051
16052 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16053
16054 uword
16055 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16056 {
16057   u32 *mode = va_arg (*args, u32 *);
16058
16059   if (unformat (input, "lisp"))
16060     *mode = 0;
16061   else if (unformat (input, "vxlan"))
16062     *mode = 1;
16063   else
16064     return 0;
16065
16066   return 1;
16067 }
16068
16069 static int
16070 api_gpe_get_encap_mode (vat_main_t * vam)
16071 {
16072   vl_api_gpe_get_encap_mode_t *mp;
16073   int ret;
16074
16075   /* Construct the API message */
16076   M (GPE_GET_ENCAP_MODE, mp);
16077
16078   /* send it... */
16079   S (mp);
16080
16081   /* Wait for a reply... */
16082   W (ret);
16083   return ret;
16084 }
16085
16086 static int
16087 api_gpe_set_encap_mode (vat_main_t * vam)
16088 {
16089   unformat_input_t *input = vam->input;
16090   vl_api_gpe_set_encap_mode_t *mp;
16091   int ret;
16092   u32 mode = 0;
16093
16094   /* Parse args required to build the message */
16095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16096     {
16097       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16098         ;
16099       else
16100         break;
16101     }
16102
16103   /* Construct the API message */
16104   M (GPE_SET_ENCAP_MODE, mp);
16105
16106   mp->mode = mode;
16107
16108   /* send it... */
16109   S (mp);
16110
16111   /* Wait for a reply... */
16112   W (ret);
16113   return ret;
16114 }
16115
16116 static int
16117 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16118 {
16119   unformat_input_t *input = vam->input;
16120   vl_api_gpe_add_del_iface_t *mp;
16121   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16122   u32 dp_table = 0, vni = 0;
16123   int ret;
16124
16125   /* Parse args required to build the message */
16126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16127     {
16128       if (unformat (input, "up"))
16129         {
16130           action_set = 1;
16131           is_add = 1;
16132         }
16133       else if (unformat (input, "down"))
16134         {
16135           action_set = 1;
16136           is_add = 0;
16137         }
16138       else if (unformat (input, "table_id %d", &dp_table))
16139         {
16140           dp_table_set = 1;
16141         }
16142       else if (unformat (input, "bd_id %d", &dp_table))
16143         {
16144           dp_table_set = 1;
16145           is_l2 = 1;
16146         }
16147       else if (unformat (input, "vni %d", &vni))
16148         {
16149           vni_set = 1;
16150         }
16151       else
16152         break;
16153     }
16154
16155   if (action_set == 0)
16156     {
16157       errmsg ("Action not set");
16158       return -99;
16159     }
16160   if (dp_table_set == 0 || vni_set == 0)
16161     {
16162       errmsg ("vni and dp_table must be set");
16163       return -99;
16164     }
16165
16166   /* Construct the API message */
16167   M (GPE_ADD_DEL_IFACE, mp);
16168
16169   mp->is_add = is_add;
16170   mp->dp_table = clib_host_to_net_u32 (dp_table);
16171   mp->is_l2 = is_l2;
16172   mp->vni = clib_host_to_net_u32 (vni);
16173
16174   /* send it... */
16175   S (mp);
16176
16177   /* Wait for a reply... */
16178   W (ret);
16179   return ret;
16180 }
16181
16182 static int
16183 api_one_map_register_fallback_threshold (vat_main_t * vam)
16184 {
16185   unformat_input_t *input = vam->input;
16186   vl_api_one_map_register_fallback_threshold_t *mp;
16187   u32 value = 0;
16188   u8 is_set = 0;
16189   int ret;
16190
16191   /* Parse args required to build the message */
16192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16193     {
16194       if (unformat (input, "%u", &value))
16195         is_set = 1;
16196       else
16197         {
16198           clib_warning ("parse error '%U'", format_unformat_error, input);
16199           return -99;
16200         }
16201     }
16202
16203   if (!is_set)
16204     {
16205       errmsg ("fallback threshold value is missing!");
16206       return -99;
16207     }
16208
16209   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16210   mp->value = clib_host_to_net_u32 (value);
16211
16212   /* send it... */
16213   S (mp);
16214
16215   /* Wait for a reply... */
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16222 {
16223   vl_api_show_one_map_register_fallback_threshold_t *mp;
16224   int ret;
16225
16226   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16227
16228   /* send it... */
16229   S (mp);
16230
16231   /* Wait for a reply... */
16232   W (ret);
16233   return ret;
16234 }
16235
16236 uword
16237 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16238 {
16239   u32 *proto = va_arg (*args, u32 *);
16240
16241   if (unformat (input, "udp"))
16242     *proto = 1;
16243   else if (unformat (input, "api"))
16244     *proto = 2;
16245   else
16246     return 0;
16247
16248   return 1;
16249 }
16250
16251 static int
16252 api_one_set_transport_protocol (vat_main_t * vam)
16253 {
16254   unformat_input_t *input = vam->input;
16255   vl_api_one_set_transport_protocol_t *mp;
16256   u8 is_set = 0;
16257   u32 protocol = 0;
16258   int ret;
16259
16260   /* Parse args required to build the message */
16261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16262     {
16263       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16264         is_set = 1;
16265       else
16266         {
16267           clib_warning ("parse error '%U'", format_unformat_error, input);
16268           return -99;
16269         }
16270     }
16271
16272   if (!is_set)
16273     {
16274       errmsg ("Transport protocol missing!");
16275       return -99;
16276     }
16277
16278   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16279   mp->protocol = (u8) protocol;
16280
16281   /* send it... */
16282   S (mp);
16283
16284   /* Wait for a reply... */
16285   W (ret);
16286   return ret;
16287 }
16288
16289 static int
16290 api_one_get_transport_protocol (vat_main_t * vam)
16291 {
16292   vl_api_one_get_transport_protocol_t *mp;
16293   int ret;
16294
16295   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16296
16297   /* send it... */
16298   S (mp);
16299
16300   /* Wait for a reply... */
16301   W (ret);
16302   return ret;
16303 }
16304
16305 static int
16306 api_one_map_register_set_ttl (vat_main_t * vam)
16307 {
16308   unformat_input_t *input = vam->input;
16309   vl_api_one_map_register_set_ttl_t *mp;
16310   u32 ttl = 0;
16311   u8 is_set = 0;
16312   int ret;
16313
16314   /* Parse args required to build the message */
16315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16316     {
16317       if (unformat (input, "%u", &ttl))
16318         is_set = 1;
16319       else
16320         {
16321           clib_warning ("parse error '%U'", format_unformat_error, input);
16322           return -99;
16323         }
16324     }
16325
16326   if (!is_set)
16327     {
16328       errmsg ("TTL value missing!");
16329       return -99;
16330     }
16331
16332   M (ONE_MAP_REGISTER_SET_TTL, mp);
16333   mp->ttl = clib_host_to_net_u32 (ttl);
16334
16335   /* send it... */
16336   S (mp);
16337
16338   /* Wait for a reply... */
16339   W (ret);
16340   return ret;
16341 }
16342
16343 static int
16344 api_show_one_map_register_ttl (vat_main_t * vam)
16345 {
16346   vl_api_show_one_map_register_ttl_t *mp;
16347   int ret;
16348
16349   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16350
16351   /* send it... */
16352   S (mp);
16353
16354   /* Wait for a reply... */
16355   W (ret);
16356   return ret;
16357 }
16358
16359 /**
16360  * Add/del map request itr rlocs from ONE control plane and updates
16361  *
16362  * @param vam vpp API test context
16363  * @return return code
16364  */
16365 static int
16366 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16367 {
16368   unformat_input_t *input = vam->input;
16369   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16370   u8 *locator_set_name = 0;
16371   u8 locator_set_name_set = 0;
16372   u8 is_add = 1;
16373   int ret;
16374
16375   /* Parse args required to build the message */
16376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16377     {
16378       if (unformat (input, "del"))
16379         {
16380           is_add = 0;
16381         }
16382       else if (unformat (input, "%_%v%_", &locator_set_name))
16383         {
16384           locator_set_name_set = 1;
16385         }
16386       else
16387         {
16388           clib_warning ("parse error '%U'", format_unformat_error, input);
16389           return -99;
16390         }
16391     }
16392
16393   if (is_add && !locator_set_name_set)
16394     {
16395       errmsg ("itr-rloc is not set!");
16396       return -99;
16397     }
16398
16399   if (is_add && vec_len (locator_set_name) > 64)
16400     {
16401       errmsg ("itr-rloc locator-set name too long");
16402       vec_free (locator_set_name);
16403       return -99;
16404     }
16405
16406   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16407   mp->is_add = is_add;
16408   if (is_add)
16409     {
16410       clib_memcpy (mp->locator_set_name, locator_set_name,
16411                    vec_len (locator_set_name));
16412     }
16413   else
16414     {
16415       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16416     }
16417   vec_free (locator_set_name);
16418
16419   /* send it... */
16420   S (mp);
16421
16422   /* Wait for a reply... */
16423   W (ret);
16424   return ret;
16425 }
16426
16427 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16428
16429 static int
16430 api_one_locator_dump (vat_main_t * vam)
16431 {
16432   unformat_input_t *input = vam->input;
16433   vl_api_one_locator_dump_t *mp;
16434   vl_api_control_ping_t *mp_ping;
16435   u8 is_index_set = 0, is_name_set = 0;
16436   u8 *ls_name = 0;
16437   u32 ls_index = ~0;
16438   int ret;
16439
16440   /* Parse args required to build the message */
16441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16442     {
16443       if (unformat (input, "ls_name %_%v%_", &ls_name))
16444         {
16445           is_name_set = 1;
16446         }
16447       else if (unformat (input, "ls_index %d", &ls_index))
16448         {
16449           is_index_set = 1;
16450         }
16451       else
16452         {
16453           errmsg ("parse error '%U'", format_unformat_error, input);
16454           return -99;
16455         }
16456     }
16457
16458   if (!is_index_set && !is_name_set)
16459     {
16460       errmsg ("error: expected one of index or name!");
16461       return -99;
16462     }
16463
16464   if (is_index_set && is_name_set)
16465     {
16466       errmsg ("error: only one param expected!");
16467       return -99;
16468     }
16469
16470   if (vec_len (ls_name) > 62)
16471     {
16472       errmsg ("error: locator set name too long!");
16473       return -99;
16474     }
16475
16476   if (!vam->json_output)
16477     {
16478       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16479     }
16480
16481   M (ONE_LOCATOR_DUMP, mp);
16482   mp->is_index_set = is_index_set;
16483
16484   if (is_index_set)
16485     mp->ls_index = clib_host_to_net_u32 (ls_index);
16486   else
16487     {
16488       vec_add1 (ls_name, 0);
16489       strncpy ((char *) mp->ls_name, (char *) ls_name,
16490                sizeof (mp->ls_name) - 1);
16491     }
16492
16493   /* send it... */
16494   S (mp);
16495
16496   /* Use a control ping for synchronization */
16497   MPING (CONTROL_PING, mp_ping);
16498   S (mp_ping);
16499
16500   /* Wait for a reply... */
16501   W (ret);
16502   return ret;
16503 }
16504
16505 #define api_lisp_locator_dump api_one_locator_dump
16506
16507 static int
16508 api_one_locator_set_dump (vat_main_t * vam)
16509 {
16510   vl_api_one_locator_set_dump_t *mp;
16511   vl_api_control_ping_t *mp_ping;
16512   unformat_input_t *input = vam->input;
16513   u8 filter = 0;
16514   int ret;
16515
16516   /* Parse args required to build the message */
16517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (input, "local"))
16520         {
16521           filter = 1;
16522         }
16523       else if (unformat (input, "remote"))
16524         {
16525           filter = 2;
16526         }
16527       else
16528         {
16529           errmsg ("parse error '%U'", format_unformat_error, input);
16530           return -99;
16531         }
16532     }
16533
16534   if (!vam->json_output)
16535     {
16536       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16537     }
16538
16539   M (ONE_LOCATOR_SET_DUMP, mp);
16540
16541   mp->filter = filter;
16542
16543   /* send it... */
16544   S (mp);
16545
16546   /* Use a control ping for synchronization */
16547   MPING (CONTROL_PING, mp_ping);
16548   S (mp_ping);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 #define api_lisp_locator_set_dump api_one_locator_set_dump
16556
16557 static int
16558 api_one_eid_table_map_dump (vat_main_t * vam)
16559 {
16560   u8 is_l2 = 0;
16561   u8 mode_set = 0;
16562   unformat_input_t *input = vam->input;
16563   vl_api_one_eid_table_map_dump_t *mp;
16564   vl_api_control_ping_t *mp_ping;
16565   int ret;
16566
16567   /* Parse args required to build the message */
16568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16569     {
16570       if (unformat (input, "l2"))
16571         {
16572           is_l2 = 1;
16573           mode_set = 1;
16574         }
16575       else if (unformat (input, "l3"))
16576         {
16577           is_l2 = 0;
16578           mode_set = 1;
16579         }
16580       else
16581         {
16582           errmsg ("parse error '%U'", format_unformat_error, input);
16583           return -99;
16584         }
16585     }
16586
16587   if (!mode_set)
16588     {
16589       errmsg ("expected one of 'l2' or 'l3' parameter!");
16590       return -99;
16591     }
16592
16593   if (!vam->json_output)
16594     {
16595       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16596     }
16597
16598   M (ONE_EID_TABLE_MAP_DUMP, mp);
16599   mp->is_l2 = is_l2;
16600
16601   /* send it... */
16602   S (mp);
16603
16604   /* Use a control ping for synchronization */
16605   MPING (CONTROL_PING, mp_ping);
16606   S (mp_ping);
16607
16608   /* Wait for a reply... */
16609   W (ret);
16610   return ret;
16611 }
16612
16613 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16614
16615 static int
16616 api_one_eid_table_vni_dump (vat_main_t * vam)
16617 {
16618   vl_api_one_eid_table_vni_dump_t *mp;
16619   vl_api_control_ping_t *mp_ping;
16620   int ret;
16621
16622   if (!vam->json_output)
16623     {
16624       print (vam->ofp, "VNI");
16625     }
16626
16627   M (ONE_EID_TABLE_VNI_DUMP, mp);
16628
16629   /* send it... */
16630   S (mp);
16631
16632   /* Use a control ping for synchronization */
16633   MPING (CONTROL_PING, mp_ping);
16634   S (mp_ping);
16635
16636   /* Wait for a reply... */
16637   W (ret);
16638   return ret;
16639 }
16640
16641 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16642
16643 static int
16644 api_one_eid_table_dump (vat_main_t * vam)
16645 {
16646   unformat_input_t *i = vam->input;
16647   vl_api_one_eid_table_dump_t *mp;
16648   vl_api_control_ping_t *mp_ping;
16649   struct in_addr ip4;
16650   struct in6_addr ip6;
16651   u8 mac[6];
16652   u8 eid_type = ~0, eid_set = 0;
16653   u32 prefix_length = ~0, t, vni = 0;
16654   u8 filter = 0;
16655   int ret;
16656   lisp_nsh_api_t nsh;
16657
16658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16659     {
16660       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16661         {
16662           eid_set = 1;
16663           eid_type = 0;
16664           prefix_length = t;
16665         }
16666       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16667         {
16668           eid_set = 1;
16669           eid_type = 1;
16670           prefix_length = t;
16671         }
16672       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16673         {
16674           eid_set = 1;
16675           eid_type = 2;
16676         }
16677       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16678         {
16679           eid_set = 1;
16680           eid_type = 3;
16681         }
16682       else if (unformat (i, "vni %d", &t))
16683         {
16684           vni = t;
16685         }
16686       else if (unformat (i, "local"))
16687         {
16688           filter = 1;
16689         }
16690       else if (unformat (i, "remote"))
16691         {
16692           filter = 2;
16693         }
16694       else
16695         {
16696           errmsg ("parse error '%U'", format_unformat_error, i);
16697           return -99;
16698         }
16699     }
16700
16701   if (!vam->json_output)
16702     {
16703       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16704              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16705     }
16706
16707   M (ONE_EID_TABLE_DUMP, mp);
16708
16709   mp->filter = filter;
16710   if (eid_set)
16711     {
16712       mp->eid_set = 1;
16713       mp->vni = htonl (vni);
16714       mp->eid_type = eid_type;
16715       switch (eid_type)
16716         {
16717         case 0:
16718           mp->prefix_length = prefix_length;
16719           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16720           break;
16721         case 1:
16722           mp->prefix_length = prefix_length;
16723           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16724           break;
16725         case 2:
16726           clib_memcpy (mp->eid, mac, sizeof (mac));
16727           break;
16728         case 3:
16729           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16730           break;
16731         default:
16732           errmsg ("unknown EID type %d!", eid_type);
16733           return -99;
16734         }
16735     }
16736
16737   /* send it... */
16738   S (mp);
16739
16740   /* Use a control ping for synchronization */
16741   MPING (CONTROL_PING, mp_ping);
16742   S (mp_ping);
16743
16744   /* Wait for a reply... */
16745   W (ret);
16746   return ret;
16747 }
16748
16749 #define api_lisp_eid_table_dump api_one_eid_table_dump
16750
16751 static int
16752 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16753 {
16754   unformat_input_t *i = vam->input;
16755   vl_api_gpe_fwd_entries_get_t *mp;
16756   u8 vni_set = 0;
16757   u32 vni = ~0;
16758   int ret;
16759
16760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16761     {
16762       if (unformat (i, "vni %d", &vni))
16763         {
16764           vni_set = 1;
16765         }
16766       else
16767         {
16768           errmsg ("parse error '%U'", format_unformat_error, i);
16769           return -99;
16770         }
16771     }
16772
16773   if (!vni_set)
16774     {
16775       errmsg ("vni not set!");
16776       return -99;
16777     }
16778
16779   if (!vam->json_output)
16780     {
16781       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16782              "leid", "reid");
16783     }
16784
16785   M (GPE_FWD_ENTRIES_GET, mp);
16786   mp->vni = clib_host_to_net_u32 (vni);
16787
16788   /* send it... */
16789   S (mp);
16790
16791   /* Wait for a reply... */
16792   W (ret);
16793   return ret;
16794 }
16795
16796 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16797 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16798 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16799 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16800 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16801 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16802 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16803 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16804
16805 static int
16806 api_one_adjacencies_get (vat_main_t * vam)
16807 {
16808   unformat_input_t *i = vam->input;
16809   vl_api_one_adjacencies_get_t *mp;
16810   u8 vni_set = 0;
16811   u32 vni = ~0;
16812   int ret;
16813
16814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16815     {
16816       if (unformat (i, "vni %d", &vni))
16817         {
16818           vni_set = 1;
16819         }
16820       else
16821         {
16822           errmsg ("parse error '%U'", format_unformat_error, i);
16823           return -99;
16824         }
16825     }
16826
16827   if (!vni_set)
16828     {
16829       errmsg ("vni not set!");
16830       return -99;
16831     }
16832
16833   if (!vam->json_output)
16834     {
16835       print (vam->ofp, "%s %40s", "leid", "reid");
16836     }
16837
16838   M (ONE_ADJACENCIES_GET, mp);
16839   mp->vni = clib_host_to_net_u32 (vni);
16840
16841   /* send it... */
16842   S (mp);
16843
16844   /* Wait for a reply... */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 #define api_lisp_adjacencies_get api_one_adjacencies_get
16850
16851 static int
16852 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16853 {
16854   unformat_input_t *i = vam->input;
16855   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16856   int ret;
16857   u8 ip_family_set = 0, is_ip4 = 1;
16858
16859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16860     {
16861       if (unformat (i, "ip4"))
16862         {
16863           ip_family_set = 1;
16864           is_ip4 = 1;
16865         }
16866       else if (unformat (i, "ip6"))
16867         {
16868           ip_family_set = 1;
16869           is_ip4 = 0;
16870         }
16871       else
16872         {
16873           errmsg ("parse error '%U'", format_unformat_error, i);
16874           return -99;
16875         }
16876     }
16877
16878   if (!ip_family_set)
16879     {
16880       errmsg ("ip family not set!");
16881       return -99;
16882     }
16883
16884   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16885   mp->is_ip4 = is_ip4;
16886
16887   /* send it... */
16888   S (mp);
16889
16890   /* Wait for a reply... */
16891   W (ret);
16892   return ret;
16893 }
16894
16895 static int
16896 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16897 {
16898   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16899   int ret;
16900
16901   if (!vam->json_output)
16902     {
16903       print (vam->ofp, "VNIs");
16904     }
16905
16906   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16907
16908   /* send it... */
16909   S (mp);
16910
16911   /* Wait for a reply... */
16912   W (ret);
16913   return ret;
16914 }
16915
16916 static int
16917 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16918 {
16919   unformat_input_t *i = vam->input;
16920   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16921   int ret = 0;
16922   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16923   struct in_addr ip4;
16924   struct in6_addr ip6;
16925   u32 table_id = 0, nh_sw_if_index = ~0;
16926
16927   clib_memset (&ip4, 0, sizeof (ip4));
16928   clib_memset (&ip6, 0, sizeof (ip6));
16929
16930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16931     {
16932       if (unformat (i, "del"))
16933         is_add = 0;
16934       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16935                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16936         {
16937           ip_set = 1;
16938           is_ip4 = 1;
16939         }
16940       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16941                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16942         {
16943           ip_set = 1;
16944           is_ip4 = 0;
16945         }
16946       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16947         {
16948           ip_set = 1;
16949           is_ip4 = 1;
16950           nh_sw_if_index = ~0;
16951         }
16952       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16953         {
16954           ip_set = 1;
16955           is_ip4 = 0;
16956           nh_sw_if_index = ~0;
16957         }
16958       else if (unformat (i, "table %d", &table_id))
16959         ;
16960       else
16961         {
16962           errmsg ("parse error '%U'", format_unformat_error, i);
16963           return -99;
16964         }
16965     }
16966
16967   if (!ip_set)
16968     {
16969       errmsg ("nh addr not set!");
16970       return -99;
16971     }
16972
16973   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16974   mp->is_add = is_add;
16975   mp->table_id = clib_host_to_net_u32 (table_id);
16976   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16977   mp->is_ip4 = is_ip4;
16978   if (is_ip4)
16979     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16980   else
16981     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16982
16983   /* send it... */
16984   S (mp);
16985
16986   /* Wait for a reply... */
16987   W (ret);
16988   return ret;
16989 }
16990
16991 static int
16992 api_one_map_server_dump (vat_main_t * vam)
16993 {
16994   vl_api_one_map_server_dump_t *mp;
16995   vl_api_control_ping_t *mp_ping;
16996   int ret;
16997
16998   if (!vam->json_output)
16999     {
17000       print (vam->ofp, "%=20s", "Map server");
17001     }
17002
17003   M (ONE_MAP_SERVER_DUMP, mp);
17004   /* send it... */
17005   S (mp);
17006
17007   /* Use a control ping for synchronization */
17008   MPING (CONTROL_PING, mp_ping);
17009   S (mp_ping);
17010
17011   /* Wait for a reply... */
17012   W (ret);
17013   return ret;
17014 }
17015
17016 #define api_lisp_map_server_dump api_one_map_server_dump
17017
17018 static int
17019 api_one_map_resolver_dump (vat_main_t * vam)
17020 {
17021   vl_api_one_map_resolver_dump_t *mp;
17022   vl_api_control_ping_t *mp_ping;
17023   int ret;
17024
17025   if (!vam->json_output)
17026     {
17027       print (vam->ofp, "%=20s", "Map resolver");
17028     }
17029
17030   M (ONE_MAP_RESOLVER_DUMP, mp);
17031   /* send it... */
17032   S (mp);
17033
17034   /* Use a control ping for synchronization */
17035   MPING (CONTROL_PING, mp_ping);
17036   S (mp_ping);
17037
17038   /* Wait for a reply... */
17039   W (ret);
17040   return ret;
17041 }
17042
17043 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17044
17045 static int
17046 api_one_stats_flush (vat_main_t * vam)
17047 {
17048   vl_api_one_stats_flush_t *mp;
17049   int ret = 0;
17050
17051   M (ONE_STATS_FLUSH, mp);
17052   S (mp);
17053   W (ret);
17054   return ret;
17055 }
17056
17057 static int
17058 api_one_stats_dump (vat_main_t * vam)
17059 {
17060   vl_api_one_stats_dump_t *mp;
17061   vl_api_control_ping_t *mp_ping;
17062   int ret;
17063
17064   M (ONE_STATS_DUMP, mp);
17065   /* send it... */
17066   S (mp);
17067
17068   /* Use a control ping for synchronization */
17069   MPING (CONTROL_PING, mp_ping);
17070   S (mp_ping);
17071
17072   /* Wait for a reply... */
17073   W (ret);
17074   return ret;
17075 }
17076
17077 static int
17078 api_show_one_status (vat_main_t * vam)
17079 {
17080   vl_api_show_one_status_t *mp;
17081   int ret;
17082
17083   if (!vam->json_output)
17084     {
17085       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17086     }
17087
17088   M (SHOW_ONE_STATUS, mp);
17089   /* send it... */
17090   S (mp);
17091   /* Wait for a reply... */
17092   W (ret);
17093   return ret;
17094 }
17095
17096 #define api_show_lisp_status api_show_one_status
17097
17098 static int
17099 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17100 {
17101   vl_api_gpe_fwd_entry_path_dump_t *mp;
17102   vl_api_control_ping_t *mp_ping;
17103   unformat_input_t *i = vam->input;
17104   u32 fwd_entry_index = ~0;
17105   int ret;
17106
17107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17108     {
17109       if (unformat (i, "index %d", &fwd_entry_index))
17110         ;
17111       else
17112         break;
17113     }
17114
17115   if (~0 == fwd_entry_index)
17116     {
17117       errmsg ("no index specified!");
17118       return -99;
17119     }
17120
17121   if (!vam->json_output)
17122     {
17123       print (vam->ofp, "first line");
17124     }
17125
17126   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17127
17128   /* send it... */
17129   S (mp);
17130   /* Use a control ping for synchronization */
17131   MPING (CONTROL_PING, mp_ping);
17132   S (mp_ping);
17133
17134   /* Wait for a reply... */
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static int
17140 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17141 {
17142   vl_api_one_get_map_request_itr_rlocs_t *mp;
17143   int ret;
17144
17145   if (!vam->json_output)
17146     {
17147       print (vam->ofp, "%=20s", "itr-rlocs:");
17148     }
17149
17150   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17151   /* send it... */
17152   S (mp);
17153   /* Wait for a reply... */
17154   W (ret);
17155   return ret;
17156 }
17157
17158 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17159
17160 static int
17161 api_af_packet_create (vat_main_t * vam)
17162 {
17163   unformat_input_t *i = vam->input;
17164   vl_api_af_packet_create_t *mp;
17165   u8 *host_if_name = 0;
17166   u8 hw_addr[6];
17167   u8 random_hw_addr = 1;
17168   int ret;
17169
17170   clib_memset (hw_addr, 0, sizeof (hw_addr));
17171
17172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17173     {
17174       if (unformat (i, "name %s", &host_if_name))
17175         vec_add1 (host_if_name, 0);
17176       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17177         random_hw_addr = 0;
17178       else
17179         break;
17180     }
17181
17182   if (!vec_len (host_if_name))
17183     {
17184       errmsg ("host-interface name must be specified");
17185       return -99;
17186     }
17187
17188   if (vec_len (host_if_name) > 64)
17189     {
17190       errmsg ("host-interface name too long");
17191       return -99;
17192     }
17193
17194   M (AF_PACKET_CREATE, mp);
17195
17196   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17197   clib_memcpy (mp->hw_addr, hw_addr, 6);
17198   mp->use_random_hw_addr = random_hw_addr;
17199   vec_free (host_if_name);
17200
17201   S (mp);
17202
17203   /* *INDENT-OFF* */
17204   W2 (ret,
17205       ({
17206         if (ret == 0)
17207           fprintf (vam->ofp ? vam->ofp : stderr,
17208                    " new sw_if_index = %d\n", vam->sw_if_index);
17209       }));
17210   /* *INDENT-ON* */
17211   return ret;
17212 }
17213
17214 static int
17215 api_af_packet_delete (vat_main_t * vam)
17216 {
17217   unformat_input_t *i = vam->input;
17218   vl_api_af_packet_delete_t *mp;
17219   u8 *host_if_name = 0;
17220   int ret;
17221
17222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (i, "name %s", &host_if_name))
17225         vec_add1 (host_if_name, 0);
17226       else
17227         break;
17228     }
17229
17230   if (!vec_len (host_if_name))
17231     {
17232       errmsg ("host-interface name must be specified");
17233       return -99;
17234     }
17235
17236   if (vec_len (host_if_name) > 64)
17237     {
17238       errmsg ("host-interface name too long");
17239       return -99;
17240     }
17241
17242   M (AF_PACKET_DELETE, mp);
17243
17244   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17245   vec_free (host_if_name);
17246
17247   S (mp);
17248   W (ret);
17249   return ret;
17250 }
17251
17252 static void vl_api_af_packet_details_t_handler
17253   (vl_api_af_packet_details_t * mp)
17254 {
17255   vat_main_t *vam = &vat_main;
17256
17257   print (vam->ofp, "%-16s %d",
17258          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17259 }
17260
17261 static void vl_api_af_packet_details_t_handler_json
17262   (vl_api_af_packet_details_t * mp)
17263 {
17264   vat_main_t *vam = &vat_main;
17265   vat_json_node_t *node = NULL;
17266
17267   if (VAT_JSON_ARRAY != vam->json_tree.type)
17268     {
17269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17270       vat_json_init_array (&vam->json_tree);
17271     }
17272   node = vat_json_array_add (&vam->json_tree);
17273
17274   vat_json_init_object (node);
17275   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17276   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17277 }
17278
17279 static int
17280 api_af_packet_dump (vat_main_t * vam)
17281 {
17282   vl_api_af_packet_dump_t *mp;
17283   vl_api_control_ping_t *mp_ping;
17284   int ret;
17285
17286   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17287   /* Get list of tap interfaces */
17288   M (AF_PACKET_DUMP, mp);
17289   S (mp);
17290
17291   /* Use a control ping for synchronization */
17292   MPING (CONTROL_PING, mp_ping);
17293   S (mp_ping);
17294
17295   W (ret);
17296   return ret;
17297 }
17298
17299 static int
17300 api_policer_add_del (vat_main_t * vam)
17301 {
17302   unformat_input_t *i = vam->input;
17303   vl_api_policer_add_del_t *mp;
17304   u8 is_add = 1;
17305   u8 *name = 0;
17306   u32 cir = 0;
17307   u32 eir = 0;
17308   u64 cb = 0;
17309   u64 eb = 0;
17310   u8 rate_type = 0;
17311   u8 round_type = 0;
17312   u8 type = 0;
17313   u8 color_aware = 0;
17314   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17315   int ret;
17316
17317   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17318   conform_action.dscp = 0;
17319   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17320   exceed_action.dscp = 0;
17321   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17322   violate_action.dscp = 0;
17323
17324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (i, "del"))
17327         is_add = 0;
17328       else if (unformat (i, "name %s", &name))
17329         vec_add1 (name, 0);
17330       else if (unformat (i, "cir %u", &cir))
17331         ;
17332       else if (unformat (i, "eir %u", &eir))
17333         ;
17334       else if (unformat (i, "cb %u", &cb))
17335         ;
17336       else if (unformat (i, "eb %u", &eb))
17337         ;
17338       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17339                          &rate_type))
17340         ;
17341       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17342                          &round_type))
17343         ;
17344       else if (unformat (i, "type %U", unformat_policer_type, &type))
17345         ;
17346       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17347                          &conform_action))
17348         ;
17349       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17350                          &exceed_action))
17351         ;
17352       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17353                          &violate_action))
17354         ;
17355       else if (unformat (i, "color-aware"))
17356         color_aware = 1;
17357       else
17358         break;
17359     }
17360
17361   if (!vec_len (name))
17362     {
17363       errmsg ("policer name must be specified");
17364       return -99;
17365     }
17366
17367   if (vec_len (name) > 64)
17368     {
17369       errmsg ("policer name too long");
17370       return -99;
17371     }
17372
17373   M (POLICER_ADD_DEL, mp);
17374
17375   clib_memcpy (mp->name, name, vec_len (name));
17376   vec_free (name);
17377   mp->is_add = is_add;
17378   mp->cir = ntohl (cir);
17379   mp->eir = ntohl (eir);
17380   mp->cb = clib_net_to_host_u64 (cb);
17381   mp->eb = clib_net_to_host_u64 (eb);
17382   mp->rate_type = rate_type;
17383   mp->round_type = round_type;
17384   mp->type = type;
17385   mp->conform_action_type = conform_action.action_type;
17386   mp->conform_dscp = conform_action.dscp;
17387   mp->exceed_action_type = exceed_action.action_type;
17388   mp->exceed_dscp = exceed_action.dscp;
17389   mp->violate_action_type = violate_action.action_type;
17390   mp->violate_dscp = violate_action.dscp;
17391   mp->color_aware = color_aware;
17392
17393   S (mp);
17394   W (ret);
17395   return ret;
17396 }
17397
17398 static int
17399 api_policer_dump (vat_main_t * vam)
17400 {
17401   unformat_input_t *i = vam->input;
17402   vl_api_policer_dump_t *mp;
17403   vl_api_control_ping_t *mp_ping;
17404   u8 *match_name = 0;
17405   u8 match_name_valid = 0;
17406   int ret;
17407
17408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17409     {
17410       if (unformat (i, "name %s", &match_name))
17411         {
17412           vec_add1 (match_name, 0);
17413           match_name_valid = 1;
17414         }
17415       else
17416         break;
17417     }
17418
17419   M (POLICER_DUMP, mp);
17420   mp->match_name_valid = match_name_valid;
17421   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17422   vec_free (match_name);
17423   /* send it... */
17424   S (mp);
17425
17426   /* Use a control ping for synchronization */
17427   MPING (CONTROL_PING, mp_ping);
17428   S (mp_ping);
17429
17430   /* Wait for a reply... */
17431   W (ret);
17432   return ret;
17433 }
17434
17435 static int
17436 api_policer_classify_set_interface (vat_main_t * vam)
17437 {
17438   unformat_input_t *i = vam->input;
17439   vl_api_policer_classify_set_interface_t *mp;
17440   u32 sw_if_index;
17441   int sw_if_index_set;
17442   u32 ip4_table_index = ~0;
17443   u32 ip6_table_index = ~0;
17444   u32 l2_table_index = ~0;
17445   u8 is_add = 1;
17446   int ret;
17447
17448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17451         sw_if_index_set = 1;
17452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17453         sw_if_index_set = 1;
17454       else if (unformat (i, "del"))
17455         is_add = 0;
17456       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17457         ;
17458       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17459         ;
17460       else if (unformat (i, "l2-table %d", &l2_table_index))
17461         ;
17462       else
17463         {
17464           clib_warning ("parse error '%U'", format_unformat_error, i);
17465           return -99;
17466         }
17467     }
17468
17469   if (sw_if_index_set == 0)
17470     {
17471       errmsg ("missing interface name or sw_if_index");
17472       return -99;
17473     }
17474
17475   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17476
17477   mp->sw_if_index = ntohl (sw_if_index);
17478   mp->ip4_table_index = ntohl (ip4_table_index);
17479   mp->ip6_table_index = ntohl (ip6_table_index);
17480   mp->l2_table_index = ntohl (l2_table_index);
17481   mp->is_add = is_add;
17482
17483   S (mp);
17484   W (ret);
17485   return ret;
17486 }
17487
17488 static int
17489 api_policer_classify_dump (vat_main_t * vam)
17490 {
17491   unformat_input_t *i = vam->input;
17492   vl_api_policer_classify_dump_t *mp;
17493   vl_api_control_ping_t *mp_ping;
17494   u8 type = POLICER_CLASSIFY_N_TABLES;
17495   int ret;
17496
17497   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17498     ;
17499   else
17500     {
17501       errmsg ("classify table type must be specified");
17502       return -99;
17503     }
17504
17505   if (!vam->json_output)
17506     {
17507       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17508     }
17509
17510   M (POLICER_CLASSIFY_DUMP, mp);
17511   mp->type = type;
17512   /* send it... */
17513   S (mp);
17514
17515   /* Use a control ping for synchronization */
17516   MPING (CONTROL_PING, mp_ping);
17517   S (mp_ping);
17518
17519   /* Wait for a reply... */
17520   W (ret);
17521   return ret;
17522 }
17523
17524 static u8 *
17525 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17526 {
17527   vl_api_fib_path_nh_proto_t proto =
17528     va_arg (*args, vl_api_fib_path_nh_proto_t);
17529
17530   switch (proto)
17531     {
17532     case FIB_API_PATH_NH_PROTO_IP4:
17533       s = format (s, "ip4");
17534       break;
17535     case FIB_API_PATH_NH_PROTO_IP6:
17536       s = format (s, "ip6");
17537       break;
17538     case FIB_API_PATH_NH_PROTO_MPLS:
17539       s = format (s, "mpls");
17540       break;
17541     case FIB_API_PATH_NH_PROTO_BIER:
17542       s = format (s, "bier");
17543       break;
17544     case FIB_API_PATH_NH_PROTO_ETHERNET:
17545       s = format (s, "ethernet");
17546       break;
17547     }
17548
17549   return (s);
17550 }
17551
17552 static u8 *
17553 format_vl_api_ip_address_union (u8 * s, va_list * args)
17554 {
17555   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17556   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17557
17558   switch (af)
17559     {
17560     case ADDRESS_IP4:
17561       s = format (s, "%U", format_ip4_address, u->ip4);
17562       break;
17563     case ADDRESS_IP6:
17564       s = format (s, "%U", format_ip6_address, u->ip6);
17565       break;
17566     }
17567   return (s);
17568 }
17569
17570 static u8 *
17571 format_vl_api_fib_path_type (u8 * s, va_list * args)
17572 {
17573   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17574
17575   switch (t)
17576     {
17577     case FIB_API_PATH_TYPE_NORMAL:
17578       s = format (s, "normal");
17579       break;
17580     case FIB_API_PATH_TYPE_LOCAL:
17581       s = format (s, "local");
17582       break;
17583     case FIB_API_PATH_TYPE_DROP:
17584       s = format (s, "drop");
17585       break;
17586     case FIB_API_PATH_TYPE_UDP_ENCAP:
17587       s = format (s, "udp-encap");
17588       break;
17589     case FIB_API_PATH_TYPE_BIER_IMP:
17590       s = format (s, "bier-imp");
17591       break;
17592     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17593       s = format (s, "unreach");
17594       break;
17595     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17596       s = format (s, "prohibit");
17597       break;
17598     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17599       s = format (s, "src-lookup");
17600       break;
17601     case FIB_API_PATH_TYPE_DVR:
17602       s = format (s, "dvr");
17603       break;
17604     case FIB_API_PATH_TYPE_INTERFACE_RX:
17605       s = format (s, "interface-rx");
17606       break;
17607     case FIB_API_PATH_TYPE_CLASSIFY:
17608       s = format (s, "classify");
17609       break;
17610     }
17611
17612   return (s);
17613 }
17614
17615 static void
17616 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17617 {
17618   print (vam->ofp,
17619          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17620          ntohl (fp->weight), ntohl (fp->sw_if_index),
17621          format_vl_api_fib_path_type, fp->type,
17622          format_fib_api_path_nh_proto, fp->proto,
17623          format_vl_api_ip_address_union, &fp->nh.address);
17624 }
17625
17626 static void
17627 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17628                                  vl_api_fib_path_t * fp)
17629 {
17630   struct in_addr ip4;
17631   struct in6_addr ip6;
17632
17633   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17634   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17635   vat_json_object_add_uint (node, "type", fp->type);
17636   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17637   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17638     {
17639       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17640       vat_json_object_add_ip4 (node, "next_hop", ip4);
17641     }
17642   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17643     {
17644       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17645       vat_json_object_add_ip6 (node, "next_hop", ip6);
17646     }
17647 }
17648
17649 static void
17650 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17651 {
17652   vat_main_t *vam = &vat_main;
17653   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17654   vl_api_fib_path_t *fp;
17655   i32 i;
17656
17657   print (vam->ofp, "sw_if_index %d via:",
17658          ntohl (mp->mt_tunnel.mt_sw_if_index));
17659   fp = mp->mt_tunnel.mt_paths;
17660   for (i = 0; i < count; i++)
17661     {
17662       vl_api_fib_path_print (vam, fp);
17663       fp++;
17664     }
17665
17666   print (vam->ofp, "");
17667 }
17668
17669 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17670 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17671
17672 static void
17673 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17674 {
17675   vat_main_t *vam = &vat_main;
17676   vat_json_node_t *node = NULL;
17677   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17678   vl_api_fib_path_t *fp;
17679   i32 i;
17680
17681   if (VAT_JSON_ARRAY != vam->json_tree.type)
17682     {
17683       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17684       vat_json_init_array (&vam->json_tree);
17685     }
17686   node = vat_json_array_add (&vam->json_tree);
17687
17688   vat_json_init_object (node);
17689   vat_json_object_add_uint (node, "sw_if_index",
17690                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17691
17692   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17693
17694   fp = mp->mt_tunnel.mt_paths;
17695   for (i = 0; i < count; i++)
17696     {
17697       vl_api_mpls_fib_path_json_print (node, fp);
17698       fp++;
17699     }
17700 }
17701
17702 static int
17703 api_mpls_tunnel_dump (vat_main_t * vam)
17704 {
17705   vl_api_mpls_tunnel_dump_t *mp;
17706   vl_api_control_ping_t *mp_ping;
17707   int ret;
17708
17709   M (MPLS_TUNNEL_DUMP, mp);
17710
17711   S (mp);
17712
17713   /* Use a control ping for synchronization */
17714   MPING (CONTROL_PING, mp_ping);
17715   S (mp_ping);
17716
17717   W (ret);
17718   return ret;
17719 }
17720
17721 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17722 #define vl_api_mpls_table_details_t_print vl_noop_handler
17723
17724
17725 static void
17726 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17727 {
17728   vat_main_t *vam = &vat_main;
17729
17730   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17731 }
17732
17733 static void vl_api_mpls_table_details_t_handler_json
17734   (vl_api_mpls_table_details_t * mp)
17735 {
17736   vat_main_t *vam = &vat_main;
17737   vat_json_node_t *node = NULL;
17738
17739   if (VAT_JSON_ARRAY != vam->json_tree.type)
17740     {
17741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17742       vat_json_init_array (&vam->json_tree);
17743     }
17744   node = vat_json_array_add (&vam->json_tree);
17745
17746   vat_json_init_object (node);
17747   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17748 }
17749
17750 static int
17751 api_mpls_table_dump (vat_main_t * vam)
17752 {
17753   vl_api_mpls_table_dump_t *mp;
17754   vl_api_control_ping_t *mp_ping;
17755   int ret;
17756
17757   M (MPLS_TABLE_DUMP, mp);
17758   S (mp);
17759
17760   /* Use a control ping for synchronization */
17761   MPING (CONTROL_PING, mp_ping);
17762   S (mp_ping);
17763
17764   W (ret);
17765   return ret;
17766 }
17767
17768 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17769 #define vl_api_mpls_route_details_t_print vl_noop_handler
17770
17771 static void
17772 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17773 {
17774   vat_main_t *vam = &vat_main;
17775   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17776   vl_api_fib_path_t *fp;
17777   int i;
17778
17779   print (vam->ofp,
17780          "table-id %d, label %u, ess_bit %u",
17781          ntohl (mp->mr_route.mr_table_id),
17782          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17783   fp = mp->mr_route.mr_paths;
17784   for (i = 0; i < count; i++)
17785     {
17786       vl_api_fib_path_print (vam, fp);
17787       fp++;
17788     }
17789 }
17790
17791 static void vl_api_mpls_route_details_t_handler_json
17792   (vl_api_mpls_route_details_t * mp)
17793 {
17794   vat_main_t *vam = &vat_main;
17795   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17796   vat_json_node_t *node = NULL;
17797   vl_api_fib_path_t *fp;
17798   int i;
17799
17800   if (VAT_JSON_ARRAY != vam->json_tree.type)
17801     {
17802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17803       vat_json_init_array (&vam->json_tree);
17804     }
17805   node = vat_json_array_add (&vam->json_tree);
17806
17807   vat_json_init_object (node);
17808   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17809   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17810   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17811   vat_json_object_add_uint (node, "path_count", count);
17812   fp = mp->mr_route.mr_paths;
17813   for (i = 0; i < count; i++)
17814     {
17815       vl_api_mpls_fib_path_json_print (node, fp);
17816       fp++;
17817     }
17818 }
17819
17820 static int
17821 api_mpls_route_dump (vat_main_t * vam)
17822 {
17823   unformat_input_t *input = vam->input;
17824   vl_api_mpls_route_dump_t *mp;
17825   vl_api_control_ping_t *mp_ping;
17826   u32 table_id;
17827   int ret;
17828
17829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17830     {
17831       if (unformat (input, "table_id %d", &table_id))
17832         ;
17833       else
17834         break;
17835     }
17836   if (table_id == ~0)
17837     {
17838       errmsg ("missing table id");
17839       return -99;
17840     }
17841
17842   M (MPLS_ROUTE_DUMP, mp);
17843
17844   mp->table.mt_table_id = ntohl (table_id);
17845   S (mp);
17846
17847   /* Use a control ping for synchronization */
17848   MPING (CONTROL_PING, mp_ping);
17849   S (mp_ping);
17850
17851   W (ret);
17852   return ret;
17853 }
17854
17855 #define vl_api_ip_table_details_t_endian vl_noop_handler
17856 #define vl_api_ip_table_details_t_print vl_noop_handler
17857
17858 static void
17859 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17860 {
17861   vat_main_t *vam = &vat_main;
17862
17863   print (vam->ofp,
17864          "%s; table-id %d, prefix %U/%d",
17865          mp->table.name, ntohl (mp->table.table_id));
17866 }
17867
17868
17869 static void vl_api_ip_table_details_t_handler_json
17870   (vl_api_ip_table_details_t * mp)
17871 {
17872   vat_main_t *vam = &vat_main;
17873   vat_json_node_t *node = NULL;
17874
17875   if (VAT_JSON_ARRAY != vam->json_tree.type)
17876     {
17877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17878       vat_json_init_array (&vam->json_tree);
17879     }
17880   node = vat_json_array_add (&vam->json_tree);
17881
17882   vat_json_init_object (node);
17883   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17884 }
17885
17886 static int
17887 api_ip_table_dump (vat_main_t * vam)
17888 {
17889   vl_api_ip_table_dump_t *mp;
17890   vl_api_control_ping_t *mp_ping;
17891   int ret;
17892
17893   M (IP_TABLE_DUMP, mp);
17894   S (mp);
17895
17896   /* Use a control ping for synchronization */
17897   MPING (CONTROL_PING, mp_ping);
17898   S (mp_ping);
17899
17900   W (ret);
17901   return ret;
17902 }
17903
17904 static int
17905 api_ip_mtable_dump (vat_main_t * vam)
17906 {
17907   vl_api_ip_mtable_dump_t *mp;
17908   vl_api_control_ping_t *mp_ping;
17909   int ret;
17910
17911   M (IP_MTABLE_DUMP, mp);
17912   S (mp);
17913
17914   /* Use a control ping for synchronization */
17915   MPING (CONTROL_PING, mp_ping);
17916   S (mp_ping);
17917
17918   W (ret);
17919   return ret;
17920 }
17921
17922 static int
17923 api_ip_mroute_dump (vat_main_t * vam)
17924 {
17925   unformat_input_t *input = vam->input;
17926   vl_api_control_ping_t *mp_ping;
17927   vl_api_ip_mroute_dump_t *mp;
17928   int ret, is_ip6;
17929   u32 table_id;
17930
17931   is_ip6 = 0;
17932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17933     {
17934       if (unformat (input, "table_id %d", &table_id))
17935         ;
17936       else if (unformat (input, "ip6"))
17937         is_ip6 = 1;
17938       else if (unformat (input, "ip4"))
17939         is_ip6 = 0;
17940       else
17941         break;
17942     }
17943   if (table_id == ~0)
17944     {
17945       errmsg ("missing table id");
17946       return -99;
17947     }
17948
17949   M (IP_MROUTE_DUMP, mp);
17950   mp->table.table_id = table_id;
17951   mp->table.is_ip6 = is_ip6;
17952   S (mp);
17953
17954   /* Use a control ping for synchronization */
17955   MPING (CONTROL_PING, mp_ping);
17956   S (mp_ping);
17957
17958   W (ret);
17959   return ret;
17960 }
17961
17962 #define vl_api_ip_route_details_t_endian vl_noop_handler
17963 #define vl_api_ip_route_details_t_print vl_noop_handler
17964
17965 static void
17966 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17967 {
17968   vat_main_t *vam = &vat_main;
17969   u8 count = mp->route.n_paths;
17970   vl_api_fib_path_t *fp;
17971   int i;
17972
17973   print (vam->ofp,
17974          "table-id %d, prefix %U/%d",
17975          ntohl (mp->route.table_id),
17976          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17977   for (i = 0; i < count; i++)
17978     {
17979       fp = &mp->route.paths[i];
17980
17981       vl_api_fib_path_print (vam, fp);
17982       fp++;
17983     }
17984 }
17985
17986 static void vl_api_ip_route_details_t_handler_json
17987   (vl_api_ip_route_details_t * mp)
17988 {
17989   vat_main_t *vam = &vat_main;
17990   u8 count = mp->route.n_paths;
17991   vat_json_node_t *node = NULL;
17992   struct in_addr ip4;
17993   struct in6_addr ip6;
17994   vl_api_fib_path_t *fp;
17995   int i;
17996
17997   if (VAT_JSON_ARRAY != vam->json_tree.type)
17998     {
17999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18000       vat_json_init_array (&vam->json_tree);
18001     }
18002   node = vat_json_array_add (&vam->json_tree);
18003
18004   vat_json_init_object (node);
18005   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18006   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18007     {
18008       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18009       vat_json_object_add_ip6 (node, "prefix", ip6);
18010     }
18011   else
18012     {
18013       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18014       vat_json_object_add_ip4 (node, "prefix", ip4);
18015     }
18016   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18017   vat_json_object_add_uint (node, "path_count", count);
18018   for (i = 0; i < count; i++)
18019     {
18020       fp = &mp->route.paths[i];
18021       vl_api_mpls_fib_path_json_print (node, fp);
18022     }
18023 }
18024
18025 static int
18026 api_ip_route_dump (vat_main_t * vam)
18027 {
18028   unformat_input_t *input = vam->input;
18029   vl_api_ip_route_dump_t *mp;
18030   vl_api_control_ping_t *mp_ping;
18031   u32 table_id;
18032   u8 is_ip6;
18033   int ret;
18034
18035   is_ip6 = 0;
18036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18037     {
18038       if (unformat (input, "table_id %d", &table_id))
18039         ;
18040       else if (unformat (input, "ip6"))
18041         is_ip6 = 1;
18042       else if (unformat (input, "ip4"))
18043         is_ip6 = 0;
18044       else
18045         break;
18046     }
18047   if (table_id == ~0)
18048     {
18049       errmsg ("missing table id");
18050       return -99;
18051     }
18052
18053   M (IP_ROUTE_DUMP, mp);
18054
18055   mp->table.table_id = table_id;
18056   mp->table.is_ip6 = is_ip6;
18057
18058   S (mp);
18059
18060   /* Use a control ping for synchronization */
18061   MPING (CONTROL_PING, mp_ping);
18062   S (mp_ping);
18063
18064   W (ret);
18065   return ret;
18066 }
18067
18068 int
18069 api_classify_table_ids (vat_main_t * vam)
18070 {
18071   vl_api_classify_table_ids_t *mp;
18072   int ret;
18073
18074   /* Construct the API message */
18075   M (CLASSIFY_TABLE_IDS, mp);
18076   mp->context = 0;
18077
18078   S (mp);
18079   W (ret);
18080   return ret;
18081 }
18082
18083 int
18084 api_classify_table_by_interface (vat_main_t * vam)
18085 {
18086   unformat_input_t *input = vam->input;
18087   vl_api_classify_table_by_interface_t *mp;
18088
18089   u32 sw_if_index = ~0;
18090   int ret;
18091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18092     {
18093       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18094         ;
18095       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18096         ;
18097       else
18098         break;
18099     }
18100   if (sw_if_index == ~0)
18101     {
18102       errmsg ("missing interface name or sw_if_index");
18103       return -99;
18104     }
18105
18106   /* Construct the API message */
18107   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18108   mp->context = 0;
18109   mp->sw_if_index = ntohl (sw_if_index);
18110
18111   S (mp);
18112   W (ret);
18113   return ret;
18114 }
18115
18116 int
18117 api_classify_table_info (vat_main_t * vam)
18118 {
18119   unformat_input_t *input = vam->input;
18120   vl_api_classify_table_info_t *mp;
18121
18122   u32 table_id = ~0;
18123   int ret;
18124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18125     {
18126       if (unformat (input, "table_id %d", &table_id))
18127         ;
18128       else
18129         break;
18130     }
18131   if (table_id == ~0)
18132     {
18133       errmsg ("missing table id");
18134       return -99;
18135     }
18136
18137   /* Construct the API message */
18138   M (CLASSIFY_TABLE_INFO, mp);
18139   mp->context = 0;
18140   mp->table_id = ntohl (table_id);
18141
18142   S (mp);
18143   W (ret);
18144   return ret;
18145 }
18146
18147 int
18148 api_classify_session_dump (vat_main_t * vam)
18149 {
18150   unformat_input_t *input = vam->input;
18151   vl_api_classify_session_dump_t *mp;
18152   vl_api_control_ping_t *mp_ping;
18153
18154   u32 table_id = ~0;
18155   int ret;
18156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18157     {
18158       if (unformat (input, "table_id %d", &table_id))
18159         ;
18160       else
18161         break;
18162     }
18163   if (table_id == ~0)
18164     {
18165       errmsg ("missing table id");
18166       return -99;
18167     }
18168
18169   /* Construct the API message */
18170   M (CLASSIFY_SESSION_DUMP, mp);
18171   mp->context = 0;
18172   mp->table_id = ntohl (table_id);
18173   S (mp);
18174
18175   /* Use a control ping for synchronization */
18176   MPING (CONTROL_PING, mp_ping);
18177   S (mp_ping);
18178
18179   W (ret);
18180   return ret;
18181 }
18182
18183 static void
18184 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18185 {
18186   vat_main_t *vam = &vat_main;
18187
18188   print (vam->ofp, "collector_address %U, collector_port %d, "
18189          "src_address %U, vrf_id %d, path_mtu %u, "
18190          "template_interval %u, udp_checksum %d",
18191          format_ip4_address, mp->collector_address,
18192          ntohs (mp->collector_port),
18193          format_ip4_address, mp->src_address,
18194          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18195          ntohl (mp->template_interval), mp->udp_checksum);
18196
18197   vam->retval = 0;
18198   vam->result_ready = 1;
18199 }
18200
18201 static void
18202   vl_api_ipfix_exporter_details_t_handler_json
18203   (vl_api_ipfix_exporter_details_t * mp)
18204 {
18205   vat_main_t *vam = &vat_main;
18206   vat_json_node_t node;
18207   struct in_addr collector_address;
18208   struct in_addr src_address;
18209
18210   vat_json_init_object (&node);
18211   clib_memcpy (&collector_address, &mp->collector_address,
18212                sizeof (collector_address));
18213   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18214   vat_json_object_add_uint (&node, "collector_port",
18215                             ntohs (mp->collector_port));
18216   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18217   vat_json_object_add_ip4 (&node, "src_address", src_address);
18218   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18219   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18220   vat_json_object_add_uint (&node, "template_interval",
18221                             ntohl (mp->template_interval));
18222   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18223
18224   vat_json_print (vam->ofp, &node);
18225   vat_json_free (&node);
18226   vam->retval = 0;
18227   vam->result_ready = 1;
18228 }
18229
18230 int
18231 api_ipfix_exporter_dump (vat_main_t * vam)
18232 {
18233   vl_api_ipfix_exporter_dump_t *mp;
18234   int ret;
18235
18236   /* Construct the API message */
18237   M (IPFIX_EXPORTER_DUMP, mp);
18238   mp->context = 0;
18239
18240   S (mp);
18241   W (ret);
18242   return ret;
18243 }
18244
18245 static int
18246 api_ipfix_classify_stream_dump (vat_main_t * vam)
18247 {
18248   vl_api_ipfix_classify_stream_dump_t *mp;
18249   int ret;
18250
18251   /* Construct the API message */
18252   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18253   mp->context = 0;
18254
18255   S (mp);
18256   W (ret);
18257   return ret;
18258   /* NOTREACHED */
18259   return 0;
18260 }
18261
18262 static void
18263   vl_api_ipfix_classify_stream_details_t_handler
18264   (vl_api_ipfix_classify_stream_details_t * mp)
18265 {
18266   vat_main_t *vam = &vat_main;
18267   print (vam->ofp, "domain_id %d, src_port %d",
18268          ntohl (mp->domain_id), ntohs (mp->src_port));
18269   vam->retval = 0;
18270   vam->result_ready = 1;
18271 }
18272
18273 static void
18274   vl_api_ipfix_classify_stream_details_t_handler_json
18275   (vl_api_ipfix_classify_stream_details_t * mp)
18276 {
18277   vat_main_t *vam = &vat_main;
18278   vat_json_node_t node;
18279
18280   vat_json_init_object (&node);
18281   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18282   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18283
18284   vat_json_print (vam->ofp, &node);
18285   vat_json_free (&node);
18286   vam->retval = 0;
18287   vam->result_ready = 1;
18288 }
18289
18290 static int
18291 api_ipfix_classify_table_dump (vat_main_t * vam)
18292 {
18293   vl_api_ipfix_classify_table_dump_t *mp;
18294   vl_api_control_ping_t *mp_ping;
18295   int ret;
18296
18297   if (!vam->json_output)
18298     {
18299       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18300              "transport_protocol");
18301     }
18302
18303   /* Construct the API message */
18304   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18305
18306   /* send it... */
18307   S (mp);
18308
18309   /* Use a control ping for synchronization */
18310   MPING (CONTROL_PING, mp_ping);
18311   S (mp_ping);
18312
18313   W (ret);
18314   return ret;
18315 }
18316
18317 static void
18318   vl_api_ipfix_classify_table_details_t_handler
18319   (vl_api_ipfix_classify_table_details_t * mp)
18320 {
18321   vat_main_t *vam = &vat_main;
18322   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18323          mp->transport_protocol);
18324 }
18325
18326 static void
18327   vl_api_ipfix_classify_table_details_t_handler_json
18328   (vl_api_ipfix_classify_table_details_t * mp)
18329 {
18330   vat_json_node_t *node = NULL;
18331   vat_main_t *vam = &vat_main;
18332
18333   if (VAT_JSON_ARRAY != vam->json_tree.type)
18334     {
18335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18336       vat_json_init_array (&vam->json_tree);
18337     }
18338
18339   node = vat_json_array_add (&vam->json_tree);
18340   vat_json_init_object (node);
18341
18342   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18343   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18344   vat_json_object_add_uint (node, "transport_protocol",
18345                             mp->transport_protocol);
18346 }
18347
18348 static int
18349 api_sw_interface_span_enable_disable (vat_main_t * vam)
18350 {
18351   unformat_input_t *i = vam->input;
18352   vl_api_sw_interface_span_enable_disable_t *mp;
18353   u32 src_sw_if_index = ~0;
18354   u32 dst_sw_if_index = ~0;
18355   u8 state = 3;
18356   int ret;
18357   u8 is_l2 = 0;
18358
18359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18360     {
18361       if (unformat
18362           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18363         ;
18364       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18365         ;
18366       else
18367         if (unformat
18368             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18369         ;
18370       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18371         ;
18372       else if (unformat (i, "disable"))
18373         state = 0;
18374       else if (unformat (i, "rx"))
18375         state = 1;
18376       else if (unformat (i, "tx"))
18377         state = 2;
18378       else if (unformat (i, "both"))
18379         state = 3;
18380       else if (unformat (i, "l2"))
18381         is_l2 = 1;
18382       else
18383         break;
18384     }
18385
18386   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18387
18388   mp->sw_if_index_from = htonl (src_sw_if_index);
18389   mp->sw_if_index_to = htonl (dst_sw_if_index);
18390   mp->state = state;
18391   mp->is_l2 = is_l2;
18392
18393   S (mp);
18394   W (ret);
18395   return ret;
18396 }
18397
18398 static void
18399 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18400                                             * mp)
18401 {
18402   vat_main_t *vam = &vat_main;
18403   u8 *sw_if_from_name = 0;
18404   u8 *sw_if_to_name = 0;
18405   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18406   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18407   char *states[] = { "none", "rx", "tx", "both" };
18408   hash_pair_t *p;
18409
18410   /* *INDENT-OFF* */
18411   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18412   ({
18413     if ((u32) p->value[0] == sw_if_index_from)
18414       {
18415         sw_if_from_name = (u8 *)(p->key);
18416         if (sw_if_to_name)
18417           break;
18418       }
18419     if ((u32) p->value[0] == sw_if_index_to)
18420       {
18421         sw_if_to_name = (u8 *)(p->key);
18422         if (sw_if_from_name)
18423           break;
18424       }
18425   }));
18426   /* *INDENT-ON* */
18427   print (vam->ofp, "%20s => %20s (%s) %s",
18428          sw_if_from_name, sw_if_to_name, states[mp->state],
18429          mp->is_l2 ? "l2" : "device");
18430 }
18431
18432 static void
18433   vl_api_sw_interface_span_details_t_handler_json
18434   (vl_api_sw_interface_span_details_t * mp)
18435 {
18436   vat_main_t *vam = &vat_main;
18437   vat_json_node_t *node = NULL;
18438   u8 *sw_if_from_name = 0;
18439   u8 *sw_if_to_name = 0;
18440   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18441   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18442   hash_pair_t *p;
18443
18444   /* *INDENT-OFF* */
18445   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18446   ({
18447     if ((u32) p->value[0] == sw_if_index_from)
18448       {
18449         sw_if_from_name = (u8 *)(p->key);
18450         if (sw_if_to_name)
18451           break;
18452       }
18453     if ((u32) p->value[0] == sw_if_index_to)
18454       {
18455         sw_if_to_name = (u8 *)(p->key);
18456         if (sw_if_from_name)
18457           break;
18458       }
18459   }));
18460   /* *INDENT-ON* */
18461
18462   if (VAT_JSON_ARRAY != vam->json_tree.type)
18463     {
18464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18465       vat_json_init_array (&vam->json_tree);
18466     }
18467   node = vat_json_array_add (&vam->json_tree);
18468
18469   vat_json_init_object (node);
18470   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18471   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18472   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18473   if (0 != sw_if_to_name)
18474     {
18475       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18476     }
18477   vat_json_object_add_uint (node, "state", mp->state);
18478   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18479 }
18480
18481 static int
18482 api_sw_interface_span_dump (vat_main_t * vam)
18483 {
18484   unformat_input_t *input = vam->input;
18485   vl_api_sw_interface_span_dump_t *mp;
18486   vl_api_control_ping_t *mp_ping;
18487   u8 is_l2 = 0;
18488   int ret;
18489
18490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18491     {
18492       if (unformat (input, "l2"))
18493         is_l2 = 1;
18494       else
18495         break;
18496     }
18497
18498   M (SW_INTERFACE_SPAN_DUMP, mp);
18499   mp->is_l2 = is_l2;
18500   S (mp);
18501
18502   /* Use a control ping for synchronization */
18503   MPING (CONTROL_PING, mp_ping);
18504   S (mp_ping);
18505
18506   W (ret);
18507   return ret;
18508 }
18509
18510 int
18511 api_pg_create_interface (vat_main_t * vam)
18512 {
18513   unformat_input_t *input = vam->input;
18514   vl_api_pg_create_interface_t *mp;
18515
18516   u32 if_id = ~0, gso_size = 0;
18517   u8 gso_enabled = 0;
18518   int ret;
18519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (input, "if_id %d", &if_id))
18522         ;
18523       else if (unformat (input, "gso-enabled"))
18524         {
18525           gso_enabled = 1;
18526           if (unformat (input, "gso-size %u", &gso_size))
18527             ;
18528           else
18529             {
18530               errmsg ("missing gso-size");
18531               return -99;
18532             }
18533         }
18534       else
18535         break;
18536     }
18537   if (if_id == ~0)
18538     {
18539       errmsg ("missing pg interface index");
18540       return -99;
18541     }
18542
18543   /* Construct the API message */
18544   M (PG_CREATE_INTERFACE, mp);
18545   mp->context = 0;
18546   mp->interface_id = ntohl (if_id);
18547   mp->gso_enabled = gso_enabled;
18548
18549   S (mp);
18550   W (ret);
18551   return ret;
18552 }
18553
18554 int
18555 api_pg_capture (vat_main_t * vam)
18556 {
18557   unformat_input_t *input = vam->input;
18558   vl_api_pg_capture_t *mp;
18559
18560   u32 if_id = ~0;
18561   u8 enable = 1;
18562   u32 count = 1;
18563   u8 pcap_file_set = 0;
18564   u8 *pcap_file = 0;
18565   int ret;
18566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18567     {
18568       if (unformat (input, "if_id %d", &if_id))
18569         ;
18570       else if (unformat (input, "pcap %s", &pcap_file))
18571         pcap_file_set = 1;
18572       else if (unformat (input, "count %d", &count))
18573         ;
18574       else if (unformat (input, "disable"))
18575         enable = 0;
18576       else
18577         break;
18578     }
18579   if (if_id == ~0)
18580     {
18581       errmsg ("missing pg interface index");
18582       return -99;
18583     }
18584   if (pcap_file_set > 0)
18585     {
18586       if (vec_len (pcap_file) > 255)
18587         {
18588           errmsg ("pcap file name is too long");
18589           return -99;
18590         }
18591     }
18592
18593   /* Construct the API message */
18594   M (PG_CAPTURE, mp);
18595   mp->context = 0;
18596   mp->interface_id = ntohl (if_id);
18597   mp->is_enabled = enable;
18598   mp->count = ntohl (count);
18599   if (pcap_file_set != 0)
18600     {
18601       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18602     }
18603   vec_free (pcap_file);
18604
18605   S (mp);
18606   W (ret);
18607   return ret;
18608 }
18609
18610 int
18611 api_pg_enable_disable (vat_main_t * vam)
18612 {
18613   unformat_input_t *input = vam->input;
18614   vl_api_pg_enable_disable_t *mp;
18615
18616   u8 enable = 1;
18617   u8 stream_name_set = 0;
18618   u8 *stream_name = 0;
18619   int ret;
18620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18621     {
18622       if (unformat (input, "stream %s", &stream_name))
18623         stream_name_set = 1;
18624       else if (unformat (input, "disable"))
18625         enable = 0;
18626       else
18627         break;
18628     }
18629
18630   if (stream_name_set > 0)
18631     {
18632       if (vec_len (stream_name) > 255)
18633         {
18634           errmsg ("stream name too long");
18635           return -99;
18636         }
18637     }
18638
18639   /* Construct the API message */
18640   M (PG_ENABLE_DISABLE, mp);
18641   mp->context = 0;
18642   mp->is_enabled = enable;
18643   if (stream_name_set != 0)
18644     {
18645       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18646     }
18647   vec_free (stream_name);
18648
18649   S (mp);
18650   W (ret);
18651   return ret;
18652 }
18653
18654 int
18655 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18656 {
18657   unformat_input_t *input = vam->input;
18658   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18659
18660   u16 *low_ports = 0;
18661   u16 *high_ports = 0;
18662   u16 this_low;
18663   u16 this_hi;
18664   vl_api_prefix_t prefix;
18665   u32 tmp, tmp2;
18666   u8 prefix_set = 0;
18667   u32 vrf_id = ~0;
18668   u8 is_add = 1;
18669   int ret;
18670
18671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18672     {
18673       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18674         prefix_set = 1;
18675       else if (unformat (input, "vrf %d", &vrf_id))
18676         ;
18677       else if (unformat (input, "del"))
18678         is_add = 0;
18679       else if (unformat (input, "port %d", &tmp))
18680         {
18681           if (tmp == 0 || tmp > 65535)
18682             {
18683               errmsg ("port %d out of range", tmp);
18684               return -99;
18685             }
18686           this_low = tmp;
18687           this_hi = this_low + 1;
18688           vec_add1 (low_ports, this_low);
18689           vec_add1 (high_ports, this_hi);
18690         }
18691       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18692         {
18693           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18694             {
18695               errmsg ("incorrect range parameters");
18696               return -99;
18697             }
18698           this_low = tmp;
18699           /* Note: in debug CLI +1 is added to high before
18700              passing to real fn that does "the work"
18701              (ip_source_and_port_range_check_add_del).
18702              This fn is a wrapper around the binary API fn a
18703              control plane will call, which expects this increment
18704              to have occurred. Hence letting the binary API control
18705              plane fn do the increment for consistency between VAT
18706              and other control planes.
18707            */
18708           this_hi = tmp2;
18709           vec_add1 (low_ports, this_low);
18710           vec_add1 (high_ports, this_hi);
18711         }
18712       else
18713         break;
18714     }
18715
18716   if (prefix_set == 0)
18717     {
18718       errmsg ("<address>/<mask> not specified");
18719       return -99;
18720     }
18721
18722   if (vrf_id == ~0)
18723     {
18724       errmsg ("VRF ID required, not specified");
18725       return -99;
18726     }
18727
18728   if (vrf_id == 0)
18729     {
18730       errmsg
18731         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18732       return -99;
18733     }
18734
18735   if (vec_len (low_ports) == 0)
18736     {
18737       errmsg ("At least one port or port range required");
18738       return -99;
18739     }
18740
18741   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18742
18743   mp->is_add = is_add;
18744
18745   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18746
18747   mp->number_of_ranges = vec_len (low_ports);
18748
18749   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18750   vec_free (low_ports);
18751
18752   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18753   vec_free (high_ports);
18754
18755   mp->vrf_id = ntohl (vrf_id);
18756
18757   S (mp);
18758   W (ret);
18759   return ret;
18760 }
18761
18762 int
18763 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18764 {
18765   unformat_input_t *input = vam->input;
18766   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18767   u32 sw_if_index = ~0;
18768   int vrf_set = 0;
18769   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18770   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18771   u8 is_add = 1;
18772   int ret;
18773
18774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18775     {
18776       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18777         ;
18778       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18779         ;
18780       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18781         vrf_set = 1;
18782       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18783         vrf_set = 1;
18784       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18785         vrf_set = 1;
18786       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18787         vrf_set = 1;
18788       else if (unformat (input, "del"))
18789         is_add = 0;
18790       else
18791         break;
18792     }
18793
18794   if (sw_if_index == ~0)
18795     {
18796       errmsg ("Interface required but not specified");
18797       return -99;
18798     }
18799
18800   if (vrf_set == 0)
18801     {
18802       errmsg ("VRF ID required but not specified");
18803       return -99;
18804     }
18805
18806   if (tcp_out_vrf_id == 0
18807       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18808     {
18809       errmsg
18810         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18811       return -99;
18812     }
18813
18814   /* Construct the API message */
18815   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18816
18817   mp->sw_if_index = ntohl (sw_if_index);
18818   mp->is_add = is_add;
18819   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18820   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18821   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18822   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18823
18824   /* send it... */
18825   S (mp);
18826
18827   /* Wait for a reply... */
18828   W (ret);
18829   return ret;
18830 }
18831
18832 static int
18833 api_set_punt (vat_main_t * vam)
18834 {
18835   unformat_input_t *i = vam->input;
18836   vl_api_address_family_t af;
18837   vl_api_set_punt_t *mp;
18838   u32 protocol = ~0;
18839   u32 port = ~0;
18840   int is_add = 1;
18841   int ret;
18842
18843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18844     {
18845       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18846         ;
18847       else if (unformat (i, "protocol %d", &protocol))
18848         ;
18849       else if (unformat (i, "port %d", &port))
18850         ;
18851       else if (unformat (i, "del"))
18852         is_add = 0;
18853       else
18854         {
18855           clib_warning ("parse error '%U'", format_unformat_error, i);
18856           return -99;
18857         }
18858     }
18859
18860   M (SET_PUNT, mp);
18861
18862   mp->is_add = (u8) is_add;
18863   mp->punt.type = PUNT_API_TYPE_L4;
18864   mp->punt.punt.l4.af = af;
18865   mp->punt.punt.l4.protocol = (u8) protocol;
18866   mp->punt.punt.l4.port = htons ((u16) port);
18867
18868   S (mp);
18869   W (ret);
18870   return ret;
18871 }
18872
18873 static int
18874 api_delete_subif (vat_main_t * vam)
18875 {
18876   unformat_input_t *i = vam->input;
18877   vl_api_delete_subif_t *mp;
18878   u32 sw_if_index = ~0;
18879   int ret;
18880
18881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18882     {
18883       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18884         ;
18885       if (unformat (i, "sw_if_index %d", &sw_if_index))
18886         ;
18887       else
18888         break;
18889     }
18890
18891   if (sw_if_index == ~0)
18892     {
18893       errmsg ("missing sw_if_index");
18894       return -99;
18895     }
18896
18897   /* Construct the API message */
18898   M (DELETE_SUBIF, mp);
18899   mp->sw_if_index = ntohl (sw_if_index);
18900
18901   S (mp);
18902   W (ret);
18903   return ret;
18904 }
18905
18906 #define foreach_pbb_vtr_op      \
18907 _("disable",  L2_VTR_DISABLED)  \
18908 _("pop",  L2_VTR_POP_2)         \
18909 _("push",  L2_VTR_PUSH_2)
18910
18911 static int
18912 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18913 {
18914   unformat_input_t *i = vam->input;
18915   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18916   u32 sw_if_index = ~0, vtr_op = ~0;
18917   u16 outer_tag = ~0;
18918   u8 dmac[6], smac[6];
18919   u8 dmac_set = 0, smac_set = 0;
18920   u16 vlanid = 0;
18921   u32 sid = ~0;
18922   u32 tmp;
18923   int ret;
18924
18925   /* Shut up coverity */
18926   clib_memset (dmac, 0, sizeof (dmac));
18927   clib_memset (smac, 0, sizeof (smac));
18928
18929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18930     {
18931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18932         ;
18933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18934         ;
18935       else if (unformat (i, "vtr_op %d", &vtr_op))
18936         ;
18937 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18938       foreach_pbb_vtr_op
18939 #undef _
18940         else if (unformat (i, "translate_pbb_stag"))
18941         {
18942           if (unformat (i, "%d", &tmp))
18943             {
18944               vtr_op = L2_VTR_TRANSLATE_2_1;
18945               outer_tag = tmp;
18946             }
18947           else
18948             {
18949               errmsg
18950                 ("translate_pbb_stag operation requires outer tag definition");
18951               return -99;
18952             }
18953         }
18954       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18955         dmac_set++;
18956       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18957         smac_set++;
18958       else if (unformat (i, "sid %d", &sid))
18959         ;
18960       else if (unformat (i, "vlanid %d", &tmp))
18961         vlanid = tmp;
18962       else
18963         {
18964           clib_warning ("parse error '%U'", format_unformat_error, i);
18965           return -99;
18966         }
18967     }
18968
18969   if ((sw_if_index == ~0) || (vtr_op == ~0))
18970     {
18971       errmsg ("missing sw_if_index or vtr operation");
18972       return -99;
18973     }
18974   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18975       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18976     {
18977       errmsg
18978         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18979       return -99;
18980     }
18981
18982   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18983   mp->sw_if_index = ntohl (sw_if_index);
18984   mp->vtr_op = ntohl (vtr_op);
18985   mp->outer_tag = ntohs (outer_tag);
18986   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18987   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18988   mp->b_vlanid = ntohs (vlanid);
18989   mp->i_sid = ntohl (sid);
18990
18991   S (mp);
18992   W (ret);
18993   return ret;
18994 }
18995
18996 static int
18997 api_flow_classify_set_interface (vat_main_t * vam)
18998 {
18999   unformat_input_t *i = vam->input;
19000   vl_api_flow_classify_set_interface_t *mp;
19001   u32 sw_if_index;
19002   int sw_if_index_set;
19003   u32 ip4_table_index = ~0;
19004   u32 ip6_table_index = ~0;
19005   u8 is_add = 1;
19006   int ret;
19007
19008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19009     {
19010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19011         sw_if_index_set = 1;
19012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19013         sw_if_index_set = 1;
19014       else if (unformat (i, "del"))
19015         is_add = 0;
19016       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19017         ;
19018       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19019         ;
19020       else
19021         {
19022           clib_warning ("parse error '%U'", format_unformat_error, i);
19023           return -99;
19024         }
19025     }
19026
19027   if (sw_if_index_set == 0)
19028     {
19029       errmsg ("missing interface name or sw_if_index");
19030       return -99;
19031     }
19032
19033   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19034
19035   mp->sw_if_index = ntohl (sw_if_index);
19036   mp->ip4_table_index = ntohl (ip4_table_index);
19037   mp->ip6_table_index = ntohl (ip6_table_index);
19038   mp->is_add = is_add;
19039
19040   S (mp);
19041   W (ret);
19042   return ret;
19043 }
19044
19045 static int
19046 api_flow_classify_dump (vat_main_t * vam)
19047 {
19048   unformat_input_t *i = vam->input;
19049   vl_api_flow_classify_dump_t *mp;
19050   vl_api_control_ping_t *mp_ping;
19051   u8 type = FLOW_CLASSIFY_N_TABLES;
19052   int ret;
19053
19054   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19055     ;
19056   else
19057     {
19058       errmsg ("classify table type must be specified");
19059       return -99;
19060     }
19061
19062   if (!vam->json_output)
19063     {
19064       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19065     }
19066
19067   M (FLOW_CLASSIFY_DUMP, mp);
19068   mp->type = type;
19069   /* send it... */
19070   S (mp);
19071
19072   /* Use a control ping for synchronization */
19073   MPING (CONTROL_PING, mp_ping);
19074   S (mp_ping);
19075
19076   /* Wait for a reply... */
19077   W (ret);
19078   return ret;
19079 }
19080
19081 static int
19082 api_feature_enable_disable (vat_main_t * vam)
19083 {
19084   unformat_input_t *i = vam->input;
19085   vl_api_feature_enable_disable_t *mp;
19086   u8 *arc_name = 0;
19087   u8 *feature_name = 0;
19088   u32 sw_if_index = ~0;
19089   u8 enable = 1;
19090   int ret;
19091
19092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19093     {
19094       if (unformat (i, "arc_name %s", &arc_name))
19095         ;
19096       else if (unformat (i, "feature_name %s", &feature_name))
19097         ;
19098       else
19099         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19100         ;
19101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19102         ;
19103       else if (unformat (i, "disable"))
19104         enable = 0;
19105       else
19106         break;
19107     }
19108
19109   if (arc_name == 0)
19110     {
19111       errmsg ("missing arc name");
19112       return -99;
19113     }
19114   if (vec_len (arc_name) > 63)
19115     {
19116       errmsg ("arc name too long");
19117     }
19118
19119   if (feature_name == 0)
19120     {
19121       errmsg ("missing feature name");
19122       return -99;
19123     }
19124   if (vec_len (feature_name) > 63)
19125     {
19126       errmsg ("feature name too long");
19127     }
19128
19129   if (sw_if_index == ~0)
19130     {
19131       errmsg ("missing interface name or sw_if_index");
19132       return -99;
19133     }
19134
19135   /* Construct the API message */
19136   M (FEATURE_ENABLE_DISABLE, mp);
19137   mp->sw_if_index = ntohl (sw_if_index);
19138   mp->enable = enable;
19139   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19140   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19141   vec_free (arc_name);
19142   vec_free (feature_name);
19143
19144   S (mp);
19145   W (ret);
19146   return ret;
19147 }
19148
19149 static int
19150 api_feature_gso_enable_disable (vat_main_t * vam)
19151 {
19152   unformat_input_t *i = vam->input;
19153   vl_api_feature_gso_enable_disable_t *mp;
19154   u32 sw_if_index = ~0;
19155   u8 enable = 1;
19156   int ret;
19157
19158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19159     {
19160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19161         ;
19162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19163         ;
19164       else if (unformat (i, "enable"))
19165         enable = 1;
19166       else if (unformat (i, "disable"))
19167         enable = 0;
19168       else
19169         break;
19170     }
19171
19172   if (sw_if_index == ~0)
19173     {
19174       errmsg ("missing interface name or sw_if_index");
19175       return -99;
19176     }
19177
19178   /* Construct the API message */
19179   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19180   mp->sw_if_index = ntohl (sw_if_index);
19181   mp->enable_disable = enable;
19182
19183   S (mp);
19184   W (ret);
19185   return ret;
19186 }
19187
19188 static int
19189 api_sw_interface_tag_add_del (vat_main_t * vam)
19190 {
19191   unformat_input_t *i = vam->input;
19192   vl_api_sw_interface_tag_add_del_t *mp;
19193   u32 sw_if_index = ~0;
19194   u8 *tag = 0;
19195   u8 enable = 1;
19196   int ret;
19197
19198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19199     {
19200       if (unformat (i, "tag %s", &tag))
19201         ;
19202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19203         ;
19204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19205         ;
19206       else if (unformat (i, "del"))
19207         enable = 0;
19208       else
19209         break;
19210     }
19211
19212   if (sw_if_index == ~0)
19213     {
19214       errmsg ("missing interface name or sw_if_index");
19215       return -99;
19216     }
19217
19218   if (enable && (tag == 0))
19219     {
19220       errmsg ("no tag specified");
19221       return -99;
19222     }
19223
19224   /* Construct the API message */
19225   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19226   mp->sw_if_index = ntohl (sw_if_index);
19227   mp->is_add = enable;
19228   if (enable)
19229     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19230   vec_free (tag);
19231
19232   S (mp);
19233   W (ret);
19234   return ret;
19235 }
19236
19237 static int
19238 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19239 {
19240   unformat_input_t *i = vam->input;
19241   vl_api_mac_address_t mac = { 0 };
19242   vl_api_sw_interface_add_del_mac_address_t *mp;
19243   u32 sw_if_index = ~0;
19244   u8 is_add = 1;
19245   u8 mac_set = 0;
19246   int ret;
19247
19248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19249     {
19250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19251         ;
19252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19253         ;
19254       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19255         mac_set++;
19256       else if (unformat (i, "del"))
19257         is_add = 0;
19258       else
19259         break;
19260     }
19261
19262   if (sw_if_index == ~0)
19263     {
19264       errmsg ("missing interface name or sw_if_index");
19265       return -99;
19266     }
19267
19268   if (!mac_set)
19269     {
19270       errmsg ("missing MAC address");
19271       return -99;
19272     }
19273
19274   /* Construct the API message */
19275   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19276   mp->sw_if_index = ntohl (sw_if_index);
19277   mp->is_add = is_add;
19278   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19279
19280   S (mp);
19281   W (ret);
19282   return ret;
19283 }
19284
19285 static void vl_api_l2_xconnect_details_t_handler
19286   (vl_api_l2_xconnect_details_t * mp)
19287 {
19288   vat_main_t *vam = &vat_main;
19289
19290   print (vam->ofp, "%15d%15d",
19291          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19292 }
19293
19294 static void vl_api_l2_xconnect_details_t_handler_json
19295   (vl_api_l2_xconnect_details_t * mp)
19296 {
19297   vat_main_t *vam = &vat_main;
19298   vat_json_node_t *node = NULL;
19299
19300   if (VAT_JSON_ARRAY != vam->json_tree.type)
19301     {
19302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19303       vat_json_init_array (&vam->json_tree);
19304     }
19305   node = vat_json_array_add (&vam->json_tree);
19306
19307   vat_json_init_object (node);
19308   vat_json_object_add_uint (node, "rx_sw_if_index",
19309                             ntohl (mp->rx_sw_if_index));
19310   vat_json_object_add_uint (node, "tx_sw_if_index",
19311                             ntohl (mp->tx_sw_if_index));
19312 }
19313
19314 static int
19315 api_l2_xconnect_dump (vat_main_t * vam)
19316 {
19317   vl_api_l2_xconnect_dump_t *mp;
19318   vl_api_control_ping_t *mp_ping;
19319   int ret;
19320
19321   if (!vam->json_output)
19322     {
19323       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19324     }
19325
19326   M (L2_XCONNECT_DUMP, mp);
19327
19328   S (mp);
19329
19330   /* Use a control ping for synchronization */
19331   MPING (CONTROL_PING, mp_ping);
19332   S (mp_ping);
19333
19334   W (ret);
19335   return ret;
19336 }
19337
19338 static int
19339 api_hw_interface_set_mtu (vat_main_t * vam)
19340 {
19341   unformat_input_t *i = vam->input;
19342   vl_api_hw_interface_set_mtu_t *mp;
19343   u32 sw_if_index = ~0;
19344   u32 mtu = 0;
19345   int ret;
19346
19347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19348     {
19349       if (unformat (i, "mtu %d", &mtu))
19350         ;
19351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19352         ;
19353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19354         ;
19355       else
19356         break;
19357     }
19358
19359   if (sw_if_index == ~0)
19360     {
19361       errmsg ("missing interface name or sw_if_index");
19362       return -99;
19363     }
19364
19365   if (mtu == 0)
19366     {
19367       errmsg ("no mtu specified");
19368       return -99;
19369     }
19370
19371   /* Construct the API message */
19372   M (HW_INTERFACE_SET_MTU, mp);
19373   mp->sw_if_index = ntohl (sw_if_index);
19374   mp->mtu = ntohs ((u16) mtu);
19375
19376   S (mp);
19377   W (ret);
19378   return ret;
19379 }
19380
19381 static int
19382 api_p2p_ethernet_add (vat_main_t * vam)
19383 {
19384   unformat_input_t *i = vam->input;
19385   vl_api_p2p_ethernet_add_t *mp;
19386   u32 parent_if_index = ~0;
19387   u32 sub_id = ~0;
19388   u8 remote_mac[6];
19389   u8 mac_set = 0;
19390   int ret;
19391
19392   clib_memset (remote_mac, 0, sizeof (remote_mac));
19393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19394     {
19395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19396         ;
19397       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19398         ;
19399       else
19400         if (unformat
19401             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19402         mac_set++;
19403       else if (unformat (i, "sub_id %d", &sub_id))
19404         ;
19405       else
19406         {
19407           clib_warning ("parse error '%U'", format_unformat_error, i);
19408           return -99;
19409         }
19410     }
19411
19412   if (parent_if_index == ~0)
19413     {
19414       errmsg ("missing interface name or sw_if_index");
19415       return -99;
19416     }
19417   if (mac_set == 0)
19418     {
19419       errmsg ("missing remote mac address");
19420       return -99;
19421     }
19422   if (sub_id == ~0)
19423     {
19424       errmsg ("missing sub-interface id");
19425       return -99;
19426     }
19427
19428   M (P2P_ETHERNET_ADD, mp);
19429   mp->parent_if_index = ntohl (parent_if_index);
19430   mp->subif_id = ntohl (sub_id);
19431   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19432
19433   S (mp);
19434   W (ret);
19435   return ret;
19436 }
19437
19438 static int
19439 api_p2p_ethernet_del (vat_main_t * vam)
19440 {
19441   unformat_input_t *i = vam->input;
19442   vl_api_p2p_ethernet_del_t *mp;
19443   u32 parent_if_index = ~0;
19444   u8 remote_mac[6];
19445   u8 mac_set = 0;
19446   int ret;
19447
19448   clib_memset (remote_mac, 0, sizeof (remote_mac));
19449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19450     {
19451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19452         ;
19453       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19454         ;
19455       else
19456         if (unformat
19457             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19458         mac_set++;
19459       else
19460         {
19461           clib_warning ("parse error '%U'", format_unformat_error, i);
19462           return -99;
19463         }
19464     }
19465
19466   if (parent_if_index == ~0)
19467     {
19468       errmsg ("missing interface name or sw_if_index");
19469       return -99;
19470     }
19471   if (mac_set == 0)
19472     {
19473       errmsg ("missing remote mac address");
19474       return -99;
19475     }
19476
19477   M (P2P_ETHERNET_DEL, mp);
19478   mp->parent_if_index = ntohl (parent_if_index);
19479   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19480
19481   S (mp);
19482   W (ret);
19483   return ret;
19484 }
19485
19486 static int
19487 api_lldp_config (vat_main_t * vam)
19488 {
19489   unformat_input_t *i = vam->input;
19490   vl_api_lldp_config_t *mp;
19491   int tx_hold = 0;
19492   int tx_interval = 0;
19493   u8 *sys_name = NULL;
19494   int ret;
19495
19496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19497     {
19498       if (unformat (i, "system-name %s", &sys_name))
19499         ;
19500       else if (unformat (i, "tx-hold %d", &tx_hold))
19501         ;
19502       else if (unformat (i, "tx-interval %d", &tx_interval))
19503         ;
19504       else
19505         {
19506           clib_warning ("parse error '%U'", format_unformat_error, i);
19507           return -99;
19508         }
19509     }
19510
19511   vec_add1 (sys_name, 0);
19512
19513   M (LLDP_CONFIG, mp);
19514   mp->tx_hold = htonl (tx_hold);
19515   mp->tx_interval = htonl (tx_interval);
19516   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19517   vec_free (sys_name);
19518
19519   S (mp);
19520   W (ret);
19521   return ret;
19522 }
19523
19524 static int
19525 api_sw_interface_set_lldp (vat_main_t * vam)
19526 {
19527   unformat_input_t *i = vam->input;
19528   vl_api_sw_interface_set_lldp_t *mp;
19529   u32 sw_if_index = ~0;
19530   u32 enable = 1;
19531   u8 *port_desc = NULL, *mgmt_oid = NULL;
19532   ip4_address_t ip4_addr;
19533   ip6_address_t ip6_addr;
19534   int ret;
19535
19536   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19537   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19538
19539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19540     {
19541       if (unformat (i, "disable"))
19542         enable = 0;
19543       else
19544         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19545         ;
19546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19547         ;
19548       else if (unformat (i, "port-desc %s", &port_desc))
19549         ;
19550       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19551         ;
19552       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19553         ;
19554       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19555         ;
19556       else
19557         break;
19558     }
19559
19560   if (sw_if_index == ~0)
19561     {
19562       errmsg ("missing interface name or sw_if_index");
19563       return -99;
19564     }
19565
19566   /* Construct the API message */
19567   vec_add1 (port_desc, 0);
19568   vec_add1 (mgmt_oid, 0);
19569   M (SW_INTERFACE_SET_LLDP, mp);
19570   mp->sw_if_index = ntohl (sw_if_index);
19571   mp->enable = enable;
19572   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19573   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19574   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19575   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19576   vec_free (port_desc);
19577   vec_free (mgmt_oid);
19578
19579   S (mp);
19580   W (ret);
19581   return ret;
19582 }
19583
19584 static int
19585 api_tcp_configure_src_addresses (vat_main_t * vam)
19586 {
19587   vl_api_tcp_configure_src_addresses_t *mp;
19588   unformat_input_t *i = vam->input;
19589   vl_api_address_t first, last;
19590   u8 range_set = 0;
19591   u32 vrf_id = 0;
19592   int ret;
19593
19594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19595     {
19596       if (unformat (i, "%U - %U",
19597                     unformat_vl_api_address, &first,
19598                     unformat_vl_api_address, &last))
19599         {
19600           if (range_set)
19601             {
19602               errmsg ("one range per message (range already set)");
19603               return -99;
19604             }
19605           range_set = 1;
19606         }
19607       else if (unformat (i, "vrf %d", &vrf_id))
19608         ;
19609       else
19610         break;
19611     }
19612
19613   if (range_set == 0)
19614     {
19615       errmsg ("address range not set");
19616       return -99;
19617     }
19618
19619   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19620
19621   mp->vrf_id = ntohl (vrf_id);
19622   clib_memcpy (&mp->first_address, &first, sizeof (first));
19623   clib_memcpy (&mp->last_address, &last, sizeof (last));
19624
19625   S (mp);
19626   W (ret);
19627   return ret;
19628 }
19629
19630 static void vl_api_app_namespace_add_del_reply_t_handler
19631   (vl_api_app_namespace_add_del_reply_t * mp)
19632 {
19633   vat_main_t *vam = &vat_main;
19634   i32 retval = ntohl (mp->retval);
19635   if (vam->async_mode)
19636     {
19637       vam->async_errors += (retval < 0);
19638     }
19639   else
19640     {
19641       vam->retval = retval;
19642       if (retval == 0)
19643         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19644       vam->result_ready = 1;
19645     }
19646 }
19647
19648 static void vl_api_app_namespace_add_del_reply_t_handler_json
19649   (vl_api_app_namespace_add_del_reply_t * mp)
19650 {
19651   vat_main_t *vam = &vat_main;
19652   vat_json_node_t node;
19653
19654   vat_json_init_object (&node);
19655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19656   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19657
19658   vat_json_print (vam->ofp, &node);
19659   vat_json_free (&node);
19660
19661   vam->retval = ntohl (mp->retval);
19662   vam->result_ready = 1;
19663 }
19664
19665 static int
19666 api_app_namespace_add_del (vat_main_t * vam)
19667 {
19668   vl_api_app_namespace_add_del_t *mp;
19669   unformat_input_t *i = vam->input;
19670   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19671   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19672   u64 secret;
19673   int ret;
19674
19675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19676     {
19677       if (unformat (i, "id %_%v%_", &ns_id))
19678         ;
19679       else if (unformat (i, "secret %lu", &secret))
19680         secret_set = 1;
19681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19682         sw_if_index_set = 1;
19683       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19684         ;
19685       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19686         ;
19687       else
19688         break;
19689     }
19690   if (!ns_id || !secret_set || !sw_if_index_set)
19691     {
19692       errmsg ("namespace id, secret and sw_if_index must be set");
19693       return -99;
19694     }
19695   if (vec_len (ns_id) > 64)
19696     {
19697       errmsg ("namespace id too long");
19698       return -99;
19699     }
19700   M (APP_NAMESPACE_ADD_DEL, mp);
19701
19702   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19703   mp->secret = clib_host_to_net_u64 (secret);
19704   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19705   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19706   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19707   vec_free (ns_id);
19708   S (mp);
19709   W (ret);
19710   return ret;
19711 }
19712
19713 static int
19714 api_sock_init_shm (vat_main_t * vam)
19715 {
19716 #if VPP_API_TEST_BUILTIN == 0
19717   unformat_input_t *i = vam->input;
19718   vl_api_shm_elem_config_t *config = 0;
19719   u64 size = 64 << 20;
19720   int rv;
19721
19722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat (i, "size %U", unformat_memory_size, &size))
19725         ;
19726       else
19727         break;
19728     }
19729
19730   /*
19731    * Canned custom ring allocator config.
19732    * Should probably parse all of this
19733    */
19734   vec_validate (config, 6);
19735   config[0].type = VL_API_VLIB_RING;
19736   config[0].size = 256;
19737   config[0].count = 32;
19738
19739   config[1].type = VL_API_VLIB_RING;
19740   config[1].size = 1024;
19741   config[1].count = 16;
19742
19743   config[2].type = VL_API_VLIB_RING;
19744   config[2].size = 4096;
19745   config[2].count = 2;
19746
19747   config[3].type = VL_API_CLIENT_RING;
19748   config[3].size = 256;
19749   config[3].count = 32;
19750
19751   config[4].type = VL_API_CLIENT_RING;
19752   config[4].size = 1024;
19753   config[4].count = 16;
19754
19755   config[5].type = VL_API_CLIENT_RING;
19756   config[5].size = 4096;
19757   config[5].count = 2;
19758
19759   config[6].type = VL_API_QUEUE;
19760   config[6].count = 128;
19761   config[6].size = sizeof (uword);
19762
19763   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19764   if (!rv)
19765     vam->client_index_invalid = 1;
19766   return rv;
19767 #else
19768   return -99;
19769 #endif
19770 }
19771
19772 static void
19773 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19774 {
19775   vat_main_t *vam = &vat_main;
19776   fib_prefix_t lcl, rmt;
19777
19778   ip_prefix_decode (&mp->lcl, &lcl);
19779   ip_prefix_decode (&mp->rmt, &rmt);
19780
19781   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19782     {
19783       print (vam->ofp,
19784              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19785              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19786              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19787              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19788              &rmt.fp_addr.ip4, rmt.fp_len,
19789              clib_net_to_host_u16 (mp->rmt_port),
19790              clib_net_to_host_u32 (mp->action_index), mp->tag);
19791     }
19792   else
19793     {
19794       print (vam->ofp,
19795              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19796              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19797              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19798              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19799              &rmt.fp_addr.ip6, rmt.fp_len,
19800              clib_net_to_host_u16 (mp->rmt_port),
19801              clib_net_to_host_u32 (mp->action_index), mp->tag);
19802     }
19803 }
19804
19805 static void
19806 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19807                                              mp)
19808 {
19809   vat_main_t *vam = &vat_main;
19810   vat_json_node_t *node = NULL;
19811   struct in6_addr ip6;
19812   struct in_addr ip4;
19813
19814   fib_prefix_t lcl, rmt;
19815
19816   ip_prefix_decode (&mp->lcl, &lcl);
19817   ip_prefix_decode (&mp->rmt, &rmt);
19818
19819   if (VAT_JSON_ARRAY != vam->json_tree.type)
19820     {
19821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19822       vat_json_init_array (&vam->json_tree);
19823     }
19824   node = vat_json_array_add (&vam->json_tree);
19825   vat_json_init_object (node);
19826
19827   vat_json_object_add_uint (node, "appns_index",
19828                             clib_net_to_host_u32 (mp->appns_index));
19829   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19830   vat_json_object_add_uint (node, "scope", mp->scope);
19831   vat_json_object_add_uint (node, "action_index",
19832                             clib_net_to_host_u32 (mp->action_index));
19833   vat_json_object_add_uint (node, "lcl_port",
19834                             clib_net_to_host_u16 (mp->lcl_port));
19835   vat_json_object_add_uint (node, "rmt_port",
19836                             clib_net_to_host_u16 (mp->rmt_port));
19837   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19838   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19839   vat_json_object_add_string_copy (node, "tag", mp->tag);
19840   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19841     {
19842       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19843       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19844       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19845       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19846     }
19847   else
19848     {
19849       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19850       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19851       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19852       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19853     }
19854 }
19855
19856 static int
19857 api_session_rule_add_del (vat_main_t * vam)
19858 {
19859   vl_api_session_rule_add_del_t *mp;
19860   unformat_input_t *i = vam->input;
19861   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19862   u32 appns_index = 0, scope = 0;
19863   ip4_address_t lcl_ip4, rmt_ip4;
19864   ip6_address_t lcl_ip6, rmt_ip6;
19865   u8 is_ip4 = 1, conn_set = 0;
19866   u8 is_add = 1, *tag = 0;
19867   int ret;
19868   fib_prefix_t lcl, rmt;
19869
19870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19871     {
19872       if (unformat (i, "del"))
19873         is_add = 0;
19874       else if (unformat (i, "add"))
19875         ;
19876       else if (unformat (i, "proto tcp"))
19877         proto = 0;
19878       else if (unformat (i, "proto udp"))
19879         proto = 1;
19880       else if (unformat (i, "appns %d", &appns_index))
19881         ;
19882       else if (unformat (i, "scope %d", &scope))
19883         ;
19884       else if (unformat (i, "tag %_%v%_", &tag))
19885         ;
19886       else
19887         if (unformat
19888             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19889              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19890              &rmt_port))
19891         {
19892           is_ip4 = 1;
19893           conn_set = 1;
19894         }
19895       else
19896         if (unformat
19897             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19898              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19899              &rmt_port))
19900         {
19901           is_ip4 = 0;
19902           conn_set = 1;
19903         }
19904       else if (unformat (i, "action %d", &action))
19905         ;
19906       else
19907         break;
19908     }
19909   if (proto == ~0 || !conn_set || action == ~0)
19910     {
19911       errmsg ("transport proto, connection and action must be set");
19912       return -99;
19913     }
19914
19915   if (scope > 3)
19916     {
19917       errmsg ("scope should be 0-3");
19918       return -99;
19919     }
19920
19921   M (SESSION_RULE_ADD_DEL, mp);
19922
19923   clib_memset (&lcl, 0, sizeof (lcl));
19924   clib_memset (&rmt, 0, sizeof (rmt));
19925   if (is_ip4)
19926     {
19927       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19928       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19929       lcl.fp_len = lcl_plen;
19930       rmt.fp_len = rmt_plen;
19931     }
19932   else
19933     {
19934       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19935       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19936       lcl.fp_len = lcl_plen;
19937       rmt.fp_len = rmt_plen;
19938     }
19939
19940
19941   ip_prefix_encode (&lcl, &mp->lcl);
19942   ip_prefix_encode (&rmt, &mp->rmt);
19943   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19944   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19945   mp->transport_proto =
19946     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19947   mp->action_index = clib_host_to_net_u32 (action);
19948   mp->appns_index = clib_host_to_net_u32 (appns_index);
19949   mp->scope = scope;
19950   mp->is_add = is_add;
19951   if (tag)
19952     {
19953       clib_memcpy (mp->tag, tag, vec_len (tag));
19954       vec_free (tag);
19955     }
19956
19957   S (mp);
19958   W (ret);
19959   return ret;
19960 }
19961
19962 static int
19963 api_session_rules_dump (vat_main_t * vam)
19964 {
19965   vl_api_session_rules_dump_t *mp;
19966   vl_api_control_ping_t *mp_ping;
19967   int ret;
19968
19969   if (!vam->json_output)
19970     {
19971       print (vam->ofp, "%=20s", "Session Rules");
19972     }
19973
19974   M (SESSION_RULES_DUMP, mp);
19975   /* send it... */
19976   S (mp);
19977
19978   /* Use a control ping for synchronization */
19979   MPING (CONTROL_PING, mp_ping);
19980   S (mp_ping);
19981
19982   /* Wait for a reply... */
19983   W (ret);
19984   return ret;
19985 }
19986
19987 static int
19988 api_ip_container_proxy_add_del (vat_main_t * vam)
19989 {
19990   vl_api_ip_container_proxy_add_del_t *mp;
19991   unformat_input_t *i = vam->input;
19992   u32 sw_if_index = ~0;
19993   vl_api_prefix_t pfx = { };
19994   u8 is_add = 1;
19995   int ret;
19996
19997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19998     {
19999       if (unformat (i, "del"))
20000         is_add = 0;
20001       else if (unformat (i, "add"))
20002         ;
20003       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20004         ;
20005       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20006         ;
20007       else
20008         break;
20009     }
20010   if (sw_if_index == ~0 || pfx.len == 0)
20011     {
20012       errmsg ("address and sw_if_index must be set");
20013       return -99;
20014     }
20015
20016   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20017
20018   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20019   mp->is_add = is_add;
20020   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20021
20022   S (mp);
20023   W (ret);
20024   return ret;
20025 }
20026
20027 static int
20028 api_qos_record_enable_disable (vat_main_t * vam)
20029 {
20030   unformat_input_t *i = vam->input;
20031   vl_api_qos_record_enable_disable_t *mp;
20032   u32 sw_if_index, qs = 0xff;
20033   u8 sw_if_index_set = 0;
20034   u8 enable = 1;
20035   int ret;
20036
20037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20038     {
20039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20040         sw_if_index_set = 1;
20041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20042         sw_if_index_set = 1;
20043       else if (unformat (i, "%U", unformat_qos_source, &qs))
20044         ;
20045       else if (unformat (i, "disable"))
20046         enable = 0;
20047       else
20048         {
20049           clib_warning ("parse error '%U'", format_unformat_error, i);
20050           return -99;
20051         }
20052     }
20053
20054   if (sw_if_index_set == 0)
20055     {
20056       errmsg ("missing interface name or sw_if_index");
20057       return -99;
20058     }
20059   if (qs == 0xff)
20060     {
20061       errmsg ("input location must be specified");
20062       return -99;
20063     }
20064
20065   M (QOS_RECORD_ENABLE_DISABLE, mp);
20066
20067   mp->record.sw_if_index = ntohl (sw_if_index);
20068   mp->record.input_source = qs;
20069   mp->enable = enable;
20070
20071   S (mp);
20072   W (ret);
20073   return ret;
20074 }
20075
20076
20077 static int
20078 q_or_quit (vat_main_t * vam)
20079 {
20080 #if VPP_API_TEST_BUILTIN == 0
20081   longjmp (vam->jump_buf, 1);
20082 #endif
20083   return 0;                     /* not so much */
20084 }
20085
20086 static int
20087 q (vat_main_t * vam)
20088 {
20089   return q_or_quit (vam);
20090 }
20091
20092 static int
20093 quit (vat_main_t * vam)
20094 {
20095   return q_or_quit (vam);
20096 }
20097
20098 static int
20099 comment (vat_main_t * vam)
20100 {
20101   return 0;
20102 }
20103
20104 static int
20105 elog_save (vat_main_t * vam)
20106 {
20107 #if VPP_API_TEST_BUILTIN == 0
20108   elog_main_t *em = &vam->elog_main;
20109   unformat_input_t *i = vam->input;
20110   char *file, *chroot_file;
20111   clib_error_t *error;
20112
20113   if (!unformat (i, "%s", &file))
20114     {
20115       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20116       return 0;
20117     }
20118
20119   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20120   if (strstr (file, "..") || index (file, '/'))
20121     {
20122       errmsg ("illegal characters in filename '%s'", file);
20123       return 0;
20124     }
20125
20126   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20127
20128   vec_free (file);
20129
20130   errmsg ("Saving %wd of %wd events to %s",
20131           elog_n_events_in_buffer (em),
20132           elog_buffer_capacity (em), chroot_file);
20133
20134   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20135   vec_free (chroot_file);
20136
20137   if (error)
20138     clib_error_report (error);
20139 #else
20140   errmsg ("Use the vpp event loger...");
20141 #endif
20142
20143   return 0;
20144 }
20145
20146 static int
20147 elog_setup (vat_main_t * vam)
20148 {
20149 #if VPP_API_TEST_BUILTIN == 0
20150   elog_main_t *em = &vam->elog_main;
20151   unformat_input_t *i = vam->input;
20152   u32 nevents = 128 << 10;
20153
20154   (void) unformat (i, "nevents %d", &nevents);
20155
20156   elog_init (em, nevents);
20157   vl_api_set_elog_main (em);
20158   vl_api_set_elog_trace_api_messages (1);
20159   errmsg ("Event logger initialized with %u events", nevents);
20160 #else
20161   errmsg ("Use the vpp event loger...");
20162 #endif
20163   return 0;
20164 }
20165
20166 static int
20167 elog_enable (vat_main_t * vam)
20168 {
20169 #if VPP_API_TEST_BUILTIN == 0
20170   elog_main_t *em = &vam->elog_main;
20171
20172   elog_enable_disable (em, 1 /* enable */ );
20173   vl_api_set_elog_trace_api_messages (1);
20174   errmsg ("Event logger enabled...");
20175 #else
20176   errmsg ("Use the vpp event loger...");
20177 #endif
20178   return 0;
20179 }
20180
20181 static int
20182 elog_disable (vat_main_t * vam)
20183 {
20184 #if VPP_API_TEST_BUILTIN == 0
20185   elog_main_t *em = &vam->elog_main;
20186
20187   elog_enable_disable (em, 0 /* enable */ );
20188   vl_api_set_elog_trace_api_messages (1);
20189   errmsg ("Event logger disabled...");
20190 #else
20191   errmsg ("Use the vpp event loger...");
20192 #endif
20193   return 0;
20194 }
20195
20196 static int
20197 statseg (vat_main_t * vam)
20198 {
20199   ssvm_private_t *ssvmp = &vam->stat_segment;
20200   ssvm_shared_header_t *shared_header = ssvmp->sh;
20201   vlib_counter_t **counters;
20202   u64 thread0_index1_packets;
20203   u64 thread0_index1_bytes;
20204   f64 vector_rate, input_rate;
20205   uword *p;
20206
20207   uword *counter_vector_by_name;
20208   if (vam->stat_segment_lockp == 0)
20209     {
20210       errmsg ("Stat segment not mapped...");
20211       return -99;
20212     }
20213
20214   /* look up "/if/rx for sw_if_index 1 as a test */
20215
20216   clib_spinlock_lock (vam->stat_segment_lockp);
20217
20218   counter_vector_by_name = (uword *) shared_header->opaque[1];
20219
20220   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20221   if (p == 0)
20222     {
20223       clib_spinlock_unlock (vam->stat_segment_lockp);
20224       errmsg ("/if/tx not found?");
20225       return -99;
20226     }
20227
20228   /* Fish per-thread vector of combined counters from shared memory */
20229   counters = (vlib_counter_t **) p[0];
20230
20231   if (vec_len (counters[0]) < 2)
20232     {
20233       clib_spinlock_unlock (vam->stat_segment_lockp);
20234       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20235       return -99;
20236     }
20237
20238   /* Read thread 0 sw_if_index 1 counter */
20239   thread0_index1_packets = counters[0][1].packets;
20240   thread0_index1_bytes = counters[0][1].bytes;
20241
20242   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20243   if (p == 0)
20244     {
20245       clib_spinlock_unlock (vam->stat_segment_lockp);
20246       errmsg ("vector_rate not found?");
20247       return -99;
20248     }
20249
20250   vector_rate = *(f64 *) (p[0]);
20251   p = hash_get_mem (counter_vector_by_name, "input_rate");
20252   if (p == 0)
20253     {
20254       clib_spinlock_unlock (vam->stat_segment_lockp);
20255       errmsg ("input_rate not found?");
20256       return -99;
20257     }
20258   input_rate = *(f64 *) (p[0]);
20259
20260   clib_spinlock_unlock (vam->stat_segment_lockp);
20261
20262   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20263          vector_rate, input_rate);
20264   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20265          thread0_index1_packets, thread0_index1_bytes);
20266
20267   return 0;
20268 }
20269
20270 static int
20271 cmd_cmp (void *a1, void *a2)
20272 {
20273   u8 **c1 = a1;
20274   u8 **c2 = a2;
20275
20276   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20277 }
20278
20279 static int
20280 help (vat_main_t * vam)
20281 {
20282   u8 **cmds = 0;
20283   u8 *name = 0;
20284   hash_pair_t *p;
20285   unformat_input_t *i = vam->input;
20286   int j;
20287
20288   if (unformat (i, "%s", &name))
20289     {
20290       uword *hs;
20291
20292       vec_add1 (name, 0);
20293
20294       hs = hash_get_mem (vam->help_by_name, name);
20295       if (hs)
20296         print (vam->ofp, "usage: %s %s", name, hs[0]);
20297       else
20298         print (vam->ofp, "No such msg / command '%s'", name);
20299       vec_free (name);
20300       return 0;
20301     }
20302
20303   print (vam->ofp, "Help is available for the following:");
20304
20305     /* *INDENT-OFF* */
20306     hash_foreach_pair (p, vam->function_by_name,
20307     ({
20308       vec_add1 (cmds, (u8 *)(p->key));
20309     }));
20310     /* *INDENT-ON* */
20311
20312   vec_sort_with_function (cmds, cmd_cmp);
20313
20314   for (j = 0; j < vec_len (cmds); j++)
20315     print (vam->ofp, "%s", cmds[j]);
20316
20317   vec_free (cmds);
20318   return 0;
20319 }
20320
20321 static int
20322 set (vat_main_t * vam)
20323 {
20324   u8 *name = 0, *value = 0;
20325   unformat_input_t *i = vam->input;
20326
20327   if (unformat (i, "%s", &name))
20328     {
20329       /* The input buffer is a vector, not a string. */
20330       value = vec_dup (i->buffer);
20331       vec_delete (value, i->index, 0);
20332       /* Almost certainly has a trailing newline */
20333       if (value[vec_len (value) - 1] == '\n')
20334         value[vec_len (value) - 1] = 0;
20335       /* Make sure it's a proper string, one way or the other */
20336       vec_add1 (value, 0);
20337       (void) clib_macro_set_value (&vam->macro_main,
20338                                    (char *) name, (char *) value);
20339     }
20340   else
20341     errmsg ("usage: set <name> <value>");
20342
20343   vec_free (name);
20344   vec_free (value);
20345   return 0;
20346 }
20347
20348 static int
20349 unset (vat_main_t * vam)
20350 {
20351   u8 *name = 0;
20352
20353   if (unformat (vam->input, "%s", &name))
20354     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20355       errmsg ("unset: %s wasn't set", name);
20356   vec_free (name);
20357   return 0;
20358 }
20359
20360 typedef struct
20361 {
20362   u8 *name;
20363   u8 *value;
20364 } macro_sort_t;
20365
20366
20367 static int
20368 macro_sort_cmp (void *a1, void *a2)
20369 {
20370   macro_sort_t *s1 = a1;
20371   macro_sort_t *s2 = a2;
20372
20373   return strcmp ((char *) (s1->name), (char *) (s2->name));
20374 }
20375
20376 static int
20377 dump_macro_table (vat_main_t * vam)
20378 {
20379   macro_sort_t *sort_me = 0, *sm;
20380   int i;
20381   hash_pair_t *p;
20382
20383     /* *INDENT-OFF* */
20384     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20385     ({
20386       vec_add2 (sort_me, sm, 1);
20387       sm->name = (u8 *)(p->key);
20388       sm->value = (u8 *) (p->value[0]);
20389     }));
20390     /* *INDENT-ON* */
20391
20392   vec_sort_with_function (sort_me, macro_sort_cmp);
20393
20394   if (vec_len (sort_me))
20395     print (vam->ofp, "%-15s%s", "Name", "Value");
20396   else
20397     print (vam->ofp, "The macro table is empty...");
20398
20399   for (i = 0; i < vec_len (sort_me); i++)
20400     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20401   return 0;
20402 }
20403
20404 static int
20405 dump_node_table (vat_main_t * vam)
20406 {
20407   int i, j;
20408   vlib_node_t *node, *next_node;
20409
20410   if (vec_len (vam->graph_nodes) == 0)
20411     {
20412       print (vam->ofp, "Node table empty, issue get_node_graph...");
20413       return 0;
20414     }
20415
20416   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20417     {
20418       node = vam->graph_nodes[0][i];
20419       print (vam->ofp, "[%d] %s", i, node->name);
20420       for (j = 0; j < vec_len (node->next_nodes); j++)
20421         {
20422           if (node->next_nodes[j] != ~0)
20423             {
20424               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20425               print (vam->ofp, "  [%d] %s", j, next_node->name);
20426             }
20427         }
20428     }
20429   return 0;
20430 }
20431
20432 static int
20433 value_sort_cmp (void *a1, void *a2)
20434 {
20435   name_sort_t *n1 = a1;
20436   name_sort_t *n2 = a2;
20437
20438   if (n1->value < n2->value)
20439     return -1;
20440   if (n1->value > n2->value)
20441     return 1;
20442   return 0;
20443 }
20444
20445
20446 static int
20447 dump_msg_api_table (vat_main_t * vam)
20448 {
20449   api_main_t *am = vlibapi_get_main ();
20450   name_sort_t *nses = 0, *ns;
20451   hash_pair_t *hp;
20452   int i;
20453
20454   /* *INDENT-OFF* */
20455   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20456   ({
20457     vec_add2 (nses, ns, 1);
20458     ns->name = (u8 *)(hp->key);
20459     ns->value = (u32) hp->value[0];
20460   }));
20461   /* *INDENT-ON* */
20462
20463   vec_sort_with_function (nses, value_sort_cmp);
20464
20465   for (i = 0; i < vec_len (nses); i++)
20466     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20467   vec_free (nses);
20468   return 0;
20469 }
20470
20471 static int
20472 get_msg_id (vat_main_t * vam)
20473 {
20474   u8 *name_and_crc;
20475   u32 message_index;
20476
20477   if (unformat (vam->input, "%s", &name_and_crc))
20478     {
20479       message_index = vl_msg_api_get_msg_index (name_and_crc);
20480       if (message_index == ~0)
20481         {
20482           print (vam->ofp, " '%s' not found", name_and_crc);
20483           return 0;
20484         }
20485       print (vam->ofp, " '%s' has message index %d",
20486              name_and_crc, message_index);
20487       return 0;
20488     }
20489   errmsg ("name_and_crc required...");
20490   return 0;
20491 }
20492
20493 static int
20494 search_node_table (vat_main_t * vam)
20495 {
20496   unformat_input_t *line_input = vam->input;
20497   u8 *node_to_find;
20498   int j;
20499   vlib_node_t *node, *next_node;
20500   uword *p;
20501
20502   if (vam->graph_node_index_by_name == 0)
20503     {
20504       print (vam->ofp, "Node table empty, issue get_node_graph...");
20505       return 0;
20506     }
20507
20508   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20509     {
20510       if (unformat (line_input, "%s", &node_to_find))
20511         {
20512           vec_add1 (node_to_find, 0);
20513           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20514           if (p == 0)
20515             {
20516               print (vam->ofp, "%s not found...", node_to_find);
20517               goto out;
20518             }
20519           node = vam->graph_nodes[0][p[0]];
20520           print (vam->ofp, "[%d] %s", p[0], node->name);
20521           for (j = 0; j < vec_len (node->next_nodes); j++)
20522             {
20523               if (node->next_nodes[j] != ~0)
20524                 {
20525                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20526                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20527                 }
20528             }
20529         }
20530
20531       else
20532         {
20533           clib_warning ("parse error '%U'", format_unformat_error,
20534                         line_input);
20535           return -99;
20536         }
20537
20538     out:
20539       vec_free (node_to_find);
20540
20541     }
20542
20543   return 0;
20544 }
20545
20546
20547 static int
20548 script (vat_main_t * vam)
20549 {
20550 #if (VPP_API_TEST_BUILTIN==0)
20551   u8 *s = 0;
20552   char *save_current_file;
20553   unformat_input_t save_input;
20554   jmp_buf save_jump_buf;
20555   u32 save_line_number;
20556
20557   FILE *new_fp, *save_ifp;
20558
20559   if (unformat (vam->input, "%s", &s))
20560     {
20561       new_fp = fopen ((char *) s, "r");
20562       if (new_fp == 0)
20563         {
20564           errmsg ("Couldn't open script file %s", s);
20565           vec_free (s);
20566           return -99;
20567         }
20568     }
20569   else
20570     {
20571       errmsg ("Missing script name");
20572       return -99;
20573     }
20574
20575   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20576   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20577   save_ifp = vam->ifp;
20578   save_line_number = vam->input_line_number;
20579   save_current_file = (char *) vam->current_file;
20580
20581   vam->input_line_number = 0;
20582   vam->ifp = new_fp;
20583   vam->current_file = s;
20584   do_one_file (vam);
20585
20586   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20587   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20588   vam->ifp = save_ifp;
20589   vam->input_line_number = save_line_number;
20590   vam->current_file = (u8 *) save_current_file;
20591   vec_free (s);
20592
20593   return 0;
20594 #else
20595   clib_warning ("use the exec command...");
20596   return -99;
20597 #endif
20598 }
20599
20600 static int
20601 echo (vat_main_t * vam)
20602 {
20603   print (vam->ofp, "%v", vam->input->buffer);
20604   return 0;
20605 }
20606
20607 /* List of API message constructors, CLI names map to api_xxx */
20608 #define foreach_vpe_api_msg                                             \
20609 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20610 _(sw_interface_dump,"")                                                 \
20611 _(sw_interface_set_flags,                                               \
20612   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20613 _(sw_interface_add_del_address,                                         \
20614   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20615 _(sw_interface_set_rx_mode,                                             \
20616   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20617 _(sw_interface_set_rx_placement,                                        \
20618   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20619 _(sw_interface_rx_placement_dump,                                       \
20620   "[<intfc> | sw_if_index <id>]")                                         \
20621 _(sw_interface_set_table,                                               \
20622   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20623 _(sw_interface_set_mpls_enable,                                         \
20624   "<intfc> | sw_if_index [disable | dis]")                              \
20625 _(sw_interface_set_vpath,                                               \
20626   "<intfc> | sw_if_index <id> enable | disable")                        \
20627 _(sw_interface_set_vxlan_bypass,                                        \
20628   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20629 _(sw_interface_set_geneve_bypass,                                       \
20630   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20631 _(sw_interface_set_l2_xconnect,                                         \
20632   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20633   "enable | disable")                                                   \
20634 _(sw_interface_set_l2_bridge,                                           \
20635   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20636   "[shg <split-horizon-group>] [bvi]\n"                                 \
20637   "enable | disable")                                                   \
20638 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20639 _(bridge_domain_add_del,                                                \
20640   "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") \
20641 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20642 _(l2fib_add_del,                                                        \
20643   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20644 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20645 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20646 _(l2_flags,                                                             \
20647   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20648 _(bridge_flags,                                                         \
20649   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20650 _(tap_create_v2,                                                        \
20651   "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]") \
20652 _(tap_delete_v2,                                                        \
20653   "<vpp-if-name> | sw_if_index <id>")                                   \
20654 _(sw_interface_tap_v2_dump, "")                                         \
20655 _(virtio_pci_create,                                                    \
20656   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20657 _(virtio_pci_delete,                                                    \
20658   "<vpp-if-name> | sw_if_index <id>")                                   \
20659 _(sw_interface_virtio_pci_dump, "")                                     \
20660 _(bond_create,                                                          \
20661   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20662   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20663   "[id <if-id>]")                                                       \
20664 _(bond_delete,                                                          \
20665   "<vpp-if-name> | sw_if_index <id>")                                   \
20666 _(bond_enslave,                                                         \
20667   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20668 _(bond_detach_slave,                                                    \
20669   "sw_if_index <n>")                                                    \
20670  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20671 _(sw_interface_bond_dump, "")                                           \
20672 _(sw_interface_slave_dump,                                              \
20673   "<vpp-if-name> | sw_if_index <id>")                                   \
20674 _(ip_table_add_del,                                                     \
20675   "table <n> [ipv6] [add | del]\n")                                     \
20676 _(ip_route_add_del,                                                     \
20677   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20678   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20679   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20680   "[multipath] [count <n>] [del]")                                      \
20681 _(ip_mroute_add_del,                                                    \
20682   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20683   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20684 _(mpls_table_add_del,                                                   \
20685   "table <n> [add | del]\n")                                            \
20686 _(mpls_route_add_del,                                                   \
20687   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20688   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20689   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20690   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20691   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20692   "[count <n>] [del]")                                                  \
20693 _(mpls_ip_bind_unbind,                                                  \
20694   "<label> <addr/len>")                                                 \
20695 _(mpls_tunnel_add_del,                                                  \
20696   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20697   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20698   "[l2-only]  [out-label <n>]")                                         \
20699 _(sr_mpls_policy_add,                                                   \
20700   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20701 _(sr_mpls_policy_del,                                                   \
20702   "bsid <id>")                                                          \
20703 _(bier_table_add_del,                                                   \
20704   "<label> <sub-domain> <set> <bsl> [del]")                             \
20705 _(bier_route_add_del,                                                   \
20706   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20707   "[<intfc> | sw_if_index <id>]"                                        \
20708   "[weight <n>] [del] [multipath]")                                     \
20709 _(sw_interface_set_unnumbered,                                          \
20710   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20711 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20712 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20713   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20714   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20715   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20716 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20717 _(ip_table_flush, "table <n> [ipv6]")                                   \
20718 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20719 _(set_ip_flow_hash,                                                     \
20720   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20721 _(sw_interface_ip6_enable_disable,                                      \
20722   "<intfc> | sw_if_index <id> enable | disable")                        \
20723 _(l2_patch_add_del,                                                     \
20724   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20725   "enable | disable")                                                   \
20726 _(sr_localsid_add_del,                                                  \
20727   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20728   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20729 _(classify_add_del_table,                                               \
20730   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20731   " [del] [del-chain] mask <mask-value>\n"                              \
20732   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20733   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20734 _(classify_add_del_session,                                             \
20735   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20736   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20737   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20738   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20739 _(classify_set_interface_ip_table,                                      \
20740   "<intfc> | sw_if_index <nn> table <nn>")                              \
20741 _(classify_set_interface_l2_tables,                                     \
20742   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20743   "  [other-table <nn>]")                                               \
20744 _(get_node_index, "node <node-name")                                    \
20745 _(add_node_next, "node <node-name> next <next-node-name>")              \
20746 _(l2tpv3_create_tunnel,                                                 \
20747   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20748   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20749   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20750 _(l2tpv3_set_tunnel_cookies,                                            \
20751   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20752   "[new_remote_cookie <nn>]\n")                                         \
20753 _(l2tpv3_interface_enable_disable,                                      \
20754   "<intfc> | sw_if_index <nn> enable | disable")                        \
20755 _(l2tpv3_set_lookup_key,                                                \
20756   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20757 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20758 _(vxlan_offload_rx,                                                     \
20759   "hw { <interface name> | hw_if_index <nn>} "                          \
20760   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20761 _(vxlan_add_del_tunnel,                                                 \
20762   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20763   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20764   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20765 _(geneve_add_del_tunnel,                                                \
20766   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20767   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20768   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20769 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20770 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20771 _(gre_tunnel_add_del,                                                   \
20772   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20773   "[teb | erspan <session-id>] [del]")                                  \
20774 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20775 _(l2_fib_clear_table, "")                                               \
20776 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20777 _(l2_interface_vlan_tag_rewrite,                                        \
20778   "<intfc> | sw_if_index <nn> \n"                                       \
20779   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20780   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20781 _(create_vhost_user_if,                                                 \
20782         "socket <filename> [server] [renumber <dev_instance>] "         \
20783         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20784         "[mac <mac_address>]")                                          \
20785 _(modify_vhost_user_if,                                                 \
20786         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20787         "[server] [renumber <dev_instance>] [gso]")                     \
20788 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20789 _(sw_interface_vhost_user_dump, "")                                     \
20790 _(show_version, "")                                                     \
20791 _(show_threads, "")                                                     \
20792 _(vxlan_gpe_add_del_tunnel,                                             \
20793   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20794   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20795   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20796   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20797 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20798 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20799 _(interface_name_renumber,                                              \
20800   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20801 _(input_acl_set_interface,                                              \
20802   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20803   "  [l2-table <nn>] [del]")                                            \
20804 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20805 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20806 _(ip_dump, "ipv4 | ipv6")                                               \
20807 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20808 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20809   "  spid_id <n> ")                                                     \
20810 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20811   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20812   "  integ_alg <alg> integ_key <hex>")                                  \
20813 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20814   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20815   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20816   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20817 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20818   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20819   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20820   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20821   "  [instance <n>]")     \
20822 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20823 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20824 _(delete_loopback,"sw_if_index <nn>")                                   \
20825 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20826 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20827 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20828 _(want_interface_events,  "enable|disable")                             \
20829 _(get_first_msg_id, "client <name>")                                    \
20830 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20831 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20832   "fib-id <nn> [ip4][ip6][default]")                                    \
20833 _(get_node_graph, " ")                                                  \
20834 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20835 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20836 _(ioam_disable, "")                                                     \
20837 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20838                             " sw_if_index <sw_if_index> p <priority> "  \
20839                             "w <weight>] [del]")                        \
20840 _(one_add_del_locator, "locator-set <locator_name> "                    \
20841                         "iface <intf> | sw_if_index <sw_if_index> "     \
20842                         "p <priority> w <weight> [del]")                \
20843 _(one_add_del_local_eid,"vni <vni> eid "                                \
20844                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20845                          "locator-set <locator_name> [del]"             \
20846                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20847 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20848 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20849 _(one_enable_disable, "enable|disable")                                 \
20850 _(one_map_register_enable_disable, "enable|disable")                    \
20851 _(one_map_register_fallback_threshold, "<value>")                       \
20852 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20853 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20854                                "[seid <seid>] "                         \
20855                                "rloc <locator> p <prio> "               \
20856                                "w <weight> [rloc <loc> ... ] "          \
20857                                "action <action> [del-all]")             \
20858 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20859                           "<local-eid>")                                \
20860 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20861 _(one_use_petr, "ip-address> | disable")                                \
20862 _(one_map_request_mode, "src-dst|dst-only")                             \
20863 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20864 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20865 _(one_locator_set_dump, "[local | remote]")                             \
20866 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20867 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20868                        "[local] | [remote]")                            \
20869 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20870 _(one_ndp_bd_get, "")                                                   \
20871 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20872 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20873 _(one_l2_arp_bd_get, "")                                                \
20874 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20875 _(one_stats_enable_disable, "enable|disable")                           \
20876 _(show_one_stats_enable_disable, "")                                    \
20877 _(one_eid_table_vni_dump, "")                                           \
20878 _(one_eid_table_map_dump, "l2|l3")                                      \
20879 _(one_map_resolver_dump, "")                                            \
20880 _(one_map_server_dump, "")                                              \
20881 _(one_adjacencies_get, "vni <vni>")                                     \
20882 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20883 _(show_one_rloc_probe_state, "")                                        \
20884 _(show_one_map_register_state, "")                                      \
20885 _(show_one_status, "")                                                  \
20886 _(one_stats_dump, "")                                                   \
20887 _(one_stats_flush, "")                                                  \
20888 _(one_get_map_request_itr_rlocs, "")                                    \
20889 _(one_map_register_set_ttl, "<ttl>")                                    \
20890 _(one_set_transport_protocol, "udp|api")                                \
20891 _(one_get_transport_protocol, "")                                       \
20892 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20893 _(one_show_xtr_mode, "")                                                \
20894 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20895 _(one_show_pitr_mode, "")                                               \
20896 _(one_enable_disable_petr_mode, "enable|disable")                       \
20897 _(one_show_petr_mode, "")                                               \
20898 _(show_one_nsh_mapping, "")                                             \
20899 _(show_one_pitr, "")                                                    \
20900 _(show_one_use_petr, "")                                                \
20901 _(show_one_map_request_mode, "")                                        \
20902 _(show_one_map_register_ttl, "")                                        \
20903 _(show_one_map_register_fallback_threshold, "")                         \
20904 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20905                             " sw_if_index <sw_if_index> p <priority> "  \
20906                             "w <weight>] [del]")                        \
20907 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20908                         "iface <intf> | sw_if_index <sw_if_index> "     \
20909                         "p <priority> w <weight> [del]")                \
20910 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20911                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20912                          "locator-set <locator_name> [del]"             \
20913                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20914 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20915 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20916 _(lisp_enable_disable, "enable|disable")                                \
20917 _(lisp_map_register_enable_disable, "enable|disable")                   \
20918 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20919 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20920                                "[seid <seid>] "                         \
20921                                "rloc <locator> p <prio> "               \
20922                                "w <weight> [rloc <loc> ... ] "          \
20923                                "action <action> [del-all]")             \
20924 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20925                           "<local-eid>")                                \
20926 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20927 _(lisp_use_petr, "<ip-address> | disable")                              \
20928 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20929 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20930 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20931 _(lisp_locator_set_dump, "[local | remote]")                            \
20932 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20933 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20934                        "[local] | [remote]")                            \
20935 _(lisp_eid_table_vni_dump, "")                                          \
20936 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20937 _(lisp_map_resolver_dump, "")                                           \
20938 _(lisp_map_server_dump, "")                                             \
20939 _(lisp_adjacencies_get, "vni <vni>")                                    \
20940 _(gpe_fwd_entry_vnis_get, "")                                           \
20941 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20942 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20943                                 "[table <table-id>]")                   \
20944 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20945 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20946 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20947 _(gpe_get_encap_mode, "")                                               \
20948 _(lisp_gpe_add_del_iface, "up|down")                                    \
20949 _(lisp_gpe_enable_disable, "enable|disable")                            \
20950 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20951   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20952 _(show_lisp_rloc_probe_state, "")                                       \
20953 _(show_lisp_map_register_state, "")                                     \
20954 _(show_lisp_status, "")                                                 \
20955 _(lisp_get_map_request_itr_rlocs, "")                                   \
20956 _(show_lisp_pitr, "")                                                   \
20957 _(show_lisp_use_petr, "")                                               \
20958 _(show_lisp_map_request_mode, "")                                       \
20959 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20960 _(af_packet_delete, "name <host interface name>")                       \
20961 _(af_packet_dump, "")                                                   \
20962 _(policer_add_del, "name <policer name> <params> [del]")                \
20963 _(policer_dump, "[name <policer name>]")                                \
20964 _(policer_classify_set_interface,                                       \
20965   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20966   "  [l2-table <nn>] [del]")                                            \
20967 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20968 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20969 _(mpls_table_dump, "")                                                  \
20970 _(mpls_route_dump, "table-id <ID>")                                     \
20971 _(classify_table_ids, "")                                               \
20972 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20973 _(classify_table_info, "table_id <nn>")                                 \
20974 _(classify_session_dump, "table_id <nn>")                               \
20975 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20976     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20977     "[template_interval <nn>] [udp_checksum]")                          \
20978 _(ipfix_exporter_dump, "")                                              \
20979 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20980 _(ipfix_classify_stream_dump, "")                                       \
20981 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20982 _(ipfix_classify_table_dump, "")                                        \
20983 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20984 _(sw_interface_span_dump, "[l2]")                                           \
20985 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20986 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20987 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20988 _(pg_enable_disable, "[stream <id>] disable")                           \
20989 _(ip_source_and_port_range_check_add_del,                               \
20990   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20991 _(ip_source_and_port_range_check_interface_add_del,                     \
20992   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20993   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20994 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20995 _(l2_interface_pbb_tag_rewrite,                                         \
20996   "<intfc> | sw_if_index <nn> \n"                                       \
20997   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20998   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20999 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21000 _(flow_classify_set_interface,                                          \
21001   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21002 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21003 _(ip_table_dump, "")                                                    \
21004 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21005 _(ip_mtable_dump, "")                                                   \
21006 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21007 _(feature_enable_disable, "arc_name <arc_name> "                        \
21008   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21009 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21010   "[enable | disable] ")                                                \
21011 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21012 "[disable]")                                                            \
21013 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21014   "mac <mac-address> [del]")                                            \
21015 _(l2_xconnect_dump, "")                                                 \
21016 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21017 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21018 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21019 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21020 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21021 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21022   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21023 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21024 _(sock_init_shm, "size <nnn>")                                          \
21025 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21026 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21027   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21028 _(session_rules_dump, "")                                               \
21029 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21030 _(output_acl_set_interface,                                             \
21031   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21032   "  [l2-table <nn>] [del]")                                            \
21033 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21034
21035 /* List of command functions, CLI names map directly to functions */
21036 #define foreach_cli_function                                    \
21037 _(comment, "usage: comment <ignore-rest-of-line>")              \
21038 _(dump_interface_table, "usage: dump_interface_table")          \
21039 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21040 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21041 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21042 _(dump_macro_table, "usage: dump_macro_table ")                 \
21043 _(dump_node_table, "usage: dump_node_table")                    \
21044 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21045 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21046 _(elog_disable, "usage: elog_disable")                          \
21047 _(elog_enable, "usage: elog_enable")                            \
21048 _(elog_save, "usage: elog_save <filename>")                     \
21049 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21050 _(echo, "usage: echo <message>")                                \
21051 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21052 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21053 _(help, "usage: help")                                          \
21054 _(q, "usage: quit")                                             \
21055 _(quit, "usage: quit")                                          \
21056 _(search_node_table, "usage: search_node_table <name>...")      \
21057 _(set, "usage: set <variable-name> <value>")                    \
21058 _(script, "usage: script <file-name>")                          \
21059 _(statseg, "usage: statseg")                                    \
21060 _(unset, "usage: unset <variable-name>")
21061
21062 #define _(N,n)                                  \
21063     static void vl_api_##n##_t_handler_uni      \
21064     (vl_api_##n##_t * mp)                       \
21065     {                                           \
21066         vat_main_t * vam = &vat_main;           \
21067         if (vam->json_output) {                 \
21068             vl_api_##n##_t_handler_json(mp);    \
21069         } else {                                \
21070             vl_api_##n##_t_handler(mp);         \
21071         }                                       \
21072     }
21073 foreach_vpe_api_reply_msg;
21074 #if VPP_API_TEST_BUILTIN == 0
21075 foreach_standalone_reply_msg;
21076 #endif
21077 #undef _
21078
21079 void
21080 vat_api_hookup (vat_main_t * vam)
21081 {
21082 #define _(N,n)                                                  \
21083     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21084                            vl_api_##n##_t_handler_uni,          \
21085                            vl_noop_handler,                     \
21086                            vl_api_##n##_t_endian,               \
21087                            vl_api_##n##_t_print,                \
21088                            sizeof(vl_api_##n##_t), 1);
21089   foreach_vpe_api_reply_msg;
21090 #if VPP_API_TEST_BUILTIN == 0
21091   foreach_standalone_reply_msg;
21092 #endif
21093 #undef _
21094
21095 #if (VPP_API_TEST_BUILTIN==0)
21096   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21097
21098   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21099
21100   vam->function_by_name = hash_create_string (0, sizeof (uword));
21101
21102   vam->help_by_name = hash_create_string (0, sizeof (uword));
21103 #endif
21104
21105   /* API messages we can send */
21106 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21107   foreach_vpe_api_msg;
21108 #undef _
21109
21110   /* Help strings */
21111 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21112   foreach_vpe_api_msg;
21113 #undef _
21114
21115   /* CLI functions */
21116 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21117   foreach_cli_function;
21118 #undef _
21119
21120   /* Help strings */
21121 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21122   foreach_cli_function;
21123 #undef _
21124 }
21125
21126 #if VPP_API_TEST_BUILTIN
21127 static clib_error_t *
21128 vat_api_hookup_shim (vlib_main_t * vm)
21129 {
21130   vat_api_hookup (&vat_main);
21131   return 0;
21132 }
21133
21134 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21135 #endif
21136
21137 /*
21138  * fd.io coding-style-patch-verification: ON
21139  *
21140  * Local Variables:
21141  * eval: (c-set-style "gnu")
21142  * End:
21143  */