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