vat: add ip api types parser definitions
[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   ip4_address_t local4, remote4;
12710   ip6_address_t local6, remote6;
12711   u8 is_add = 1;
12712   u8 ipv4_set = 0, ipv6_set = 0;
12713   u8 local_set = 0;
12714   u8 remote_set = 0;
12715   u8 grp_set = 0;
12716   u32 mcast_sw_if_index = ~0;
12717   u32 encap_vrf_id = 0;
12718   u32 decap_vrf_id = 0;
12719   u8 protocol = ~0;
12720   u32 vni;
12721   u8 vni_set = 0;
12722   int ret;
12723
12724   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12725   clib_memset (&local4, 0, sizeof local4);
12726   clib_memset (&remote4, 0, sizeof remote4);
12727   clib_memset (&local6, 0, sizeof local6);
12728   clib_memset (&remote6, 0, sizeof remote6);
12729
12730   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12731     {
12732       if (unformat (line_input, "del"))
12733         is_add = 0;
12734       else if (unformat (line_input, "local %U",
12735                          unformat_ip4_address, &local4))
12736         {
12737           local_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "remote %U",
12741                          unformat_ip4_address, &remote4))
12742         {
12743           remote_set = 1;
12744           ipv4_set = 1;
12745         }
12746       else if (unformat (line_input, "local %U",
12747                          unformat_ip6_address, &local6))
12748         {
12749           local_set = 1;
12750           ipv6_set = 1;
12751         }
12752       else if (unformat (line_input, "remote %U",
12753                          unformat_ip6_address, &remote6))
12754         {
12755           remote_set = 1;
12756           ipv6_set = 1;
12757         }
12758       else if (unformat (line_input, "group %U %U",
12759                          unformat_ip4_address, &remote4,
12760                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12761         {
12762           grp_set = remote_set = 1;
12763           ipv4_set = 1;
12764         }
12765       else if (unformat (line_input, "group %U",
12766                          unformat_ip4_address, &remote4))
12767         {
12768           grp_set = remote_set = 1;
12769           ipv4_set = 1;
12770         }
12771       else if (unformat (line_input, "group %U %U",
12772                          unformat_ip6_address, &remote6,
12773                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12774         {
12775           grp_set = remote_set = 1;
12776           ipv6_set = 1;
12777         }
12778       else if (unformat (line_input, "group %U",
12779                          unformat_ip6_address, &remote6))
12780         {
12781           grp_set = remote_set = 1;
12782           ipv6_set = 1;
12783         }
12784       else
12785         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12786         ;
12787       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12788         ;
12789       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12790         ;
12791       else if (unformat (line_input, "vni %d", &vni))
12792         vni_set = 1;
12793       else if (unformat (line_input, "next-ip4"))
12794         protocol = 1;
12795       else if (unformat (line_input, "next-ip6"))
12796         protocol = 2;
12797       else if (unformat (line_input, "next-ethernet"))
12798         protocol = 3;
12799       else if (unformat (line_input, "next-nsh"))
12800         protocol = 4;
12801       else
12802         {
12803           errmsg ("parse error '%U'", format_unformat_error, line_input);
12804           return -99;
12805         }
12806     }
12807
12808   if (local_set == 0)
12809     {
12810       errmsg ("tunnel local address not specified");
12811       return -99;
12812     }
12813   if (remote_set == 0)
12814     {
12815       errmsg ("tunnel remote address not specified");
12816       return -99;
12817     }
12818   if (grp_set && mcast_sw_if_index == ~0)
12819     {
12820       errmsg ("tunnel nonexistent multicast device");
12821       return -99;
12822     }
12823   if (ipv4_set && ipv6_set)
12824     {
12825       errmsg ("both IPv4 and IPv6 addresses specified");
12826       return -99;
12827     }
12828
12829   if (vni_set == 0)
12830     {
12831       errmsg ("vni not specified");
12832       return -99;
12833     }
12834
12835   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12836
12837
12838   if (ipv6_set)
12839     {
12840       clib_memcpy (&mp->local, &local6, sizeof (local6));
12841       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12842     }
12843   else
12844     {
12845       clib_memcpy (&mp->local, &local4, sizeof (local4));
12846       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12847     }
12848
12849   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12850   mp->encap_vrf_id = ntohl (encap_vrf_id);
12851   mp->decap_vrf_id = ntohl (decap_vrf_id);
12852   mp->protocol = protocol;
12853   mp->vni = ntohl (vni);
12854   mp->is_add = is_add;
12855   mp->is_ipv6 = ipv6_set;
12856
12857   S (mp);
12858   W (ret);
12859   return ret;
12860 }
12861
12862 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12863   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12864 {
12865   vat_main_t *vam = &vat_main;
12866   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12867   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12868
12869   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12870          ntohl (mp->sw_if_index),
12871          format_ip46_address, &local, IP46_TYPE_ANY,
12872          format_ip46_address, &remote, IP46_TYPE_ANY,
12873          ntohl (mp->vni), mp->protocol,
12874          ntohl (mp->mcast_sw_if_index),
12875          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12876 }
12877
12878
12879 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12880   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12881 {
12882   vat_main_t *vam = &vat_main;
12883   vat_json_node_t *node = NULL;
12884   struct in_addr ip4;
12885   struct in6_addr ip6;
12886
12887   if (VAT_JSON_ARRAY != vam->json_tree.type)
12888     {
12889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12890       vat_json_init_array (&vam->json_tree);
12891     }
12892   node = vat_json_array_add (&vam->json_tree);
12893
12894   vat_json_init_object (node);
12895   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12896   if (mp->is_ipv6)
12897     {
12898       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12899       vat_json_object_add_ip6 (node, "local", ip6);
12900       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12901       vat_json_object_add_ip6 (node, "remote", ip6);
12902     }
12903   else
12904     {
12905       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12906       vat_json_object_add_ip4 (node, "local", ip4);
12907       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12908       vat_json_object_add_ip4 (node, "remote", ip4);
12909     }
12910   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12911   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12912   vat_json_object_add_uint (node, "mcast_sw_if_index",
12913                             ntohl (mp->mcast_sw_if_index));
12914   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12915   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12916   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12917 }
12918
12919 static int
12920 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12921 {
12922   unformat_input_t *i = vam->input;
12923   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12924   vl_api_control_ping_t *mp_ping;
12925   u32 sw_if_index;
12926   u8 sw_if_index_set = 0;
12927   int ret;
12928
12929   /* Parse args required to build the message */
12930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12931     {
12932       if (unformat (i, "sw_if_index %d", &sw_if_index))
12933         sw_if_index_set = 1;
12934       else
12935         break;
12936     }
12937
12938   if (sw_if_index_set == 0)
12939     {
12940       sw_if_index = ~0;
12941     }
12942
12943   if (!vam->json_output)
12944     {
12945       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12946              "sw_if_index", "local", "remote", "vni",
12947              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12948     }
12949
12950   /* Get list of vxlan-tunnel interfaces */
12951   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12952
12953   mp->sw_if_index = htonl (sw_if_index);
12954
12955   S (mp);
12956
12957   /* Use a control ping for synchronization */
12958   MPING (CONTROL_PING, mp_ping);
12959   S (mp_ping);
12960
12961   W (ret);
12962   return ret;
12963 }
12964
12965 static void vl_api_l2_fib_table_details_t_handler
12966   (vl_api_l2_fib_table_details_t * mp)
12967 {
12968   vat_main_t *vam = &vat_main;
12969
12970   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12971          "       %d       %d     %d",
12972          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12973          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12974          mp->bvi_mac);
12975 }
12976
12977 static void vl_api_l2_fib_table_details_t_handler_json
12978   (vl_api_l2_fib_table_details_t * mp)
12979 {
12980   vat_main_t *vam = &vat_main;
12981   vat_json_node_t *node = NULL;
12982
12983   if (VAT_JSON_ARRAY != vam->json_tree.type)
12984     {
12985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12986       vat_json_init_array (&vam->json_tree);
12987     }
12988   node = vat_json_array_add (&vam->json_tree);
12989
12990   vat_json_init_object (node);
12991   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12992   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12994   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12995   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12996   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12997 }
12998
12999 static int
13000 api_l2_fib_table_dump (vat_main_t * vam)
13001 {
13002   unformat_input_t *i = vam->input;
13003   vl_api_l2_fib_table_dump_t *mp;
13004   vl_api_control_ping_t *mp_ping;
13005   u32 bd_id;
13006   u8 bd_id_set = 0;
13007   int ret;
13008
13009   /* Parse args required to build the message */
13010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13011     {
13012       if (unformat (i, "bd_id %d", &bd_id))
13013         bd_id_set = 1;
13014       else
13015         break;
13016     }
13017
13018   if (bd_id_set == 0)
13019     {
13020       errmsg ("missing bridge domain");
13021       return -99;
13022     }
13023
13024   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13025
13026   /* Get list of l2 fib entries */
13027   M (L2_FIB_TABLE_DUMP, mp);
13028
13029   mp->bd_id = ntohl (bd_id);
13030   S (mp);
13031
13032   /* Use a control ping for synchronization */
13033   MPING (CONTROL_PING, mp_ping);
13034   S (mp_ping);
13035
13036   W (ret);
13037   return ret;
13038 }
13039
13040
13041 static int
13042 api_interface_name_renumber (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_interface_name_renumber_t *mp;
13046   u32 sw_if_index = ~0;
13047   u32 new_show_dev_instance = ~0;
13048   int ret;
13049
13050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13051     {
13052       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13053                     &sw_if_index))
13054         ;
13055       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13056         ;
13057       else if (unformat (line_input, "new_show_dev_instance %d",
13058                          &new_show_dev_instance))
13059         ;
13060       else
13061         break;
13062     }
13063
13064   if (sw_if_index == ~0)
13065     {
13066       errmsg ("missing interface name or sw_if_index");
13067       return -99;
13068     }
13069
13070   if (new_show_dev_instance == ~0)
13071     {
13072       errmsg ("missing new_show_dev_instance");
13073       return -99;
13074     }
13075
13076   M (INTERFACE_NAME_RENUMBER, mp);
13077
13078   mp->sw_if_index = ntohl (sw_if_index);
13079   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13080
13081   S (mp);
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static int
13087 api_want_l2_macs_events (vat_main_t * vam)
13088 {
13089   unformat_input_t *line_input = vam->input;
13090   vl_api_want_l2_macs_events_t *mp;
13091   u8 enable_disable = 1;
13092   u32 scan_delay = 0;
13093   u32 max_macs_in_event = 0;
13094   u32 learn_limit = 0;
13095   int ret;
13096
13097   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13098     {
13099       if (unformat (line_input, "learn-limit %d", &learn_limit))
13100         ;
13101       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13102         ;
13103       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13104         ;
13105       else if (unformat (line_input, "disable"))
13106         enable_disable = 0;
13107       else
13108         break;
13109     }
13110
13111   M (WANT_L2_MACS_EVENTS, mp);
13112   mp->enable_disable = enable_disable;
13113   mp->pid = htonl (getpid ());
13114   mp->learn_limit = htonl (learn_limit);
13115   mp->scan_delay = (u8) scan_delay;
13116   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122 static int
13123 api_input_acl_set_interface (vat_main_t * vam)
13124 {
13125   unformat_input_t *i = vam->input;
13126   vl_api_input_acl_set_interface_t *mp;
13127   u32 sw_if_index;
13128   int sw_if_index_set;
13129   u32 ip4_table_index = ~0;
13130   u32 ip6_table_index = ~0;
13131   u32 l2_table_index = ~0;
13132   u8 is_add = 1;
13133   int ret;
13134
13135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13136     {
13137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13138         sw_if_index_set = 1;
13139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13140         sw_if_index_set = 1;
13141       else if (unformat (i, "del"))
13142         is_add = 0;
13143       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13144         ;
13145       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13146         ;
13147       else if (unformat (i, "l2-table %d", &l2_table_index))
13148         ;
13149       else
13150         {
13151           clib_warning ("parse error '%U'", format_unformat_error, i);
13152           return -99;
13153         }
13154     }
13155
13156   if (sw_if_index_set == 0)
13157     {
13158       errmsg ("missing interface name or sw_if_index");
13159       return -99;
13160     }
13161
13162   M (INPUT_ACL_SET_INTERFACE, mp);
13163
13164   mp->sw_if_index = ntohl (sw_if_index);
13165   mp->ip4_table_index = ntohl (ip4_table_index);
13166   mp->ip6_table_index = ntohl (ip6_table_index);
13167   mp->l2_table_index = ntohl (l2_table_index);
13168   mp->is_add = is_add;
13169
13170   S (mp);
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_output_acl_set_interface (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_output_acl_set_interface_t *mp;
13180   u32 sw_if_index;
13181   int sw_if_index_set;
13182   u32 ip4_table_index = ~0;
13183   u32 ip6_table_index = ~0;
13184   u32 l2_table_index = ~0;
13185   u8 is_add = 1;
13186   int ret;
13187
13188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189     {
13190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13191         sw_if_index_set = 1;
13192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13193         sw_if_index_set = 1;
13194       else if (unformat (i, "del"))
13195         is_add = 0;
13196       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13197         ;
13198       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13199         ;
13200       else if (unformat (i, "l2-table %d", &l2_table_index))
13201         ;
13202       else
13203         {
13204           clib_warning ("parse error '%U'", format_unformat_error, i);
13205           return -99;
13206         }
13207     }
13208
13209   if (sw_if_index_set == 0)
13210     {
13211       errmsg ("missing interface name or sw_if_index");
13212       return -99;
13213     }
13214
13215   M (OUTPUT_ACL_SET_INTERFACE, mp);
13216
13217   mp->sw_if_index = ntohl (sw_if_index);
13218   mp->ip4_table_index = ntohl (ip4_table_index);
13219   mp->ip6_table_index = ntohl (ip6_table_index);
13220   mp->l2_table_index = ntohl (l2_table_index);
13221   mp->is_add = is_add;
13222
13223   S (mp);
13224   W (ret);
13225   return ret;
13226 }
13227
13228 static int
13229 api_ip_address_dump (vat_main_t * vam)
13230 {
13231   unformat_input_t *i = vam->input;
13232   vl_api_ip_address_dump_t *mp;
13233   vl_api_control_ping_t *mp_ping;
13234   u32 sw_if_index = ~0;
13235   u8 sw_if_index_set = 0;
13236   u8 ipv4_set = 0;
13237   u8 ipv6_set = 0;
13238   int ret;
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "sw_if_index %d", &sw_if_index))
13243         sw_if_index_set = 1;
13244       else
13245         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13246         sw_if_index_set = 1;
13247       else if (unformat (i, "ipv4"))
13248         ipv4_set = 1;
13249       else if (unformat (i, "ipv6"))
13250         ipv6_set = 1;
13251       else
13252         break;
13253     }
13254
13255   if (ipv4_set && ipv6_set)
13256     {
13257       errmsg ("ipv4 and ipv6 flags cannot be both set");
13258       return -99;
13259     }
13260
13261   if ((!ipv4_set) && (!ipv6_set))
13262     {
13263       errmsg ("no ipv4 nor ipv6 flag set");
13264       return -99;
13265     }
13266
13267   if (sw_if_index_set == 0)
13268     {
13269       errmsg ("missing interface name or sw_if_index");
13270       return -99;
13271     }
13272
13273   vam->current_sw_if_index = sw_if_index;
13274   vam->is_ipv6 = ipv6_set;
13275
13276   M (IP_ADDRESS_DUMP, mp);
13277   mp->sw_if_index = ntohl (sw_if_index);
13278   mp->is_ipv6 = ipv6_set;
13279   S (mp);
13280
13281   /* Use a control ping for synchronization */
13282   MPING (CONTROL_PING, mp_ping);
13283   S (mp_ping);
13284
13285   W (ret);
13286   return ret;
13287 }
13288
13289 static int
13290 api_ip_dump (vat_main_t * vam)
13291 {
13292   vl_api_ip_dump_t *mp;
13293   vl_api_control_ping_t *mp_ping;
13294   unformat_input_t *in = vam->input;
13295   int ipv4_set = 0;
13296   int ipv6_set = 0;
13297   int is_ipv6;
13298   int i;
13299   int ret;
13300
13301   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13302     {
13303       if (unformat (in, "ipv4"))
13304         ipv4_set = 1;
13305       else if (unformat (in, "ipv6"))
13306         ipv6_set = 1;
13307       else
13308         break;
13309     }
13310
13311   if (ipv4_set && ipv6_set)
13312     {
13313       errmsg ("ipv4 and ipv6 flags cannot be both set");
13314       return -99;
13315     }
13316
13317   if ((!ipv4_set) && (!ipv6_set))
13318     {
13319       errmsg ("no ipv4 nor ipv6 flag set");
13320       return -99;
13321     }
13322
13323   is_ipv6 = ipv6_set;
13324   vam->is_ipv6 = is_ipv6;
13325
13326   /* free old data */
13327   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13328     {
13329       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13330     }
13331   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13332
13333   M (IP_DUMP, mp);
13334   mp->is_ipv6 = ipv6_set;
13335   S (mp);
13336
13337   /* Use a control ping for synchronization */
13338   MPING (CONTROL_PING, mp_ping);
13339   S (mp_ping);
13340
13341   W (ret);
13342   return ret;
13343 }
13344
13345 static int
13346 api_ipsec_spd_add_del (vat_main_t * vam)
13347 {
13348   unformat_input_t *i = vam->input;
13349   vl_api_ipsec_spd_add_del_t *mp;
13350   u32 spd_id = ~0;
13351   u8 is_add = 1;
13352   int ret;
13353
13354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (i, "spd_id %d", &spd_id))
13357         ;
13358       else if (unformat (i, "del"))
13359         is_add = 0;
13360       else
13361         {
13362           clib_warning ("parse error '%U'", format_unformat_error, i);
13363           return -99;
13364         }
13365     }
13366   if (spd_id == ~0)
13367     {
13368       errmsg ("spd_id must be set");
13369       return -99;
13370     }
13371
13372   M (IPSEC_SPD_ADD_DEL, mp);
13373
13374   mp->spd_id = ntohl (spd_id);
13375   mp->is_add = is_add;
13376
13377   S (mp);
13378   W (ret);
13379   return ret;
13380 }
13381
13382 static int
13383 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13384 {
13385   unformat_input_t *i = vam->input;
13386   vl_api_ipsec_interface_add_del_spd_t *mp;
13387   u32 sw_if_index;
13388   u8 sw_if_index_set = 0;
13389   u32 spd_id = (u32) ~ 0;
13390   u8 is_add = 1;
13391   int ret;
13392
13393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13394     {
13395       if (unformat (i, "del"))
13396         is_add = 0;
13397       else if (unformat (i, "spd_id %d", &spd_id))
13398         ;
13399       else
13400         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13401         sw_if_index_set = 1;
13402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13403         sw_if_index_set = 1;
13404       else
13405         {
13406           clib_warning ("parse error '%U'", format_unformat_error, i);
13407           return -99;
13408         }
13409
13410     }
13411
13412   if (spd_id == (u32) ~ 0)
13413     {
13414       errmsg ("spd_id must be set");
13415       return -99;
13416     }
13417
13418   if (sw_if_index_set == 0)
13419     {
13420       errmsg ("missing interface name or sw_if_index");
13421       return -99;
13422     }
13423
13424   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13425
13426   mp->spd_id = ntohl (spd_id);
13427   mp->sw_if_index = ntohl (sw_if_index);
13428   mp->is_add = is_add;
13429
13430   S (mp);
13431   W (ret);
13432   return ret;
13433 }
13434
13435 static int
13436 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13437 {
13438   unformat_input_t *i = vam->input;
13439   vl_api_ipsec_spd_entry_add_del_t *mp;
13440   u8 is_add = 1, is_outbound = 0;
13441   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13442   i32 priority = 0;
13443   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13444   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13445   vl_api_address_t laddr_start = { }, laddr_stop =
13446   {
13447   }, raddr_start =
13448   {
13449   }, raddr_stop =
13450   {
13451   };
13452   int ret;
13453
13454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13455     {
13456       if (unformat (i, "del"))
13457         is_add = 0;
13458       if (unformat (i, "outbound"))
13459         is_outbound = 1;
13460       if (unformat (i, "inbound"))
13461         is_outbound = 0;
13462       else if (unformat (i, "spd_id %d", &spd_id))
13463         ;
13464       else if (unformat (i, "sa_id %d", &sa_id))
13465         ;
13466       else if (unformat (i, "priority %d", &priority))
13467         ;
13468       else if (unformat (i, "protocol %d", &protocol))
13469         ;
13470       else if (unformat (i, "lport_start %d", &lport_start))
13471         ;
13472       else if (unformat (i, "lport_stop %d", &lport_stop))
13473         ;
13474       else if (unformat (i, "rport_start %d", &rport_start))
13475         ;
13476       else if (unformat (i, "rport_stop %d", &rport_stop))
13477         ;
13478       else if (unformat (i, "laddr_start %U",
13479                          unformat_vl_api_address, &laddr_start))
13480         ;
13481       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13482                          &laddr_stop))
13483         ;
13484       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13485                          &raddr_start))
13486         ;
13487       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13488                          &raddr_stop))
13489         ;
13490       else
13491         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13492         {
13493           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13494             {
13495               clib_warning ("unsupported action: 'resolve'");
13496               return -99;
13497             }
13498         }
13499       else
13500         {
13501           clib_warning ("parse error '%U'", format_unformat_error, i);
13502           return -99;
13503         }
13504
13505     }
13506
13507   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13508
13509   mp->is_add = is_add;
13510
13511   mp->entry.spd_id = ntohl (spd_id);
13512   mp->entry.priority = ntohl (priority);
13513   mp->entry.is_outbound = is_outbound;
13514
13515   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13516                sizeof (vl_api_address_t));
13517   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13518                sizeof (vl_api_address_t));
13519   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13520                sizeof (vl_api_address_t));
13521   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13522                sizeof (vl_api_address_t));
13523
13524   mp->entry.protocol = (u8) protocol;
13525   mp->entry.local_port_start = ntohs ((u16) lport_start);
13526   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13527   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13528   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13529   mp->entry.policy = (u8) policy;
13530   mp->entry.sa_id = ntohl (sa_id);
13531
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537 static int
13538 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13539 {
13540   unformat_input_t *i = vam->input;
13541   vl_api_ipsec_sad_entry_add_del_t *mp;
13542   u32 sad_id = 0, spi = 0;
13543   u8 *ck = 0, *ik = 0;
13544   u8 is_add = 1;
13545
13546   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13547   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13548   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13549   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13550   vl_api_address_t tun_src, tun_dst;
13551   int ret;
13552
13553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13554     {
13555       if (unformat (i, "del"))
13556         is_add = 0;
13557       else if (unformat (i, "sad_id %d", &sad_id))
13558         ;
13559       else if (unformat (i, "spi %d", &spi))
13560         ;
13561       else if (unformat (i, "esp"))
13562         protocol = IPSEC_API_PROTO_ESP;
13563       else
13564         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13565         {
13566           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13567           if (ADDRESS_IP6 == tun_src.af)
13568             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13569         }
13570       else
13571         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13572         {
13573           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13574           if (ADDRESS_IP6 == tun_src.af)
13575             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13576         }
13577       else
13578         if (unformat (i, "crypto_alg %U",
13579                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13580         ;
13581       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13582         ;
13583       else if (unformat (i, "integ_alg %U",
13584                          unformat_ipsec_api_integ_alg, &integ_alg))
13585         ;
13586       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13587         ;
13588       else
13589         {
13590           clib_warning ("parse error '%U'", format_unformat_error, i);
13591           return -99;
13592         }
13593
13594     }
13595
13596   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13597
13598   mp->is_add = is_add;
13599   mp->entry.sad_id = ntohl (sad_id);
13600   mp->entry.protocol = protocol;
13601   mp->entry.spi = ntohl (spi);
13602   mp->entry.flags = flags;
13603
13604   mp->entry.crypto_algorithm = crypto_alg;
13605   mp->entry.integrity_algorithm = integ_alg;
13606   mp->entry.crypto_key.length = vec_len (ck);
13607   mp->entry.integrity_key.length = vec_len (ik);
13608
13609   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13610     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13611
13612   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13613     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13614
13615   if (ck)
13616     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13617   if (ik)
13618     clib_memcpy (mp->entry.integrity_key.data, ik,
13619                  mp->entry.integrity_key.length);
13620
13621   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13622     {
13623       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13624                    sizeof (mp->entry.tunnel_src));
13625       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13626                    sizeof (mp->entry.tunnel_dst));
13627     }
13628
13629   S (mp);
13630   W (ret);
13631   return ret;
13632 }
13633
13634 static int
13635 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13636 {
13637   unformat_input_t *i = vam->input;
13638   vl_api_ipsec_tunnel_if_add_del_t *mp;
13639   u32 local_spi = 0, remote_spi = 0;
13640   u32 crypto_alg = 0, integ_alg = 0;
13641   u8 *lck = NULL, *rck = NULL;
13642   u8 *lik = NULL, *rik = NULL;
13643   vl_api_address_t local_ip = { 0 };
13644   vl_api_address_t remote_ip = { 0 };
13645   f64 before = 0;
13646   u8 is_add = 1;
13647   u8 esn = 0;
13648   u8 anti_replay = 0;
13649   u8 renumber = 0;
13650   u32 instance = ~0;
13651   u32 count = 1, jj;
13652   int ret = -1;
13653
13654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13655     {
13656       if (unformat (i, "del"))
13657         is_add = 0;
13658       else if (unformat (i, "esn"))
13659         esn = 1;
13660       else if (unformat (i, "anti-replay"))
13661         anti_replay = 1;
13662       else if (unformat (i, "count %d", &count))
13663         ;
13664       else if (unformat (i, "local_spi %d", &local_spi))
13665         ;
13666       else if (unformat (i, "remote_spi %d", &remote_spi))
13667         ;
13668       else
13669         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13670         ;
13671       else
13672         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13673         ;
13674       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13675         ;
13676       else
13677         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13678         ;
13679       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13680         ;
13681       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13682         ;
13683       else
13684         if (unformat
13685             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13686         {
13687           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13688             {
13689               errmsg ("unsupported crypto-alg: '%U'\n",
13690                       format_ipsec_crypto_alg, crypto_alg);
13691               return -99;
13692             }
13693         }
13694       else
13695         if (unformat
13696             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13697         {
13698           if (integ_alg >= IPSEC_INTEG_N_ALG)
13699             {
13700               errmsg ("unsupported integ-alg: '%U'\n",
13701                       format_ipsec_integ_alg, integ_alg);
13702               return -99;
13703             }
13704         }
13705       else if (unformat (i, "instance %u", &instance))
13706         renumber = 1;
13707       else
13708         {
13709           errmsg ("parse error '%U'\n", format_unformat_error, i);
13710           return -99;
13711         }
13712     }
13713
13714   if (count > 1)
13715     {
13716       /* Turn on async mode */
13717       vam->async_mode = 1;
13718       vam->async_errors = 0;
13719       before = vat_time_now (vam);
13720     }
13721
13722   for (jj = 0; jj < count; jj++)
13723     {
13724       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13725
13726       mp->is_add = is_add;
13727       mp->esn = esn;
13728       mp->anti_replay = anti_replay;
13729
13730       if (jj > 0)
13731         increment_address (&remote_ip);
13732
13733       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13734       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13735
13736       mp->local_spi = htonl (local_spi + jj);
13737       mp->remote_spi = htonl (remote_spi + jj);
13738       mp->crypto_alg = (u8) crypto_alg;
13739
13740       mp->local_crypto_key_len = 0;
13741       if (lck)
13742         {
13743           mp->local_crypto_key_len = vec_len (lck);
13744           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13745             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13746           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13747         }
13748
13749       mp->remote_crypto_key_len = 0;
13750       if (rck)
13751         {
13752           mp->remote_crypto_key_len = vec_len (rck);
13753           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13754             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13755           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13756         }
13757
13758       mp->integ_alg = (u8) integ_alg;
13759
13760       mp->local_integ_key_len = 0;
13761       if (lik)
13762         {
13763           mp->local_integ_key_len = vec_len (lik);
13764           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13765             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13766           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13767         }
13768
13769       mp->remote_integ_key_len = 0;
13770       if (rik)
13771         {
13772           mp->remote_integ_key_len = vec_len (rik);
13773           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13774             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13775           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13776         }
13777
13778       if (renumber)
13779         {
13780           mp->renumber = renumber;
13781           mp->show_instance = ntohl (instance);
13782         }
13783       S (mp);
13784     }
13785
13786   /* When testing multiple add/del ops, use a control-ping to sync */
13787   if (count > 1)
13788     {
13789       vl_api_control_ping_t *mp_ping;
13790       f64 after;
13791       f64 timeout;
13792
13793       /* Shut off async mode */
13794       vam->async_mode = 0;
13795
13796       MPING (CONTROL_PING, mp_ping);
13797       S (mp_ping);
13798
13799       timeout = vat_time_now (vam) + 1.0;
13800       while (vat_time_now (vam) < timeout)
13801         if (vam->result_ready == 1)
13802           goto out;
13803       vam->retval = -99;
13804
13805     out:
13806       if (vam->retval == -99)
13807         errmsg ("timeout");
13808
13809       if (vam->async_errors > 0)
13810         {
13811           errmsg ("%d asynchronous errors", vam->async_errors);
13812           vam->retval = -98;
13813         }
13814       vam->async_errors = 0;
13815       after = vat_time_now (vam);
13816
13817       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13818       if (jj > 0)
13819         count = jj;
13820
13821       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13822              count, after - before, count / (after - before));
13823     }
13824   else
13825     {
13826       /* Wait for a reply... */
13827       W (ret);
13828       return ret;
13829     }
13830
13831   return ret;
13832 }
13833
13834 static void
13835 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13836 {
13837   vat_main_t *vam = &vat_main;
13838
13839   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13840          "crypto_key %U integ_alg %u integ_key %U flags %x "
13841          "tunnel_src_addr %U tunnel_dst_addr %U "
13842          "salt %u seq_outbound %lu last_seq_inbound %lu "
13843          "replay_window %lu\n",
13844          ntohl (mp->entry.sad_id),
13845          ntohl (mp->sw_if_index),
13846          ntohl (mp->entry.spi),
13847          ntohl (mp->entry.protocol),
13848          ntohl (mp->entry.crypto_algorithm),
13849          format_hex_bytes, mp->entry.crypto_key.data,
13850          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13851          format_hex_bytes, mp->entry.integrity_key.data,
13852          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13853          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13854          &mp->entry.tunnel_dst, ntohl (mp->salt),
13855          clib_net_to_host_u64 (mp->seq_outbound),
13856          clib_net_to_host_u64 (mp->last_seq_inbound),
13857          clib_net_to_host_u64 (mp->replay_window));
13858 }
13859
13860 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13861 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13862
13863 static void vl_api_ipsec_sa_details_t_handler_json
13864   (vl_api_ipsec_sa_details_t * mp)
13865 {
13866   vat_main_t *vam = &vat_main;
13867   vat_json_node_t *node = NULL;
13868   vl_api_ipsec_sad_flags_t flags;
13869
13870   if (VAT_JSON_ARRAY != vam->json_tree.type)
13871     {
13872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13873       vat_json_init_array (&vam->json_tree);
13874     }
13875   node = vat_json_array_add (&vam->json_tree);
13876
13877   vat_json_init_object (node);
13878   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13879   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13880   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13881   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13882   vat_json_object_add_uint (node, "crypto_alg",
13883                             ntohl (mp->entry.crypto_algorithm));
13884   vat_json_object_add_uint (node, "integ_alg",
13885                             ntohl (mp->entry.integrity_algorithm));
13886   flags = ntohl (mp->entry.flags);
13887   vat_json_object_add_uint (node, "use_esn",
13888                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13889   vat_json_object_add_uint (node, "use_anti_replay",
13890                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13891   vat_json_object_add_uint (node, "is_tunnel",
13892                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13893   vat_json_object_add_uint (node, "is_tunnel_ip6",
13894                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13895   vat_json_object_add_uint (node, "udp_encap",
13896                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13897   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13898                              mp->entry.crypto_key.length);
13899   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13900                              mp->entry.integrity_key.length);
13901   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13902   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13903   vat_json_object_add_uint (node, "replay_window",
13904                             clib_net_to_host_u64 (mp->replay_window));
13905 }
13906
13907 static int
13908 api_ipsec_sa_dump (vat_main_t * vam)
13909 {
13910   unformat_input_t *i = vam->input;
13911   vl_api_ipsec_sa_dump_t *mp;
13912   vl_api_control_ping_t *mp_ping;
13913   u32 sa_id = ~0;
13914   int ret;
13915
13916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13917     {
13918       if (unformat (i, "sa_id %d", &sa_id))
13919         ;
13920       else
13921         {
13922           clib_warning ("parse error '%U'", format_unformat_error, i);
13923           return -99;
13924         }
13925     }
13926
13927   M (IPSEC_SA_DUMP, mp);
13928
13929   mp->sa_id = ntohl (sa_id);
13930
13931   S (mp);
13932
13933   /* Use a control ping for synchronization */
13934   M (CONTROL_PING, mp_ping);
13935   S (mp_ping);
13936
13937   W (ret);
13938   return ret;
13939 }
13940
13941 static int
13942 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13943 {
13944   unformat_input_t *i = vam->input;
13945   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13946   u32 sw_if_index = ~0;
13947   u32 sa_id = ~0;
13948   u8 is_outbound = (u8) ~ 0;
13949   int ret;
13950
13951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13952     {
13953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13954         ;
13955       else if (unformat (i, "sa_id %d", &sa_id))
13956         ;
13957       else if (unformat (i, "outbound"))
13958         is_outbound = 1;
13959       else if (unformat (i, "inbound"))
13960         is_outbound = 0;
13961       else
13962         {
13963           clib_warning ("parse error '%U'", format_unformat_error, i);
13964           return -99;
13965         }
13966     }
13967
13968   if (sw_if_index == ~0)
13969     {
13970       errmsg ("interface must be specified");
13971       return -99;
13972     }
13973
13974   if (sa_id == ~0)
13975     {
13976       errmsg ("SA ID must be specified");
13977       return -99;
13978     }
13979
13980   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13981
13982   mp->sw_if_index = htonl (sw_if_index);
13983   mp->sa_id = htonl (sa_id);
13984   mp->is_outbound = is_outbound;
13985
13986   S (mp);
13987   W (ret);
13988
13989   return ret;
13990 }
13991
13992 static int
13993 api_get_first_msg_id (vat_main_t * vam)
13994 {
13995   vl_api_get_first_msg_id_t *mp;
13996   unformat_input_t *i = vam->input;
13997   u8 *name;
13998   u8 name_set = 0;
13999   int ret;
14000
14001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14002     {
14003       if (unformat (i, "client %s", &name))
14004         name_set = 1;
14005       else
14006         break;
14007     }
14008
14009   if (name_set == 0)
14010     {
14011       errmsg ("missing client name");
14012       return -99;
14013     }
14014   vec_add1 (name, 0);
14015
14016   if (vec_len (name) > 63)
14017     {
14018       errmsg ("client name too long");
14019       return -99;
14020     }
14021
14022   M (GET_FIRST_MSG_ID, mp);
14023   clib_memcpy (mp->name, name, vec_len (name));
14024   S (mp);
14025   W (ret);
14026   return ret;
14027 }
14028
14029 static int
14030 api_cop_interface_enable_disable (vat_main_t * vam)
14031 {
14032   unformat_input_t *line_input = vam->input;
14033   vl_api_cop_interface_enable_disable_t *mp;
14034   u32 sw_if_index = ~0;
14035   u8 enable_disable = 1;
14036   int ret;
14037
14038   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14039     {
14040       if (unformat (line_input, "disable"))
14041         enable_disable = 0;
14042       if (unformat (line_input, "enable"))
14043         enable_disable = 1;
14044       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14045                          vam, &sw_if_index))
14046         ;
14047       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14048         ;
14049       else
14050         break;
14051     }
14052
14053   if (sw_if_index == ~0)
14054     {
14055       errmsg ("missing interface name or sw_if_index");
14056       return -99;
14057     }
14058
14059   /* Construct the API message */
14060   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14061   mp->sw_if_index = ntohl (sw_if_index);
14062   mp->enable_disable = enable_disable;
14063
14064   /* send it... */
14065   S (mp);
14066   /* Wait for the reply */
14067   W (ret);
14068   return ret;
14069 }
14070
14071 static int
14072 api_cop_whitelist_enable_disable (vat_main_t * vam)
14073 {
14074   unformat_input_t *line_input = vam->input;
14075   vl_api_cop_whitelist_enable_disable_t *mp;
14076   u32 sw_if_index = ~0;
14077   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14078   u32 fib_id = 0;
14079   int ret;
14080
14081   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14082     {
14083       if (unformat (line_input, "ip4"))
14084         ip4 = 1;
14085       else if (unformat (line_input, "ip6"))
14086         ip6 = 1;
14087       else if (unformat (line_input, "default"))
14088         default_cop = 1;
14089       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14090                          vam, &sw_if_index))
14091         ;
14092       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14093         ;
14094       else if (unformat (line_input, "fib-id %d", &fib_id))
14095         ;
14096       else
14097         break;
14098     }
14099
14100   if (sw_if_index == ~0)
14101     {
14102       errmsg ("missing interface name or sw_if_index");
14103       return -99;
14104     }
14105
14106   /* Construct the API message */
14107   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14108   mp->sw_if_index = ntohl (sw_if_index);
14109   mp->fib_id = ntohl (fib_id);
14110   mp->ip4 = ip4;
14111   mp->ip6 = ip6;
14112   mp->default_cop = default_cop;
14113
14114   /* send it... */
14115   S (mp);
14116   /* Wait for the reply */
14117   W (ret);
14118   return ret;
14119 }
14120
14121 static int
14122 api_get_node_graph (vat_main_t * vam)
14123 {
14124   vl_api_get_node_graph_t *mp;
14125   int ret;
14126
14127   M (GET_NODE_GRAPH, mp);
14128
14129   /* send it... */
14130   S (mp);
14131   /* Wait for the reply */
14132   W (ret);
14133   return ret;
14134 }
14135
14136 /* *INDENT-OFF* */
14137 /** Used for parsing LISP eids */
14138 typedef CLIB_PACKED(struct{
14139   u8 addr[16];   /**< eid address */
14140   u32 len;       /**< prefix length if IP */
14141   u8 type;      /**< type of eid */
14142 }) lisp_eid_vat_t;
14143 /* *INDENT-ON* */
14144
14145 static uword
14146 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14147 {
14148   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14149
14150   clib_memset (a, 0, sizeof (a[0]));
14151
14152   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14153     {
14154       a->type = 0;              /* ipv4 type */
14155     }
14156   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14157     {
14158       a->type = 1;              /* ipv6 type */
14159     }
14160   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14161     {
14162       a->type = 2;              /* mac type */
14163     }
14164   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14165     {
14166       a->type = 3;              /* NSH type */
14167       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14168       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14169     }
14170   else
14171     {
14172       return 0;
14173     }
14174
14175   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14176     {
14177       return 0;
14178     }
14179
14180   return 1;
14181 }
14182
14183 static int
14184 lisp_eid_size_vat (u8 type)
14185 {
14186   switch (type)
14187     {
14188     case 0:
14189       return 4;
14190     case 1:
14191       return 16;
14192     case 2:
14193       return 6;
14194     case 3:
14195       return 5;
14196     }
14197   return 0;
14198 }
14199
14200 static void
14201 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14202 {
14203   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14204 }
14205
14206 static int
14207 api_one_add_del_locator_set (vat_main_t * vam)
14208 {
14209   unformat_input_t *input = vam->input;
14210   vl_api_one_add_del_locator_set_t *mp;
14211   u8 is_add = 1;
14212   u8 *locator_set_name = NULL;
14213   u8 locator_set_name_set = 0;
14214   vl_api_local_locator_t locator, *locators = 0;
14215   u32 sw_if_index, priority, weight;
14216   u32 data_len = 0;
14217
14218   int ret;
14219   /* Parse args required to build the message */
14220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14221     {
14222       if (unformat (input, "del"))
14223         {
14224           is_add = 0;
14225         }
14226       else if (unformat (input, "locator-set %s", &locator_set_name))
14227         {
14228           locator_set_name_set = 1;
14229         }
14230       else if (unformat (input, "sw_if_index %u p %u w %u",
14231                          &sw_if_index, &priority, &weight))
14232         {
14233           locator.sw_if_index = htonl (sw_if_index);
14234           locator.priority = priority;
14235           locator.weight = weight;
14236           vec_add1 (locators, locator);
14237         }
14238       else
14239         if (unformat
14240             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14241              &sw_if_index, &priority, &weight))
14242         {
14243           locator.sw_if_index = htonl (sw_if_index);
14244           locator.priority = priority;
14245           locator.weight = weight;
14246           vec_add1 (locators, locator);
14247         }
14248       else
14249         break;
14250     }
14251
14252   if (locator_set_name_set == 0)
14253     {
14254       errmsg ("missing locator-set name");
14255       vec_free (locators);
14256       return -99;
14257     }
14258
14259   if (vec_len (locator_set_name) > 64)
14260     {
14261       errmsg ("locator-set name too long");
14262       vec_free (locator_set_name);
14263       vec_free (locators);
14264       return -99;
14265     }
14266   vec_add1 (locator_set_name, 0);
14267
14268   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14269
14270   /* Construct the API message */
14271   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14272
14273   mp->is_add = is_add;
14274   clib_memcpy (mp->locator_set_name, locator_set_name,
14275                vec_len (locator_set_name));
14276   vec_free (locator_set_name);
14277
14278   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14279   if (locators)
14280     clib_memcpy (mp->locators, locators, data_len);
14281   vec_free (locators);
14282
14283   /* send it... */
14284   S (mp);
14285
14286   /* Wait for a reply... */
14287   W (ret);
14288   return ret;
14289 }
14290
14291 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14292
14293 static int
14294 api_one_add_del_locator (vat_main_t * vam)
14295 {
14296   unformat_input_t *input = vam->input;
14297   vl_api_one_add_del_locator_t *mp;
14298   u32 tmp_if_index = ~0;
14299   u32 sw_if_index = ~0;
14300   u8 sw_if_index_set = 0;
14301   u8 sw_if_index_if_name_set = 0;
14302   u32 priority = ~0;
14303   u8 priority_set = 0;
14304   u32 weight = ~0;
14305   u8 weight_set = 0;
14306   u8 is_add = 1;
14307   u8 *locator_set_name = NULL;
14308   u8 locator_set_name_set = 0;
14309   int ret;
14310
14311   /* Parse args required to build the message */
14312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14313     {
14314       if (unformat (input, "del"))
14315         {
14316           is_add = 0;
14317         }
14318       else if (unformat (input, "locator-set %s", &locator_set_name))
14319         {
14320           locator_set_name_set = 1;
14321         }
14322       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14323                          &tmp_if_index))
14324         {
14325           sw_if_index_if_name_set = 1;
14326           sw_if_index = tmp_if_index;
14327         }
14328       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14329         {
14330           sw_if_index_set = 1;
14331           sw_if_index = tmp_if_index;
14332         }
14333       else if (unformat (input, "p %d", &priority))
14334         {
14335           priority_set = 1;
14336         }
14337       else if (unformat (input, "w %d", &weight))
14338         {
14339           weight_set = 1;
14340         }
14341       else
14342         break;
14343     }
14344
14345   if (locator_set_name_set == 0)
14346     {
14347       errmsg ("missing locator-set name");
14348       return -99;
14349     }
14350
14351   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14352     {
14353       errmsg ("missing sw_if_index");
14354       vec_free (locator_set_name);
14355       return -99;
14356     }
14357
14358   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14359     {
14360       errmsg ("cannot use both params interface name and sw_if_index");
14361       vec_free (locator_set_name);
14362       return -99;
14363     }
14364
14365   if (priority_set == 0)
14366     {
14367       errmsg ("missing locator-set priority");
14368       vec_free (locator_set_name);
14369       return -99;
14370     }
14371
14372   if (weight_set == 0)
14373     {
14374       errmsg ("missing locator-set weight");
14375       vec_free (locator_set_name);
14376       return -99;
14377     }
14378
14379   if (vec_len (locator_set_name) > 64)
14380     {
14381       errmsg ("locator-set name too long");
14382       vec_free (locator_set_name);
14383       return -99;
14384     }
14385   vec_add1 (locator_set_name, 0);
14386
14387   /* Construct the API message */
14388   M (ONE_ADD_DEL_LOCATOR, mp);
14389
14390   mp->is_add = is_add;
14391   mp->sw_if_index = ntohl (sw_if_index);
14392   mp->priority = priority;
14393   mp->weight = weight;
14394   clib_memcpy (mp->locator_set_name, locator_set_name,
14395                vec_len (locator_set_name));
14396   vec_free (locator_set_name);
14397
14398   /* send it... */
14399   S (mp);
14400
14401   /* Wait for a reply... */
14402   W (ret);
14403   return ret;
14404 }
14405
14406 #define api_lisp_add_del_locator api_one_add_del_locator
14407
14408 uword
14409 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14410 {
14411   u32 *key_id = va_arg (*args, u32 *);
14412   u8 *s = 0;
14413
14414   if (unformat (input, "%s", &s))
14415     {
14416       if (!strcmp ((char *) s, "sha1"))
14417         key_id[0] = HMAC_SHA_1_96;
14418       else if (!strcmp ((char *) s, "sha256"))
14419         key_id[0] = HMAC_SHA_256_128;
14420       else
14421         {
14422           clib_warning ("invalid key_id: '%s'", s);
14423           key_id[0] = HMAC_NO_KEY;
14424         }
14425     }
14426   else
14427     return 0;
14428
14429   vec_free (s);
14430   return 1;
14431 }
14432
14433 static int
14434 api_one_add_del_local_eid (vat_main_t * vam)
14435 {
14436   unformat_input_t *input = vam->input;
14437   vl_api_one_add_del_local_eid_t *mp;
14438   u8 is_add = 1;
14439   u8 eid_set = 0;
14440   lisp_eid_vat_t _eid, *eid = &_eid;
14441   u8 *locator_set_name = 0;
14442   u8 locator_set_name_set = 0;
14443   u32 vni = 0;
14444   u16 key_id = 0;
14445   u8 *key = 0;
14446   int ret;
14447
14448   /* Parse args required to build the message */
14449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14450     {
14451       if (unformat (input, "del"))
14452         {
14453           is_add = 0;
14454         }
14455       else if (unformat (input, "vni %d", &vni))
14456         {
14457           ;
14458         }
14459       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14460         {
14461           eid_set = 1;
14462         }
14463       else if (unformat (input, "locator-set %s", &locator_set_name))
14464         {
14465           locator_set_name_set = 1;
14466         }
14467       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14468         ;
14469       else if (unformat (input, "secret-key %_%v%_", &key))
14470         ;
14471       else
14472         break;
14473     }
14474
14475   if (locator_set_name_set == 0)
14476     {
14477       errmsg ("missing locator-set name");
14478       return -99;
14479     }
14480
14481   if (0 == eid_set)
14482     {
14483       errmsg ("EID address not set!");
14484       vec_free (locator_set_name);
14485       return -99;
14486     }
14487
14488   if (key && (0 == key_id))
14489     {
14490       errmsg ("invalid key_id!");
14491       return -99;
14492     }
14493
14494   if (vec_len (key) > 64)
14495     {
14496       errmsg ("key too long");
14497       vec_free (key);
14498       return -99;
14499     }
14500
14501   if (vec_len (locator_set_name) > 64)
14502     {
14503       errmsg ("locator-set name too long");
14504       vec_free (locator_set_name);
14505       return -99;
14506     }
14507   vec_add1 (locator_set_name, 0);
14508
14509   /* Construct the API message */
14510   M (ONE_ADD_DEL_LOCAL_EID, mp);
14511
14512   mp->is_add = is_add;
14513   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14514   mp->eid_type = eid->type;
14515   mp->prefix_len = eid->len;
14516   mp->vni = clib_host_to_net_u32 (vni);
14517   mp->key_id = clib_host_to_net_u16 (key_id);
14518   clib_memcpy (mp->locator_set_name, locator_set_name,
14519                vec_len (locator_set_name));
14520   clib_memcpy (mp->key, key, vec_len (key));
14521
14522   vec_free (locator_set_name);
14523   vec_free (key);
14524
14525   /* send it... */
14526   S (mp);
14527
14528   /* Wait for a reply... */
14529   W (ret);
14530   return ret;
14531 }
14532
14533 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14534
14535 static int
14536 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14537 {
14538   u32 dp_table = 0, vni = 0;;
14539   unformat_input_t *input = vam->input;
14540   vl_api_gpe_add_del_fwd_entry_t *mp;
14541   u8 is_add = 1;
14542   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14543   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14544   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14545   u32 action = ~0, w;
14546   ip4_address_t rmt_rloc4, lcl_rloc4;
14547   ip6_address_t rmt_rloc6, lcl_rloc6;
14548   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14549   int ret;
14550
14551   clib_memset (&rloc, 0, sizeof (rloc));
14552
14553   /* Parse args required to build the message */
14554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14555     {
14556       if (unformat (input, "del"))
14557         is_add = 0;
14558       else if (unformat (input, "add"))
14559         is_add = 1;
14560       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14561         {
14562           rmt_eid_set = 1;
14563         }
14564       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14565         {
14566           lcl_eid_set = 1;
14567         }
14568       else if (unformat (input, "vrf %d", &dp_table))
14569         ;
14570       else if (unformat (input, "bd %d", &dp_table))
14571         ;
14572       else if (unformat (input, "vni %d", &vni))
14573         ;
14574       else if (unformat (input, "w %d", &w))
14575         {
14576           if (!curr_rloc)
14577             {
14578               errmsg ("No RLOC configured for setting priority/weight!");
14579               return -99;
14580             }
14581           curr_rloc->weight = w;
14582         }
14583       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14584                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14585         {
14586           rloc.is_ip4 = 1;
14587
14588           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14589           rloc.weight = 0;
14590           vec_add1 (lcl_locs, rloc);
14591
14592           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14593           vec_add1 (rmt_locs, rloc);
14594           /* weight saved in rmt loc */
14595           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14596         }
14597       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14598                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14599         {
14600           rloc.is_ip4 = 0;
14601           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14602           rloc.weight = 0;
14603           vec_add1 (lcl_locs, rloc);
14604
14605           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14606           vec_add1 (rmt_locs, rloc);
14607           /* weight saved in rmt loc */
14608           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14609         }
14610       else if (unformat (input, "action %d", &action))
14611         {
14612           ;
14613         }
14614       else
14615         {
14616           clib_warning ("parse error '%U'", format_unformat_error, input);
14617           return -99;
14618         }
14619     }
14620
14621   if (!rmt_eid_set)
14622     {
14623       errmsg ("remote eid addresses not set");
14624       return -99;
14625     }
14626
14627   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14628     {
14629       errmsg ("eid types don't match");
14630       return -99;
14631     }
14632
14633   if (0 == rmt_locs && (u32) ~ 0 == action)
14634     {
14635       errmsg ("action not set for negative mapping");
14636       return -99;
14637     }
14638
14639   /* Construct the API message */
14640   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14641       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14642
14643   mp->is_add = is_add;
14644   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14645   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14646   mp->eid_type = rmt_eid->type;
14647   mp->dp_table = clib_host_to_net_u32 (dp_table);
14648   mp->vni = clib_host_to_net_u32 (vni);
14649   mp->rmt_len = rmt_eid->len;
14650   mp->lcl_len = lcl_eid->len;
14651   mp->action = action;
14652
14653   if (0 != rmt_locs && 0 != lcl_locs)
14654     {
14655       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14656       clib_memcpy (mp->locs, lcl_locs,
14657                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14658
14659       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14660       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14661                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14662     }
14663   vec_free (lcl_locs);
14664   vec_free (rmt_locs);
14665
14666   /* send it... */
14667   S (mp);
14668
14669   /* Wait for a reply... */
14670   W (ret);
14671   return ret;
14672 }
14673
14674 static int
14675 api_one_add_del_map_server (vat_main_t * vam)
14676 {
14677   unformat_input_t *input = vam->input;
14678   vl_api_one_add_del_map_server_t *mp;
14679   u8 is_add = 1;
14680   u8 ipv4_set = 0;
14681   u8 ipv6_set = 0;
14682   ip4_address_t ipv4;
14683   ip6_address_t ipv6;
14684   int ret;
14685
14686   /* Parse args required to build the message */
14687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14688     {
14689       if (unformat (input, "del"))
14690         {
14691           is_add = 0;
14692         }
14693       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14694         {
14695           ipv4_set = 1;
14696         }
14697       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14698         {
14699           ipv6_set = 1;
14700         }
14701       else
14702         break;
14703     }
14704
14705   if (ipv4_set && ipv6_set)
14706     {
14707       errmsg ("both eid v4 and v6 addresses set");
14708       return -99;
14709     }
14710
14711   if (!ipv4_set && !ipv6_set)
14712     {
14713       errmsg ("eid addresses not set");
14714       return -99;
14715     }
14716
14717   /* Construct the API message */
14718   M (ONE_ADD_DEL_MAP_SERVER, mp);
14719
14720   mp->is_add = is_add;
14721   if (ipv6_set)
14722     {
14723       mp->is_ipv6 = 1;
14724       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14725     }
14726   else
14727     {
14728       mp->is_ipv6 = 0;
14729       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14730     }
14731
14732   /* send it... */
14733   S (mp);
14734
14735   /* Wait for a reply... */
14736   W (ret);
14737   return ret;
14738 }
14739
14740 #define api_lisp_add_del_map_server api_one_add_del_map_server
14741
14742 static int
14743 api_one_add_del_map_resolver (vat_main_t * vam)
14744 {
14745   unformat_input_t *input = vam->input;
14746   vl_api_one_add_del_map_resolver_t *mp;
14747   u8 is_add = 1;
14748   u8 ipv4_set = 0;
14749   u8 ipv6_set = 0;
14750   ip4_address_t ipv4;
14751   ip6_address_t ipv6;
14752   int ret;
14753
14754   /* Parse args required to build the message */
14755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14756     {
14757       if (unformat (input, "del"))
14758         {
14759           is_add = 0;
14760         }
14761       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14762         {
14763           ipv4_set = 1;
14764         }
14765       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14766         {
14767           ipv6_set = 1;
14768         }
14769       else
14770         break;
14771     }
14772
14773   if (ipv4_set && ipv6_set)
14774     {
14775       errmsg ("both eid v4 and v6 addresses set");
14776       return -99;
14777     }
14778
14779   if (!ipv4_set && !ipv6_set)
14780     {
14781       errmsg ("eid addresses not set");
14782       return -99;
14783     }
14784
14785   /* Construct the API message */
14786   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14787
14788   mp->is_add = is_add;
14789   if (ipv6_set)
14790     {
14791       mp->is_ipv6 = 1;
14792       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14793     }
14794   else
14795     {
14796       mp->is_ipv6 = 0;
14797       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14798     }
14799
14800   /* send it... */
14801   S (mp);
14802
14803   /* Wait for a reply... */
14804   W (ret);
14805   return ret;
14806 }
14807
14808 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14809
14810 static int
14811 api_lisp_gpe_enable_disable (vat_main_t * vam)
14812 {
14813   unformat_input_t *input = vam->input;
14814   vl_api_gpe_enable_disable_t *mp;
14815   u8 is_set = 0;
14816   u8 is_en = 1;
14817   int ret;
14818
14819   /* Parse args required to build the message */
14820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14821     {
14822       if (unformat (input, "enable"))
14823         {
14824           is_set = 1;
14825           is_en = 1;
14826         }
14827       else if (unformat (input, "disable"))
14828         {
14829           is_set = 1;
14830           is_en = 0;
14831         }
14832       else
14833         break;
14834     }
14835
14836   if (is_set == 0)
14837     {
14838       errmsg ("Value not set");
14839       return -99;
14840     }
14841
14842   /* Construct the API message */
14843   M (GPE_ENABLE_DISABLE, mp);
14844
14845   mp->is_en = is_en;
14846
14847   /* send it... */
14848   S (mp);
14849
14850   /* Wait for a reply... */
14851   W (ret);
14852   return ret;
14853 }
14854
14855 static int
14856 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14857 {
14858   unformat_input_t *input = vam->input;
14859   vl_api_one_rloc_probe_enable_disable_t *mp;
14860   u8 is_set = 0;
14861   u8 is_en = 0;
14862   int ret;
14863
14864   /* Parse args required to build the message */
14865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14866     {
14867       if (unformat (input, "enable"))
14868         {
14869           is_set = 1;
14870           is_en = 1;
14871         }
14872       else if (unformat (input, "disable"))
14873         is_set = 1;
14874       else
14875         break;
14876     }
14877
14878   if (!is_set)
14879     {
14880       errmsg ("Value not set");
14881       return -99;
14882     }
14883
14884   /* Construct the API message */
14885   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14886
14887   mp->is_enabled = is_en;
14888
14889   /* send it... */
14890   S (mp);
14891
14892   /* Wait for a reply... */
14893   W (ret);
14894   return ret;
14895 }
14896
14897 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14898
14899 static int
14900 api_one_map_register_enable_disable (vat_main_t * vam)
14901 {
14902   unformat_input_t *input = vam->input;
14903   vl_api_one_map_register_enable_disable_t *mp;
14904   u8 is_set = 0;
14905   u8 is_en = 0;
14906   int ret;
14907
14908   /* Parse args required to build the message */
14909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14910     {
14911       if (unformat (input, "enable"))
14912         {
14913           is_set = 1;
14914           is_en = 1;
14915         }
14916       else if (unformat (input, "disable"))
14917         is_set = 1;
14918       else
14919         break;
14920     }
14921
14922   if (!is_set)
14923     {
14924       errmsg ("Value not set");
14925       return -99;
14926     }
14927
14928   /* Construct the API message */
14929   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14930
14931   mp->is_enabled = is_en;
14932
14933   /* send it... */
14934   S (mp);
14935
14936   /* Wait for a reply... */
14937   W (ret);
14938   return ret;
14939 }
14940
14941 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14942
14943 static int
14944 api_one_enable_disable (vat_main_t * vam)
14945 {
14946   unformat_input_t *input = vam->input;
14947   vl_api_one_enable_disable_t *mp;
14948   u8 is_set = 0;
14949   u8 is_en = 0;
14950   int ret;
14951
14952   /* Parse args required to build the message */
14953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14954     {
14955       if (unformat (input, "enable"))
14956         {
14957           is_set = 1;
14958           is_en = 1;
14959         }
14960       else if (unformat (input, "disable"))
14961         {
14962           is_set = 1;
14963         }
14964       else
14965         break;
14966     }
14967
14968   if (!is_set)
14969     {
14970       errmsg ("Value not set");
14971       return -99;
14972     }
14973
14974   /* Construct the API message */
14975   M (ONE_ENABLE_DISABLE, mp);
14976
14977   mp->is_en = is_en;
14978
14979   /* send it... */
14980   S (mp);
14981
14982   /* Wait for a reply... */
14983   W (ret);
14984   return ret;
14985 }
14986
14987 #define api_lisp_enable_disable api_one_enable_disable
14988
14989 static int
14990 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14991 {
14992   unformat_input_t *input = vam->input;
14993   vl_api_one_enable_disable_xtr_mode_t *mp;
14994   u8 is_set = 0;
14995   u8 is_en = 0;
14996   int ret;
14997
14998   /* Parse args required to build the message */
14999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15000     {
15001       if (unformat (input, "enable"))
15002         {
15003           is_set = 1;
15004           is_en = 1;
15005         }
15006       else if (unformat (input, "disable"))
15007         {
15008           is_set = 1;
15009         }
15010       else
15011         break;
15012     }
15013
15014   if (!is_set)
15015     {
15016       errmsg ("Value not set");
15017       return -99;
15018     }
15019
15020   /* Construct the API message */
15021   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15022
15023   mp->is_en = is_en;
15024
15025   /* send it... */
15026   S (mp);
15027
15028   /* Wait for a reply... */
15029   W (ret);
15030   return ret;
15031 }
15032
15033 static int
15034 api_one_show_xtr_mode (vat_main_t * vam)
15035 {
15036   vl_api_one_show_xtr_mode_t *mp;
15037   int ret;
15038
15039   /* Construct the API message */
15040   M (ONE_SHOW_XTR_MODE, mp);
15041
15042   /* send it... */
15043   S (mp);
15044
15045   /* Wait for a reply... */
15046   W (ret);
15047   return ret;
15048 }
15049
15050 static int
15051 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15052 {
15053   unformat_input_t *input = vam->input;
15054   vl_api_one_enable_disable_pitr_mode_t *mp;
15055   u8 is_set = 0;
15056   u8 is_en = 0;
15057   int ret;
15058
15059   /* Parse args required to build the message */
15060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15061     {
15062       if (unformat (input, "enable"))
15063         {
15064           is_set = 1;
15065           is_en = 1;
15066         }
15067       else if (unformat (input, "disable"))
15068         {
15069           is_set = 1;
15070         }
15071       else
15072         break;
15073     }
15074
15075   if (!is_set)
15076     {
15077       errmsg ("Value not set");
15078       return -99;
15079     }
15080
15081   /* Construct the API message */
15082   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15083
15084   mp->is_en = is_en;
15085
15086   /* send it... */
15087   S (mp);
15088
15089   /* Wait for a reply... */
15090   W (ret);
15091   return ret;
15092 }
15093
15094 static int
15095 api_one_show_pitr_mode (vat_main_t * vam)
15096 {
15097   vl_api_one_show_pitr_mode_t *mp;
15098   int ret;
15099
15100   /* Construct the API message */
15101   M (ONE_SHOW_PITR_MODE, mp);
15102
15103   /* send it... */
15104   S (mp);
15105
15106   /* Wait for a reply... */
15107   W (ret);
15108   return ret;
15109 }
15110
15111 static int
15112 api_one_enable_disable_petr_mode (vat_main_t * vam)
15113 {
15114   unformat_input_t *input = vam->input;
15115   vl_api_one_enable_disable_petr_mode_t *mp;
15116   u8 is_set = 0;
15117   u8 is_en = 0;
15118   int ret;
15119
15120   /* Parse args required to build the message */
15121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15122     {
15123       if (unformat (input, "enable"))
15124         {
15125           is_set = 1;
15126           is_en = 1;
15127         }
15128       else if (unformat (input, "disable"))
15129         {
15130           is_set = 1;
15131         }
15132       else
15133         break;
15134     }
15135
15136   if (!is_set)
15137     {
15138       errmsg ("Value not set");
15139       return -99;
15140     }
15141
15142   /* Construct the API message */
15143   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15144
15145   mp->is_en = is_en;
15146
15147   /* send it... */
15148   S (mp);
15149
15150   /* Wait for a reply... */
15151   W (ret);
15152   return ret;
15153 }
15154
15155 static int
15156 api_one_show_petr_mode (vat_main_t * vam)
15157 {
15158   vl_api_one_show_petr_mode_t *mp;
15159   int ret;
15160
15161   /* Construct the API message */
15162   M (ONE_SHOW_PETR_MODE, mp);
15163
15164   /* send it... */
15165   S (mp);
15166
15167   /* Wait for a reply... */
15168   W (ret);
15169   return ret;
15170 }
15171
15172 static int
15173 api_show_one_map_register_state (vat_main_t * vam)
15174 {
15175   vl_api_show_one_map_register_state_t *mp;
15176   int ret;
15177
15178   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15179
15180   /* send */
15181   S (mp);
15182
15183   /* wait for reply */
15184   W (ret);
15185   return ret;
15186 }
15187
15188 #define api_show_lisp_map_register_state api_show_one_map_register_state
15189
15190 static int
15191 api_show_one_rloc_probe_state (vat_main_t * vam)
15192 {
15193   vl_api_show_one_rloc_probe_state_t *mp;
15194   int ret;
15195
15196   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15197
15198   /* send */
15199   S (mp);
15200
15201   /* wait for reply */
15202   W (ret);
15203   return ret;
15204 }
15205
15206 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15207
15208 static int
15209 api_one_add_del_ndp_entry (vat_main_t * vam)
15210 {
15211   vl_api_one_add_del_ndp_entry_t *mp;
15212   unformat_input_t *input = vam->input;
15213   u8 is_add = 1;
15214   u8 mac_set = 0;
15215   u8 bd_set = 0;
15216   u8 ip_set = 0;
15217   u8 mac[6] = { 0, };
15218   u8 ip6[16] = { 0, };
15219   u32 bd = ~0;
15220   int ret;
15221
15222   /* Parse args required to build the message */
15223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15224     {
15225       if (unformat (input, "del"))
15226         is_add = 0;
15227       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15228         mac_set = 1;
15229       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15230         ip_set = 1;
15231       else if (unformat (input, "bd %d", &bd))
15232         bd_set = 1;
15233       else
15234         {
15235           errmsg ("parse error '%U'", format_unformat_error, input);
15236           return -99;
15237         }
15238     }
15239
15240   if (!bd_set || !ip_set || (!mac_set && is_add))
15241     {
15242       errmsg ("Missing BD, IP or MAC!");
15243       return -99;
15244     }
15245
15246   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15247   mp->is_add = is_add;
15248   clib_memcpy (mp->mac, mac, 6);
15249   mp->bd = clib_host_to_net_u32 (bd);
15250   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15251
15252   /* send */
15253   S (mp);
15254
15255   /* wait for reply */
15256   W (ret);
15257   return ret;
15258 }
15259
15260 static int
15261 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15262 {
15263   vl_api_one_add_del_l2_arp_entry_t *mp;
15264   unformat_input_t *input = vam->input;
15265   u8 is_add = 1;
15266   u8 mac_set = 0;
15267   u8 bd_set = 0;
15268   u8 ip_set = 0;
15269   u8 mac[6] = { 0, };
15270   u32 ip4 = 0, bd = ~0;
15271   int ret;
15272
15273   /* Parse args required to build the message */
15274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15275     {
15276       if (unformat (input, "del"))
15277         is_add = 0;
15278       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15279         mac_set = 1;
15280       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15281         ip_set = 1;
15282       else if (unformat (input, "bd %d", &bd))
15283         bd_set = 1;
15284       else
15285         {
15286           errmsg ("parse error '%U'", format_unformat_error, input);
15287           return -99;
15288         }
15289     }
15290
15291   if (!bd_set || !ip_set || (!mac_set && is_add))
15292     {
15293       errmsg ("Missing BD, IP or MAC!");
15294       return -99;
15295     }
15296
15297   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15298   mp->is_add = is_add;
15299   clib_memcpy (mp->mac, mac, 6);
15300   mp->bd = clib_host_to_net_u32 (bd);
15301   mp->ip4 = ip4;
15302
15303   /* send */
15304   S (mp);
15305
15306   /* wait for reply */
15307   W (ret);
15308   return ret;
15309 }
15310
15311 static int
15312 api_one_ndp_bd_get (vat_main_t * vam)
15313 {
15314   vl_api_one_ndp_bd_get_t *mp;
15315   int ret;
15316
15317   M (ONE_NDP_BD_GET, mp);
15318
15319   /* send */
15320   S (mp);
15321
15322   /* wait for reply */
15323   W (ret);
15324   return ret;
15325 }
15326
15327 static int
15328 api_one_ndp_entries_get (vat_main_t * vam)
15329 {
15330   vl_api_one_ndp_entries_get_t *mp;
15331   unformat_input_t *input = vam->input;
15332   u8 bd_set = 0;
15333   u32 bd = ~0;
15334   int ret;
15335
15336   /* Parse args required to build the message */
15337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15338     {
15339       if (unformat (input, "bd %d", &bd))
15340         bd_set = 1;
15341       else
15342         {
15343           errmsg ("parse error '%U'", format_unformat_error, input);
15344           return -99;
15345         }
15346     }
15347
15348   if (!bd_set)
15349     {
15350       errmsg ("Expected bridge domain!");
15351       return -99;
15352     }
15353
15354   M (ONE_NDP_ENTRIES_GET, mp);
15355   mp->bd = clib_host_to_net_u32 (bd);
15356
15357   /* send */
15358   S (mp);
15359
15360   /* wait for reply */
15361   W (ret);
15362   return ret;
15363 }
15364
15365 static int
15366 api_one_l2_arp_bd_get (vat_main_t * vam)
15367 {
15368   vl_api_one_l2_arp_bd_get_t *mp;
15369   int ret;
15370
15371   M (ONE_L2_ARP_BD_GET, mp);
15372
15373   /* send */
15374   S (mp);
15375
15376   /* wait for reply */
15377   W (ret);
15378   return ret;
15379 }
15380
15381 static int
15382 api_one_l2_arp_entries_get (vat_main_t * vam)
15383 {
15384   vl_api_one_l2_arp_entries_get_t *mp;
15385   unformat_input_t *input = vam->input;
15386   u8 bd_set = 0;
15387   u32 bd = ~0;
15388   int ret;
15389
15390   /* Parse args required to build the message */
15391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15392     {
15393       if (unformat (input, "bd %d", &bd))
15394         bd_set = 1;
15395       else
15396         {
15397           errmsg ("parse error '%U'", format_unformat_error, input);
15398           return -99;
15399         }
15400     }
15401
15402   if (!bd_set)
15403     {
15404       errmsg ("Expected bridge domain!");
15405       return -99;
15406     }
15407
15408   M (ONE_L2_ARP_ENTRIES_GET, mp);
15409   mp->bd = clib_host_to_net_u32 (bd);
15410
15411   /* send */
15412   S (mp);
15413
15414   /* wait for reply */
15415   W (ret);
15416   return ret;
15417 }
15418
15419 static int
15420 api_one_stats_enable_disable (vat_main_t * vam)
15421 {
15422   vl_api_one_stats_enable_disable_t *mp;
15423   unformat_input_t *input = vam->input;
15424   u8 is_set = 0;
15425   u8 is_en = 0;
15426   int ret;
15427
15428   /* Parse args required to build the message */
15429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (input, "enable"))
15432         {
15433           is_set = 1;
15434           is_en = 1;
15435         }
15436       else if (unformat (input, "disable"))
15437         {
15438           is_set = 1;
15439         }
15440       else
15441         break;
15442     }
15443
15444   if (!is_set)
15445     {
15446       errmsg ("Value not set");
15447       return -99;
15448     }
15449
15450   M (ONE_STATS_ENABLE_DISABLE, mp);
15451   mp->is_en = is_en;
15452
15453   /* send */
15454   S (mp);
15455
15456   /* wait for reply */
15457   W (ret);
15458   return ret;
15459 }
15460
15461 static int
15462 api_show_one_stats_enable_disable (vat_main_t * vam)
15463 {
15464   vl_api_show_one_stats_enable_disable_t *mp;
15465   int ret;
15466
15467   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15468
15469   /* send */
15470   S (mp);
15471
15472   /* wait for reply */
15473   W (ret);
15474   return ret;
15475 }
15476
15477 static int
15478 api_show_one_map_request_mode (vat_main_t * vam)
15479 {
15480   vl_api_show_one_map_request_mode_t *mp;
15481   int ret;
15482
15483   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15484
15485   /* send */
15486   S (mp);
15487
15488   /* wait for reply */
15489   W (ret);
15490   return ret;
15491 }
15492
15493 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15494
15495 static int
15496 api_one_map_request_mode (vat_main_t * vam)
15497 {
15498   unformat_input_t *input = vam->input;
15499   vl_api_one_map_request_mode_t *mp;
15500   u8 mode = 0;
15501   int ret;
15502
15503   /* Parse args required to build the message */
15504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15505     {
15506       if (unformat (input, "dst-only"))
15507         mode = 0;
15508       else if (unformat (input, "src-dst"))
15509         mode = 1;
15510       else
15511         {
15512           errmsg ("parse error '%U'", format_unformat_error, input);
15513           return -99;
15514         }
15515     }
15516
15517   M (ONE_MAP_REQUEST_MODE, mp);
15518
15519   mp->mode = mode;
15520
15521   /* send */
15522   S (mp);
15523
15524   /* wait for reply */
15525   W (ret);
15526   return ret;
15527 }
15528
15529 #define api_lisp_map_request_mode api_one_map_request_mode
15530
15531 /**
15532  * Enable/disable ONE proxy ITR.
15533  *
15534  * @param vam vpp API test context
15535  * @return return code
15536  */
15537 static int
15538 api_one_pitr_set_locator_set (vat_main_t * vam)
15539 {
15540   u8 ls_name_set = 0;
15541   unformat_input_t *input = vam->input;
15542   vl_api_one_pitr_set_locator_set_t *mp;
15543   u8 is_add = 1;
15544   u8 *ls_name = 0;
15545   int ret;
15546
15547   /* Parse args required to build the message */
15548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15549     {
15550       if (unformat (input, "del"))
15551         is_add = 0;
15552       else if (unformat (input, "locator-set %s", &ls_name))
15553         ls_name_set = 1;
15554       else
15555         {
15556           errmsg ("parse error '%U'", format_unformat_error, input);
15557           return -99;
15558         }
15559     }
15560
15561   if (!ls_name_set)
15562     {
15563       errmsg ("locator-set name not set!");
15564       return -99;
15565     }
15566
15567   M (ONE_PITR_SET_LOCATOR_SET, mp);
15568
15569   mp->is_add = is_add;
15570   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15571   vec_free (ls_name);
15572
15573   /* send */
15574   S (mp);
15575
15576   /* wait for reply */
15577   W (ret);
15578   return ret;
15579 }
15580
15581 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15582
15583 static int
15584 api_one_nsh_set_locator_set (vat_main_t * vam)
15585 {
15586   u8 ls_name_set = 0;
15587   unformat_input_t *input = vam->input;
15588   vl_api_one_nsh_set_locator_set_t *mp;
15589   u8 is_add = 1;
15590   u8 *ls_name = 0;
15591   int ret;
15592
15593   /* Parse args required to build the message */
15594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15595     {
15596       if (unformat (input, "del"))
15597         is_add = 0;
15598       else if (unformat (input, "ls %s", &ls_name))
15599         ls_name_set = 1;
15600       else
15601         {
15602           errmsg ("parse error '%U'", format_unformat_error, input);
15603           return -99;
15604         }
15605     }
15606
15607   if (!ls_name_set && is_add)
15608     {
15609       errmsg ("locator-set name not set!");
15610       return -99;
15611     }
15612
15613   M (ONE_NSH_SET_LOCATOR_SET, mp);
15614
15615   mp->is_add = is_add;
15616   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15617   vec_free (ls_name);
15618
15619   /* send */
15620   S (mp);
15621
15622   /* wait for reply */
15623   W (ret);
15624   return ret;
15625 }
15626
15627 static int
15628 api_show_one_pitr (vat_main_t * vam)
15629 {
15630   vl_api_show_one_pitr_t *mp;
15631   int ret;
15632
15633   if (!vam->json_output)
15634     {
15635       print (vam->ofp, "%=20s", "lisp status:");
15636     }
15637
15638   M (SHOW_ONE_PITR, mp);
15639   /* send it... */
15640   S (mp);
15641
15642   /* Wait for a reply... */
15643   W (ret);
15644   return ret;
15645 }
15646
15647 #define api_show_lisp_pitr api_show_one_pitr
15648
15649 static int
15650 api_one_use_petr (vat_main_t * vam)
15651 {
15652   unformat_input_t *input = vam->input;
15653   vl_api_one_use_petr_t *mp;
15654   u8 is_add = 0;
15655   ip_address_t ip;
15656   int ret;
15657
15658   clib_memset (&ip, 0, sizeof (ip));
15659
15660   /* Parse args required to build the message */
15661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15662     {
15663       if (unformat (input, "disable"))
15664         is_add = 0;
15665       else
15666         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15667         {
15668           is_add = 1;
15669           ip_addr_version (&ip) = AF_IP4;
15670         }
15671       else
15672         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15673         {
15674           is_add = 1;
15675           ip_addr_version (&ip) = AF_IP6;
15676         }
15677       else
15678         {
15679           errmsg ("parse error '%U'", format_unformat_error, input);
15680           return -99;
15681         }
15682     }
15683
15684   M (ONE_USE_PETR, mp);
15685
15686   mp->is_add = is_add;
15687   if (is_add)
15688     {
15689       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15690       if (mp->is_ip4)
15691         clib_memcpy (mp->address, &ip, 4);
15692       else
15693         clib_memcpy (mp->address, &ip, 16);
15694     }
15695
15696   /* send */
15697   S (mp);
15698
15699   /* wait for reply */
15700   W (ret);
15701   return ret;
15702 }
15703
15704 #define api_lisp_use_petr api_one_use_petr
15705
15706 static int
15707 api_show_one_nsh_mapping (vat_main_t * vam)
15708 {
15709   vl_api_show_one_use_petr_t *mp;
15710   int ret;
15711
15712   if (!vam->json_output)
15713     {
15714       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15715     }
15716
15717   M (SHOW_ONE_NSH_MAPPING, mp);
15718   /* send it... */
15719   S (mp);
15720
15721   /* Wait for a reply... */
15722   W (ret);
15723   return ret;
15724 }
15725
15726 static int
15727 api_show_one_use_petr (vat_main_t * vam)
15728 {
15729   vl_api_show_one_use_petr_t *mp;
15730   int ret;
15731
15732   if (!vam->json_output)
15733     {
15734       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15735     }
15736
15737   M (SHOW_ONE_USE_PETR, mp);
15738   /* send it... */
15739   S (mp);
15740
15741   /* Wait for a reply... */
15742   W (ret);
15743   return ret;
15744 }
15745
15746 #define api_show_lisp_use_petr api_show_one_use_petr
15747
15748 /**
15749  * Add/delete mapping between vni and vrf
15750  */
15751 static int
15752 api_one_eid_table_add_del_map (vat_main_t * vam)
15753 {
15754   unformat_input_t *input = vam->input;
15755   vl_api_one_eid_table_add_del_map_t *mp;
15756   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15757   u32 vni, vrf, bd_index;
15758   int ret;
15759
15760   /* Parse args required to build the message */
15761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15762     {
15763       if (unformat (input, "del"))
15764         is_add = 0;
15765       else if (unformat (input, "vrf %d", &vrf))
15766         vrf_set = 1;
15767       else if (unformat (input, "bd_index %d", &bd_index))
15768         bd_index_set = 1;
15769       else if (unformat (input, "vni %d", &vni))
15770         vni_set = 1;
15771       else
15772         break;
15773     }
15774
15775   if (!vni_set || (!vrf_set && !bd_index_set))
15776     {
15777       errmsg ("missing arguments!");
15778       return -99;
15779     }
15780
15781   if (vrf_set && bd_index_set)
15782     {
15783       errmsg ("error: both vrf and bd entered!");
15784       return -99;
15785     }
15786
15787   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15788
15789   mp->is_add = is_add;
15790   mp->vni = htonl (vni);
15791   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15792   mp->is_l2 = bd_index_set;
15793
15794   /* send */
15795   S (mp);
15796
15797   /* wait for reply */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15803
15804 uword
15805 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15806 {
15807   u32 *action = va_arg (*args, u32 *);
15808   u8 *s = 0;
15809
15810   if (unformat (input, "%s", &s))
15811     {
15812       if (!strcmp ((char *) s, "no-action"))
15813         action[0] = 0;
15814       else if (!strcmp ((char *) s, "natively-forward"))
15815         action[0] = 1;
15816       else if (!strcmp ((char *) s, "send-map-request"))
15817         action[0] = 2;
15818       else if (!strcmp ((char *) s, "drop"))
15819         action[0] = 3;
15820       else
15821         {
15822           clib_warning ("invalid action: '%s'", s);
15823           action[0] = 3;
15824         }
15825     }
15826   else
15827     return 0;
15828
15829   vec_free (s);
15830   return 1;
15831 }
15832
15833 /**
15834  * Add/del remote mapping to/from ONE control plane
15835  *
15836  * @param vam vpp API test context
15837  * @return return code
15838  */
15839 static int
15840 api_one_add_del_remote_mapping (vat_main_t * vam)
15841 {
15842   unformat_input_t *input = vam->input;
15843   vl_api_one_add_del_remote_mapping_t *mp;
15844   u32 vni = 0;
15845   lisp_eid_vat_t _eid, *eid = &_eid;
15846   lisp_eid_vat_t _seid, *seid = &_seid;
15847   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15848   u32 action = ~0, p, w, data_len;
15849   ip4_address_t rloc4;
15850   ip6_address_t rloc6;
15851   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15852   int ret;
15853
15854   clib_memset (&rloc, 0, sizeof (rloc));
15855
15856   /* Parse args required to build the message */
15857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15858     {
15859       if (unformat (input, "del-all"))
15860         {
15861           del_all = 1;
15862         }
15863       else if (unformat (input, "del"))
15864         {
15865           is_add = 0;
15866         }
15867       else if (unformat (input, "add"))
15868         {
15869           is_add = 1;
15870         }
15871       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15872         {
15873           eid_set = 1;
15874         }
15875       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15876         {
15877           seid_set = 1;
15878         }
15879       else if (unformat (input, "vni %d", &vni))
15880         {
15881           ;
15882         }
15883       else if (unformat (input, "p %d w %d", &p, &w))
15884         {
15885           if (!curr_rloc)
15886             {
15887               errmsg ("No RLOC configured for setting priority/weight!");
15888               return -99;
15889             }
15890           curr_rloc->priority = p;
15891           curr_rloc->weight = w;
15892         }
15893       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15894         {
15895           rloc.is_ip4 = 1;
15896           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15897           vec_add1 (rlocs, rloc);
15898           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15899         }
15900       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15901         {
15902           rloc.is_ip4 = 0;
15903           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15904           vec_add1 (rlocs, rloc);
15905           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15906         }
15907       else if (unformat (input, "action %U",
15908                          unformat_negative_mapping_action, &action))
15909         {
15910           ;
15911         }
15912       else
15913         {
15914           clib_warning ("parse error '%U'", format_unformat_error, input);
15915           return -99;
15916         }
15917     }
15918
15919   if (0 == eid_set)
15920     {
15921       errmsg ("missing params!");
15922       return -99;
15923     }
15924
15925   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15926     {
15927       errmsg ("no action set for negative map-reply!");
15928       return -99;
15929     }
15930
15931   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15932
15933   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15934   mp->is_add = is_add;
15935   mp->vni = htonl (vni);
15936   mp->action = (u8) action;
15937   mp->is_src_dst = seid_set;
15938   mp->eid_len = eid->len;
15939   mp->seid_len = seid->len;
15940   mp->del_all = del_all;
15941   mp->eid_type = eid->type;
15942   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15943   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15944
15945   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15946   clib_memcpy (mp->rlocs, rlocs, data_len);
15947   vec_free (rlocs);
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Wait for a reply... */
15953   W (ret);
15954   return ret;
15955 }
15956
15957 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15958
15959 /**
15960  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15961  * forwarding entries in data-plane accordingly.
15962  *
15963  * @param vam vpp API test context
15964  * @return return code
15965  */
15966 static int
15967 api_one_add_del_adjacency (vat_main_t * vam)
15968 {
15969   unformat_input_t *input = vam->input;
15970   vl_api_one_add_del_adjacency_t *mp;
15971   u32 vni = 0;
15972   ip4_address_t leid4, reid4;
15973   ip6_address_t leid6, reid6;
15974   u8 reid_mac[6] = { 0 };
15975   u8 leid_mac[6] = { 0 };
15976   u8 reid_type, leid_type;
15977   u32 leid_len = 0, reid_len = 0, len;
15978   u8 is_add = 1;
15979   int ret;
15980
15981   leid_type = reid_type = (u8) ~ 0;
15982
15983   /* Parse args required to build the message */
15984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15985     {
15986       if (unformat (input, "del"))
15987         {
15988           is_add = 0;
15989         }
15990       else if (unformat (input, "add"))
15991         {
15992           is_add = 1;
15993         }
15994       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15995                          &reid4, &len))
15996         {
15997           reid_type = 0;        /* ipv4 */
15998           reid_len = len;
15999         }
16000       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16001                          &reid6, &len))
16002         {
16003           reid_type = 1;        /* ipv6 */
16004           reid_len = len;
16005         }
16006       else if (unformat (input, "reid %U", unformat_ethernet_address,
16007                          reid_mac))
16008         {
16009           reid_type = 2;        /* mac */
16010         }
16011       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16012                          &leid4, &len))
16013         {
16014           leid_type = 0;        /* ipv4 */
16015           leid_len = len;
16016         }
16017       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16018                          &leid6, &len))
16019         {
16020           leid_type = 1;        /* ipv6 */
16021           leid_len = len;
16022         }
16023       else if (unformat (input, "leid %U", unformat_ethernet_address,
16024                          leid_mac))
16025         {
16026           leid_type = 2;        /* mac */
16027         }
16028       else if (unformat (input, "vni %d", &vni))
16029         {
16030           ;
16031         }
16032       else
16033         {
16034           errmsg ("parse error '%U'", format_unformat_error, input);
16035           return -99;
16036         }
16037     }
16038
16039   if ((u8) ~ 0 == reid_type)
16040     {
16041       errmsg ("missing params!");
16042       return -99;
16043     }
16044
16045   if (leid_type != reid_type)
16046     {
16047       errmsg ("remote and local EIDs are of different types!");
16048       return -99;
16049     }
16050
16051   M (ONE_ADD_DEL_ADJACENCY, mp);
16052   mp->is_add = is_add;
16053   mp->vni = htonl (vni);
16054   mp->leid_len = leid_len;
16055   mp->reid_len = reid_len;
16056   mp->eid_type = reid_type;
16057
16058   switch (mp->eid_type)
16059     {
16060     case 0:
16061       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16062       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16063       break;
16064     case 1:
16065       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16066       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16067       break;
16068     case 2:
16069       clib_memcpy (mp->leid, leid_mac, 6);
16070       clib_memcpy (mp->reid, reid_mac, 6);
16071       break;
16072     default:
16073       errmsg ("unknown EID type %d!", mp->eid_type);
16074       return 0;
16075     }
16076
16077   /* send it... */
16078   S (mp);
16079
16080   /* Wait for a reply... */
16081   W (ret);
16082   return ret;
16083 }
16084
16085 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16086
16087 uword
16088 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16089 {
16090   u32 *mode = va_arg (*args, u32 *);
16091
16092   if (unformat (input, "lisp"))
16093     *mode = 0;
16094   else if (unformat (input, "vxlan"))
16095     *mode = 1;
16096   else
16097     return 0;
16098
16099   return 1;
16100 }
16101
16102 static int
16103 api_gpe_get_encap_mode (vat_main_t * vam)
16104 {
16105   vl_api_gpe_get_encap_mode_t *mp;
16106   int ret;
16107
16108   /* Construct the API message */
16109   M (GPE_GET_ENCAP_MODE, mp);
16110
16111   /* send it... */
16112   S (mp);
16113
16114   /* Wait for a reply... */
16115   W (ret);
16116   return ret;
16117 }
16118
16119 static int
16120 api_gpe_set_encap_mode (vat_main_t * vam)
16121 {
16122   unformat_input_t *input = vam->input;
16123   vl_api_gpe_set_encap_mode_t *mp;
16124   int ret;
16125   u32 mode = 0;
16126
16127   /* Parse args required to build the message */
16128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16129     {
16130       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16131         ;
16132       else
16133         break;
16134     }
16135
16136   /* Construct the API message */
16137   M (GPE_SET_ENCAP_MODE, mp);
16138
16139   mp->mode = mode;
16140
16141   /* send it... */
16142   S (mp);
16143
16144   /* Wait for a reply... */
16145   W (ret);
16146   return ret;
16147 }
16148
16149 static int
16150 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16151 {
16152   unformat_input_t *input = vam->input;
16153   vl_api_gpe_add_del_iface_t *mp;
16154   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16155   u32 dp_table = 0, vni = 0;
16156   int ret;
16157
16158   /* Parse args required to build the message */
16159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (input, "up"))
16162         {
16163           action_set = 1;
16164           is_add = 1;
16165         }
16166       else if (unformat (input, "down"))
16167         {
16168           action_set = 1;
16169           is_add = 0;
16170         }
16171       else if (unformat (input, "table_id %d", &dp_table))
16172         {
16173           dp_table_set = 1;
16174         }
16175       else if (unformat (input, "bd_id %d", &dp_table))
16176         {
16177           dp_table_set = 1;
16178           is_l2 = 1;
16179         }
16180       else if (unformat (input, "vni %d", &vni))
16181         {
16182           vni_set = 1;
16183         }
16184       else
16185         break;
16186     }
16187
16188   if (action_set == 0)
16189     {
16190       errmsg ("Action not set");
16191       return -99;
16192     }
16193   if (dp_table_set == 0 || vni_set == 0)
16194     {
16195       errmsg ("vni and dp_table must be set");
16196       return -99;
16197     }
16198
16199   /* Construct the API message */
16200   M (GPE_ADD_DEL_IFACE, mp);
16201
16202   mp->is_add = is_add;
16203   mp->dp_table = clib_host_to_net_u32 (dp_table);
16204   mp->is_l2 = is_l2;
16205   mp->vni = clib_host_to_net_u32 (vni);
16206
16207   /* send it... */
16208   S (mp);
16209
16210   /* Wait for a reply... */
16211   W (ret);
16212   return ret;
16213 }
16214
16215 static int
16216 api_one_map_register_fallback_threshold (vat_main_t * vam)
16217 {
16218   unformat_input_t *input = vam->input;
16219   vl_api_one_map_register_fallback_threshold_t *mp;
16220   u32 value = 0;
16221   u8 is_set = 0;
16222   int ret;
16223
16224   /* Parse args required to build the message */
16225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16226     {
16227       if (unformat (input, "%u", &value))
16228         is_set = 1;
16229       else
16230         {
16231           clib_warning ("parse error '%U'", format_unformat_error, input);
16232           return -99;
16233         }
16234     }
16235
16236   if (!is_set)
16237     {
16238       errmsg ("fallback threshold value is missing!");
16239       return -99;
16240     }
16241
16242   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16243   mp->value = clib_host_to_net_u32 (value);
16244
16245   /* send it... */
16246   S (mp);
16247
16248   /* Wait for a reply... */
16249   W (ret);
16250   return ret;
16251 }
16252
16253 static int
16254 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16255 {
16256   vl_api_show_one_map_register_fallback_threshold_t *mp;
16257   int ret;
16258
16259   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16260
16261   /* send it... */
16262   S (mp);
16263
16264   /* Wait for a reply... */
16265   W (ret);
16266   return ret;
16267 }
16268
16269 uword
16270 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16271 {
16272   u32 *proto = va_arg (*args, u32 *);
16273
16274   if (unformat (input, "udp"))
16275     *proto = 1;
16276   else if (unformat (input, "api"))
16277     *proto = 2;
16278   else
16279     return 0;
16280
16281   return 1;
16282 }
16283
16284 static int
16285 api_one_set_transport_protocol (vat_main_t * vam)
16286 {
16287   unformat_input_t *input = vam->input;
16288   vl_api_one_set_transport_protocol_t *mp;
16289   u8 is_set = 0;
16290   u32 protocol = 0;
16291   int ret;
16292
16293   /* Parse args required to build the message */
16294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16295     {
16296       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16297         is_set = 1;
16298       else
16299         {
16300           clib_warning ("parse error '%U'", format_unformat_error, input);
16301           return -99;
16302         }
16303     }
16304
16305   if (!is_set)
16306     {
16307       errmsg ("Transport protocol missing!");
16308       return -99;
16309     }
16310
16311   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16312   mp->protocol = (u8) protocol;
16313
16314   /* send it... */
16315   S (mp);
16316
16317   /* Wait for a reply... */
16318   W (ret);
16319   return ret;
16320 }
16321
16322 static int
16323 api_one_get_transport_protocol (vat_main_t * vam)
16324 {
16325   vl_api_one_get_transport_protocol_t *mp;
16326   int ret;
16327
16328   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16329
16330   /* send it... */
16331   S (mp);
16332
16333   /* Wait for a reply... */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 static int
16339 api_one_map_register_set_ttl (vat_main_t * vam)
16340 {
16341   unformat_input_t *input = vam->input;
16342   vl_api_one_map_register_set_ttl_t *mp;
16343   u32 ttl = 0;
16344   u8 is_set = 0;
16345   int ret;
16346
16347   /* Parse args required to build the message */
16348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16349     {
16350       if (unformat (input, "%u", &ttl))
16351         is_set = 1;
16352       else
16353         {
16354           clib_warning ("parse error '%U'", format_unformat_error, input);
16355           return -99;
16356         }
16357     }
16358
16359   if (!is_set)
16360     {
16361       errmsg ("TTL value missing!");
16362       return -99;
16363     }
16364
16365   M (ONE_MAP_REGISTER_SET_TTL, mp);
16366   mp->ttl = clib_host_to_net_u32 (ttl);
16367
16368   /* send it... */
16369   S (mp);
16370
16371   /* Wait for a reply... */
16372   W (ret);
16373   return ret;
16374 }
16375
16376 static int
16377 api_show_one_map_register_ttl (vat_main_t * vam)
16378 {
16379   vl_api_show_one_map_register_ttl_t *mp;
16380   int ret;
16381
16382   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16383
16384   /* send it... */
16385   S (mp);
16386
16387   /* Wait for a reply... */
16388   W (ret);
16389   return ret;
16390 }
16391
16392 /**
16393  * Add/del map request itr rlocs from ONE control plane and updates
16394  *
16395  * @param vam vpp API test context
16396  * @return return code
16397  */
16398 static int
16399 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16400 {
16401   unformat_input_t *input = vam->input;
16402   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16403   u8 *locator_set_name = 0;
16404   u8 locator_set_name_set = 0;
16405   u8 is_add = 1;
16406   int ret;
16407
16408   /* Parse args required to build the message */
16409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16410     {
16411       if (unformat (input, "del"))
16412         {
16413           is_add = 0;
16414         }
16415       else if (unformat (input, "%_%v%_", &locator_set_name))
16416         {
16417           locator_set_name_set = 1;
16418         }
16419       else
16420         {
16421           clib_warning ("parse error '%U'", format_unformat_error, input);
16422           return -99;
16423         }
16424     }
16425
16426   if (is_add && !locator_set_name_set)
16427     {
16428       errmsg ("itr-rloc is not set!");
16429       return -99;
16430     }
16431
16432   if (is_add && vec_len (locator_set_name) > 64)
16433     {
16434       errmsg ("itr-rloc locator-set name too long");
16435       vec_free (locator_set_name);
16436       return -99;
16437     }
16438
16439   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16440   mp->is_add = is_add;
16441   if (is_add)
16442     {
16443       clib_memcpy (mp->locator_set_name, locator_set_name,
16444                    vec_len (locator_set_name));
16445     }
16446   else
16447     {
16448       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16449     }
16450   vec_free (locator_set_name);
16451
16452   /* send it... */
16453   S (mp);
16454
16455   /* Wait for a reply... */
16456   W (ret);
16457   return ret;
16458 }
16459
16460 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16461
16462 static int
16463 api_one_locator_dump (vat_main_t * vam)
16464 {
16465   unformat_input_t *input = vam->input;
16466   vl_api_one_locator_dump_t *mp;
16467   vl_api_control_ping_t *mp_ping;
16468   u8 is_index_set = 0, is_name_set = 0;
16469   u8 *ls_name = 0;
16470   u32 ls_index = ~0;
16471   int ret;
16472
16473   /* Parse args required to build the message */
16474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16475     {
16476       if (unformat (input, "ls_name %_%v%_", &ls_name))
16477         {
16478           is_name_set = 1;
16479         }
16480       else if (unformat (input, "ls_index %d", &ls_index))
16481         {
16482           is_index_set = 1;
16483         }
16484       else
16485         {
16486           errmsg ("parse error '%U'", format_unformat_error, input);
16487           return -99;
16488         }
16489     }
16490
16491   if (!is_index_set && !is_name_set)
16492     {
16493       errmsg ("error: expected one of index or name!");
16494       return -99;
16495     }
16496
16497   if (is_index_set && is_name_set)
16498     {
16499       errmsg ("error: only one param expected!");
16500       return -99;
16501     }
16502
16503   if (vec_len (ls_name) > 62)
16504     {
16505       errmsg ("error: locator set name too long!");
16506       return -99;
16507     }
16508
16509   if (!vam->json_output)
16510     {
16511       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16512     }
16513
16514   M (ONE_LOCATOR_DUMP, mp);
16515   mp->is_index_set = is_index_set;
16516
16517   if (is_index_set)
16518     mp->ls_index = clib_host_to_net_u32 (ls_index);
16519   else
16520     {
16521       vec_add1 (ls_name, 0);
16522       strncpy ((char *) mp->ls_name, (char *) ls_name,
16523                sizeof (mp->ls_name) - 1);
16524     }
16525
16526   /* send it... */
16527   S (mp);
16528
16529   /* Use a control ping for synchronization */
16530   MPING (CONTROL_PING, mp_ping);
16531   S (mp_ping);
16532
16533   /* Wait for a reply... */
16534   W (ret);
16535   return ret;
16536 }
16537
16538 #define api_lisp_locator_dump api_one_locator_dump
16539
16540 static int
16541 api_one_locator_set_dump (vat_main_t * vam)
16542 {
16543   vl_api_one_locator_set_dump_t *mp;
16544   vl_api_control_ping_t *mp_ping;
16545   unformat_input_t *input = vam->input;
16546   u8 filter = 0;
16547   int ret;
16548
16549   /* Parse args required to build the message */
16550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16551     {
16552       if (unformat (input, "local"))
16553         {
16554           filter = 1;
16555         }
16556       else if (unformat (input, "remote"))
16557         {
16558           filter = 2;
16559         }
16560       else
16561         {
16562           errmsg ("parse error '%U'", format_unformat_error, input);
16563           return -99;
16564         }
16565     }
16566
16567   if (!vam->json_output)
16568     {
16569       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16570     }
16571
16572   M (ONE_LOCATOR_SET_DUMP, mp);
16573
16574   mp->filter = filter;
16575
16576   /* send it... */
16577   S (mp);
16578
16579   /* Use a control ping for synchronization */
16580   MPING (CONTROL_PING, mp_ping);
16581   S (mp_ping);
16582
16583   /* Wait for a reply... */
16584   W (ret);
16585   return ret;
16586 }
16587
16588 #define api_lisp_locator_set_dump api_one_locator_set_dump
16589
16590 static int
16591 api_one_eid_table_map_dump (vat_main_t * vam)
16592 {
16593   u8 is_l2 = 0;
16594   u8 mode_set = 0;
16595   unformat_input_t *input = vam->input;
16596   vl_api_one_eid_table_map_dump_t *mp;
16597   vl_api_control_ping_t *mp_ping;
16598   int ret;
16599
16600   /* Parse args required to build the message */
16601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16602     {
16603       if (unformat (input, "l2"))
16604         {
16605           is_l2 = 1;
16606           mode_set = 1;
16607         }
16608       else if (unformat (input, "l3"))
16609         {
16610           is_l2 = 0;
16611           mode_set = 1;
16612         }
16613       else
16614         {
16615           errmsg ("parse error '%U'", format_unformat_error, input);
16616           return -99;
16617         }
16618     }
16619
16620   if (!mode_set)
16621     {
16622       errmsg ("expected one of 'l2' or 'l3' parameter!");
16623       return -99;
16624     }
16625
16626   if (!vam->json_output)
16627     {
16628       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16629     }
16630
16631   M (ONE_EID_TABLE_MAP_DUMP, mp);
16632   mp->is_l2 = is_l2;
16633
16634   /* send it... */
16635   S (mp);
16636
16637   /* Use a control ping for synchronization */
16638   MPING (CONTROL_PING, mp_ping);
16639   S (mp_ping);
16640
16641   /* Wait for a reply... */
16642   W (ret);
16643   return ret;
16644 }
16645
16646 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16647
16648 static int
16649 api_one_eid_table_vni_dump (vat_main_t * vam)
16650 {
16651   vl_api_one_eid_table_vni_dump_t *mp;
16652   vl_api_control_ping_t *mp_ping;
16653   int ret;
16654
16655   if (!vam->json_output)
16656     {
16657       print (vam->ofp, "VNI");
16658     }
16659
16660   M (ONE_EID_TABLE_VNI_DUMP, mp);
16661
16662   /* send it... */
16663   S (mp);
16664
16665   /* Use a control ping for synchronization */
16666   MPING (CONTROL_PING, mp_ping);
16667   S (mp_ping);
16668
16669   /* Wait for a reply... */
16670   W (ret);
16671   return ret;
16672 }
16673
16674 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16675
16676 static int
16677 api_one_eid_table_dump (vat_main_t * vam)
16678 {
16679   unformat_input_t *i = vam->input;
16680   vl_api_one_eid_table_dump_t *mp;
16681   vl_api_control_ping_t *mp_ping;
16682   struct in_addr ip4;
16683   struct in6_addr ip6;
16684   u8 mac[6];
16685   u8 eid_type = ~0, eid_set = 0;
16686   u32 prefix_length = ~0, t, vni = 0;
16687   u8 filter = 0;
16688   int ret;
16689   lisp_nsh_api_t nsh;
16690
16691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16692     {
16693       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16694         {
16695           eid_set = 1;
16696           eid_type = 0;
16697           prefix_length = t;
16698         }
16699       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16700         {
16701           eid_set = 1;
16702           eid_type = 1;
16703           prefix_length = t;
16704         }
16705       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16706         {
16707           eid_set = 1;
16708           eid_type = 2;
16709         }
16710       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16711         {
16712           eid_set = 1;
16713           eid_type = 3;
16714         }
16715       else if (unformat (i, "vni %d", &t))
16716         {
16717           vni = t;
16718         }
16719       else if (unformat (i, "local"))
16720         {
16721           filter = 1;
16722         }
16723       else if (unformat (i, "remote"))
16724         {
16725           filter = 2;
16726         }
16727       else
16728         {
16729           errmsg ("parse error '%U'", format_unformat_error, i);
16730           return -99;
16731         }
16732     }
16733
16734   if (!vam->json_output)
16735     {
16736       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16737              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16738     }
16739
16740   M (ONE_EID_TABLE_DUMP, mp);
16741
16742   mp->filter = filter;
16743   if (eid_set)
16744     {
16745       mp->eid_set = 1;
16746       mp->vni = htonl (vni);
16747       mp->eid_type = eid_type;
16748       switch (eid_type)
16749         {
16750         case 0:
16751           mp->prefix_length = prefix_length;
16752           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16753           break;
16754         case 1:
16755           mp->prefix_length = prefix_length;
16756           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16757           break;
16758         case 2:
16759           clib_memcpy (mp->eid, mac, sizeof (mac));
16760           break;
16761         case 3:
16762           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16763           break;
16764         default:
16765           errmsg ("unknown EID type %d!", eid_type);
16766           return -99;
16767         }
16768     }
16769
16770   /* send it... */
16771   S (mp);
16772
16773   /* Use a control ping for synchronization */
16774   MPING (CONTROL_PING, mp_ping);
16775   S (mp_ping);
16776
16777   /* Wait for a reply... */
16778   W (ret);
16779   return ret;
16780 }
16781
16782 #define api_lisp_eid_table_dump api_one_eid_table_dump
16783
16784 static int
16785 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16786 {
16787   unformat_input_t *i = vam->input;
16788   vl_api_gpe_fwd_entries_get_t *mp;
16789   u8 vni_set = 0;
16790   u32 vni = ~0;
16791   int ret;
16792
16793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16794     {
16795       if (unformat (i, "vni %d", &vni))
16796         {
16797           vni_set = 1;
16798         }
16799       else
16800         {
16801           errmsg ("parse error '%U'", format_unformat_error, i);
16802           return -99;
16803         }
16804     }
16805
16806   if (!vni_set)
16807     {
16808       errmsg ("vni not set!");
16809       return -99;
16810     }
16811
16812   if (!vam->json_output)
16813     {
16814       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16815              "leid", "reid");
16816     }
16817
16818   M (GPE_FWD_ENTRIES_GET, mp);
16819   mp->vni = clib_host_to_net_u32 (vni);
16820
16821   /* send it... */
16822   S (mp);
16823
16824   /* Wait for a reply... */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16830 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16831 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16832 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16833 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16834 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16835 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16836 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16837
16838 static int
16839 api_one_adjacencies_get (vat_main_t * vam)
16840 {
16841   unformat_input_t *i = vam->input;
16842   vl_api_one_adjacencies_get_t *mp;
16843   u8 vni_set = 0;
16844   u32 vni = ~0;
16845   int ret;
16846
16847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16848     {
16849       if (unformat (i, "vni %d", &vni))
16850         {
16851           vni_set = 1;
16852         }
16853       else
16854         {
16855           errmsg ("parse error '%U'", format_unformat_error, i);
16856           return -99;
16857         }
16858     }
16859
16860   if (!vni_set)
16861     {
16862       errmsg ("vni not set!");
16863       return -99;
16864     }
16865
16866   if (!vam->json_output)
16867     {
16868       print (vam->ofp, "%s %40s", "leid", "reid");
16869     }
16870
16871   M (ONE_ADJACENCIES_GET, mp);
16872   mp->vni = clib_host_to_net_u32 (vni);
16873
16874   /* send it... */
16875   S (mp);
16876
16877   /* Wait for a reply... */
16878   W (ret);
16879   return ret;
16880 }
16881
16882 #define api_lisp_adjacencies_get api_one_adjacencies_get
16883
16884 static int
16885 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16886 {
16887   unformat_input_t *i = vam->input;
16888   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16889   int ret;
16890   u8 ip_family_set = 0, is_ip4 = 1;
16891
16892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16893     {
16894       if (unformat (i, "ip4"))
16895         {
16896           ip_family_set = 1;
16897           is_ip4 = 1;
16898         }
16899       else if (unformat (i, "ip6"))
16900         {
16901           ip_family_set = 1;
16902           is_ip4 = 0;
16903         }
16904       else
16905         {
16906           errmsg ("parse error '%U'", format_unformat_error, i);
16907           return -99;
16908         }
16909     }
16910
16911   if (!ip_family_set)
16912     {
16913       errmsg ("ip family not set!");
16914       return -99;
16915     }
16916
16917   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16918   mp->is_ip4 = is_ip4;
16919
16920   /* send it... */
16921   S (mp);
16922
16923   /* Wait for a reply... */
16924   W (ret);
16925   return ret;
16926 }
16927
16928 static int
16929 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16930 {
16931   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16932   int ret;
16933
16934   if (!vam->json_output)
16935     {
16936       print (vam->ofp, "VNIs");
16937     }
16938
16939   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16940
16941   /* send it... */
16942   S (mp);
16943
16944   /* Wait for a reply... */
16945   W (ret);
16946   return ret;
16947 }
16948
16949 static int
16950 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16951 {
16952   unformat_input_t *i = vam->input;
16953   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16954   int ret = 0;
16955   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16956   struct in_addr ip4;
16957   struct in6_addr ip6;
16958   u32 table_id = 0, nh_sw_if_index = ~0;
16959
16960   clib_memset (&ip4, 0, sizeof (ip4));
16961   clib_memset (&ip6, 0, sizeof (ip6));
16962
16963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16964     {
16965       if (unformat (i, "del"))
16966         is_add = 0;
16967       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16968                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16969         {
16970           ip_set = 1;
16971           is_ip4 = 1;
16972         }
16973       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16974                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16975         {
16976           ip_set = 1;
16977           is_ip4 = 0;
16978         }
16979       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16980         {
16981           ip_set = 1;
16982           is_ip4 = 1;
16983           nh_sw_if_index = ~0;
16984         }
16985       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16986         {
16987           ip_set = 1;
16988           is_ip4 = 0;
16989           nh_sw_if_index = ~0;
16990         }
16991       else if (unformat (i, "table %d", &table_id))
16992         ;
16993       else
16994         {
16995           errmsg ("parse error '%U'", format_unformat_error, i);
16996           return -99;
16997         }
16998     }
16999
17000   if (!ip_set)
17001     {
17002       errmsg ("nh addr not set!");
17003       return -99;
17004     }
17005
17006   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17007   mp->is_add = is_add;
17008   mp->table_id = clib_host_to_net_u32 (table_id);
17009   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17010   mp->is_ip4 = is_ip4;
17011   if (is_ip4)
17012     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17013   else
17014     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17015
17016   /* send it... */
17017   S (mp);
17018
17019   /* Wait for a reply... */
17020   W (ret);
17021   return ret;
17022 }
17023
17024 static int
17025 api_one_map_server_dump (vat_main_t * vam)
17026 {
17027   vl_api_one_map_server_dump_t *mp;
17028   vl_api_control_ping_t *mp_ping;
17029   int ret;
17030
17031   if (!vam->json_output)
17032     {
17033       print (vam->ofp, "%=20s", "Map server");
17034     }
17035
17036   M (ONE_MAP_SERVER_DUMP, mp);
17037   /* send it... */
17038   S (mp);
17039
17040   /* Use a control ping for synchronization */
17041   MPING (CONTROL_PING, mp_ping);
17042   S (mp_ping);
17043
17044   /* Wait for a reply... */
17045   W (ret);
17046   return ret;
17047 }
17048
17049 #define api_lisp_map_server_dump api_one_map_server_dump
17050
17051 static int
17052 api_one_map_resolver_dump (vat_main_t * vam)
17053 {
17054   vl_api_one_map_resolver_dump_t *mp;
17055   vl_api_control_ping_t *mp_ping;
17056   int ret;
17057
17058   if (!vam->json_output)
17059     {
17060       print (vam->ofp, "%=20s", "Map resolver");
17061     }
17062
17063   M (ONE_MAP_RESOLVER_DUMP, mp);
17064   /* send it... */
17065   S (mp);
17066
17067   /* Use a control ping for synchronization */
17068   MPING (CONTROL_PING, mp_ping);
17069   S (mp_ping);
17070
17071   /* Wait for a reply... */
17072   W (ret);
17073   return ret;
17074 }
17075
17076 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17077
17078 static int
17079 api_one_stats_flush (vat_main_t * vam)
17080 {
17081   vl_api_one_stats_flush_t *mp;
17082   int ret = 0;
17083
17084   M (ONE_STATS_FLUSH, mp);
17085   S (mp);
17086   W (ret);
17087   return ret;
17088 }
17089
17090 static int
17091 api_one_stats_dump (vat_main_t * vam)
17092 {
17093   vl_api_one_stats_dump_t *mp;
17094   vl_api_control_ping_t *mp_ping;
17095   int ret;
17096
17097   M (ONE_STATS_DUMP, mp);
17098   /* send it... */
17099   S (mp);
17100
17101   /* Use a control ping for synchronization */
17102   MPING (CONTROL_PING, mp_ping);
17103   S (mp_ping);
17104
17105   /* Wait for a reply... */
17106   W (ret);
17107   return ret;
17108 }
17109
17110 static int
17111 api_show_one_status (vat_main_t * vam)
17112 {
17113   vl_api_show_one_status_t *mp;
17114   int ret;
17115
17116   if (!vam->json_output)
17117     {
17118       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17119     }
17120
17121   M (SHOW_ONE_STATUS, mp);
17122   /* send it... */
17123   S (mp);
17124   /* Wait for a reply... */
17125   W (ret);
17126   return ret;
17127 }
17128
17129 #define api_show_lisp_status api_show_one_status
17130
17131 static int
17132 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17133 {
17134   vl_api_gpe_fwd_entry_path_dump_t *mp;
17135   vl_api_control_ping_t *mp_ping;
17136   unformat_input_t *i = vam->input;
17137   u32 fwd_entry_index = ~0;
17138   int ret;
17139
17140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17141     {
17142       if (unformat (i, "index %d", &fwd_entry_index))
17143         ;
17144       else
17145         break;
17146     }
17147
17148   if (~0 == fwd_entry_index)
17149     {
17150       errmsg ("no index specified!");
17151       return -99;
17152     }
17153
17154   if (!vam->json_output)
17155     {
17156       print (vam->ofp, "first line");
17157     }
17158
17159   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17160
17161   /* send it... */
17162   S (mp);
17163   /* Use a control ping for synchronization */
17164   MPING (CONTROL_PING, mp_ping);
17165   S (mp_ping);
17166
17167   /* Wait for a reply... */
17168   W (ret);
17169   return ret;
17170 }
17171
17172 static int
17173 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17174 {
17175   vl_api_one_get_map_request_itr_rlocs_t *mp;
17176   int ret;
17177
17178   if (!vam->json_output)
17179     {
17180       print (vam->ofp, "%=20s", "itr-rlocs:");
17181     }
17182
17183   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17184   /* send it... */
17185   S (mp);
17186   /* Wait for a reply... */
17187   W (ret);
17188   return ret;
17189 }
17190
17191 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17192
17193 static int
17194 api_af_packet_create (vat_main_t * vam)
17195 {
17196   unformat_input_t *i = vam->input;
17197   vl_api_af_packet_create_t *mp;
17198   u8 *host_if_name = 0;
17199   u8 hw_addr[6];
17200   u8 random_hw_addr = 1;
17201   int ret;
17202
17203   clib_memset (hw_addr, 0, sizeof (hw_addr));
17204
17205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17206     {
17207       if (unformat (i, "name %s", &host_if_name))
17208         vec_add1 (host_if_name, 0);
17209       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17210         random_hw_addr = 0;
17211       else
17212         break;
17213     }
17214
17215   if (!vec_len (host_if_name))
17216     {
17217       errmsg ("host-interface name must be specified");
17218       return -99;
17219     }
17220
17221   if (vec_len (host_if_name) > 64)
17222     {
17223       errmsg ("host-interface name too long");
17224       return -99;
17225     }
17226
17227   M (AF_PACKET_CREATE, mp);
17228
17229   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17230   clib_memcpy (mp->hw_addr, hw_addr, 6);
17231   mp->use_random_hw_addr = random_hw_addr;
17232   vec_free (host_if_name);
17233
17234   S (mp);
17235
17236   /* *INDENT-OFF* */
17237   W2 (ret,
17238       ({
17239         if (ret == 0)
17240           fprintf (vam->ofp ? vam->ofp : stderr,
17241                    " new sw_if_index = %d\n", vam->sw_if_index);
17242       }));
17243   /* *INDENT-ON* */
17244   return ret;
17245 }
17246
17247 static int
17248 api_af_packet_delete (vat_main_t * vam)
17249 {
17250   unformat_input_t *i = vam->input;
17251   vl_api_af_packet_delete_t *mp;
17252   u8 *host_if_name = 0;
17253   int ret;
17254
17255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17256     {
17257       if (unformat (i, "name %s", &host_if_name))
17258         vec_add1 (host_if_name, 0);
17259       else
17260         break;
17261     }
17262
17263   if (!vec_len (host_if_name))
17264     {
17265       errmsg ("host-interface name must be specified");
17266       return -99;
17267     }
17268
17269   if (vec_len (host_if_name) > 64)
17270     {
17271       errmsg ("host-interface name too long");
17272       return -99;
17273     }
17274
17275   M (AF_PACKET_DELETE, mp);
17276
17277   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17278   vec_free (host_if_name);
17279
17280   S (mp);
17281   W (ret);
17282   return ret;
17283 }
17284
17285 static void vl_api_af_packet_details_t_handler
17286   (vl_api_af_packet_details_t * mp)
17287 {
17288   vat_main_t *vam = &vat_main;
17289
17290   print (vam->ofp, "%-16s %d",
17291          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17292 }
17293
17294 static void vl_api_af_packet_details_t_handler_json
17295   (vl_api_af_packet_details_t * mp)
17296 {
17297   vat_main_t *vam = &vat_main;
17298   vat_json_node_t *node = NULL;
17299
17300   if (VAT_JSON_ARRAY != vam->json_tree.type)
17301     {
17302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17303       vat_json_init_array (&vam->json_tree);
17304     }
17305   node = vat_json_array_add (&vam->json_tree);
17306
17307   vat_json_init_object (node);
17308   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17309   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17310 }
17311
17312 static int
17313 api_af_packet_dump (vat_main_t * vam)
17314 {
17315   vl_api_af_packet_dump_t *mp;
17316   vl_api_control_ping_t *mp_ping;
17317   int ret;
17318
17319   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17320   /* Get list of tap interfaces */
17321   M (AF_PACKET_DUMP, mp);
17322   S (mp);
17323
17324   /* Use a control ping for synchronization */
17325   MPING (CONTROL_PING, mp_ping);
17326   S (mp_ping);
17327
17328   W (ret);
17329   return ret;
17330 }
17331
17332 static int
17333 api_policer_add_del (vat_main_t * vam)
17334 {
17335   unformat_input_t *i = vam->input;
17336   vl_api_policer_add_del_t *mp;
17337   u8 is_add = 1;
17338   u8 *name = 0;
17339   u32 cir = 0;
17340   u32 eir = 0;
17341   u64 cb = 0;
17342   u64 eb = 0;
17343   u8 rate_type = 0;
17344   u8 round_type = 0;
17345   u8 type = 0;
17346   u8 color_aware = 0;
17347   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17348   int ret;
17349
17350   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17351   conform_action.dscp = 0;
17352   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17353   exceed_action.dscp = 0;
17354   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17355   violate_action.dscp = 0;
17356
17357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17358     {
17359       if (unformat (i, "del"))
17360         is_add = 0;
17361       else if (unformat (i, "name %s", &name))
17362         vec_add1 (name, 0);
17363       else if (unformat (i, "cir %u", &cir))
17364         ;
17365       else if (unformat (i, "eir %u", &eir))
17366         ;
17367       else if (unformat (i, "cb %u", &cb))
17368         ;
17369       else if (unformat (i, "eb %u", &eb))
17370         ;
17371       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17372                          &rate_type))
17373         ;
17374       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17375                          &round_type))
17376         ;
17377       else if (unformat (i, "type %U", unformat_policer_type, &type))
17378         ;
17379       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17380                          &conform_action))
17381         ;
17382       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17383                          &exceed_action))
17384         ;
17385       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17386                          &violate_action))
17387         ;
17388       else if (unformat (i, "color-aware"))
17389         color_aware = 1;
17390       else
17391         break;
17392     }
17393
17394   if (!vec_len (name))
17395     {
17396       errmsg ("policer name must be specified");
17397       return -99;
17398     }
17399
17400   if (vec_len (name) > 64)
17401     {
17402       errmsg ("policer name too long");
17403       return -99;
17404     }
17405
17406   M (POLICER_ADD_DEL, mp);
17407
17408   clib_memcpy (mp->name, name, vec_len (name));
17409   vec_free (name);
17410   mp->is_add = is_add;
17411   mp->cir = ntohl (cir);
17412   mp->eir = ntohl (eir);
17413   mp->cb = clib_net_to_host_u64 (cb);
17414   mp->eb = clib_net_to_host_u64 (eb);
17415   mp->rate_type = rate_type;
17416   mp->round_type = round_type;
17417   mp->type = type;
17418   mp->conform_action_type = conform_action.action_type;
17419   mp->conform_dscp = conform_action.dscp;
17420   mp->exceed_action_type = exceed_action.action_type;
17421   mp->exceed_dscp = exceed_action.dscp;
17422   mp->violate_action_type = violate_action.action_type;
17423   mp->violate_dscp = violate_action.dscp;
17424   mp->color_aware = color_aware;
17425
17426   S (mp);
17427   W (ret);
17428   return ret;
17429 }
17430
17431 static int
17432 api_policer_dump (vat_main_t * vam)
17433 {
17434   unformat_input_t *i = vam->input;
17435   vl_api_policer_dump_t *mp;
17436   vl_api_control_ping_t *mp_ping;
17437   u8 *match_name = 0;
17438   u8 match_name_valid = 0;
17439   int ret;
17440
17441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17442     {
17443       if (unformat (i, "name %s", &match_name))
17444         {
17445           vec_add1 (match_name, 0);
17446           match_name_valid = 1;
17447         }
17448       else
17449         break;
17450     }
17451
17452   M (POLICER_DUMP, mp);
17453   mp->match_name_valid = match_name_valid;
17454   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17455   vec_free (match_name);
17456   /* send it... */
17457   S (mp);
17458
17459   /* Use a control ping for synchronization */
17460   MPING (CONTROL_PING, mp_ping);
17461   S (mp_ping);
17462
17463   /* Wait for a reply... */
17464   W (ret);
17465   return ret;
17466 }
17467
17468 static int
17469 api_policer_classify_set_interface (vat_main_t * vam)
17470 {
17471   unformat_input_t *i = vam->input;
17472   vl_api_policer_classify_set_interface_t *mp;
17473   u32 sw_if_index;
17474   int sw_if_index_set;
17475   u32 ip4_table_index = ~0;
17476   u32 ip6_table_index = ~0;
17477   u32 l2_table_index = ~0;
17478   u8 is_add = 1;
17479   int ret;
17480
17481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17482     {
17483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17484         sw_if_index_set = 1;
17485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17486         sw_if_index_set = 1;
17487       else if (unformat (i, "del"))
17488         is_add = 0;
17489       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17490         ;
17491       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17492         ;
17493       else if (unformat (i, "l2-table %d", &l2_table_index))
17494         ;
17495       else
17496         {
17497           clib_warning ("parse error '%U'", format_unformat_error, i);
17498           return -99;
17499         }
17500     }
17501
17502   if (sw_if_index_set == 0)
17503     {
17504       errmsg ("missing interface name or sw_if_index");
17505       return -99;
17506     }
17507
17508   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17509
17510   mp->sw_if_index = ntohl (sw_if_index);
17511   mp->ip4_table_index = ntohl (ip4_table_index);
17512   mp->ip6_table_index = ntohl (ip6_table_index);
17513   mp->l2_table_index = ntohl (l2_table_index);
17514   mp->is_add = is_add;
17515
17516   S (mp);
17517   W (ret);
17518   return ret;
17519 }
17520
17521 static int
17522 api_policer_classify_dump (vat_main_t * vam)
17523 {
17524   unformat_input_t *i = vam->input;
17525   vl_api_policer_classify_dump_t *mp;
17526   vl_api_control_ping_t *mp_ping;
17527   u8 type = POLICER_CLASSIFY_N_TABLES;
17528   int ret;
17529
17530   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17531     ;
17532   else
17533     {
17534       errmsg ("classify table type must be specified");
17535       return -99;
17536     }
17537
17538   if (!vam->json_output)
17539     {
17540       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17541     }
17542
17543   M (POLICER_CLASSIFY_DUMP, mp);
17544   mp->type = type;
17545   /* send it... */
17546   S (mp);
17547
17548   /* Use a control ping for synchronization */
17549   MPING (CONTROL_PING, mp_ping);
17550   S (mp_ping);
17551
17552   /* Wait for a reply... */
17553   W (ret);
17554   return ret;
17555 }
17556
17557 static u8 *
17558 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17559 {
17560   vl_api_fib_path_nh_proto_t proto =
17561     va_arg (*args, vl_api_fib_path_nh_proto_t);
17562
17563   switch (proto)
17564     {
17565     case FIB_API_PATH_NH_PROTO_IP4:
17566       s = format (s, "ip4");
17567       break;
17568     case FIB_API_PATH_NH_PROTO_IP6:
17569       s = format (s, "ip6");
17570       break;
17571     case FIB_API_PATH_NH_PROTO_MPLS:
17572       s = format (s, "mpls");
17573       break;
17574     case FIB_API_PATH_NH_PROTO_BIER:
17575       s = format (s, "bier");
17576       break;
17577     case FIB_API_PATH_NH_PROTO_ETHERNET:
17578       s = format (s, "ethernet");
17579       break;
17580     }
17581
17582   return (s);
17583 }
17584
17585 static u8 *
17586 format_vl_api_ip_address_union (u8 * s, va_list * args)
17587 {
17588   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17589   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17590
17591   switch (af)
17592     {
17593     case ADDRESS_IP4:
17594       s = format (s, "%U", format_ip4_address, u->ip4);
17595       break;
17596     case ADDRESS_IP6:
17597       s = format (s, "%U", format_ip6_address, u->ip6);
17598       break;
17599     }
17600   return (s);
17601 }
17602
17603 static u8 *
17604 format_vl_api_fib_path_type (u8 * s, va_list * args)
17605 {
17606   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17607
17608   switch (t)
17609     {
17610     case FIB_API_PATH_TYPE_NORMAL:
17611       s = format (s, "normal");
17612       break;
17613     case FIB_API_PATH_TYPE_LOCAL:
17614       s = format (s, "local");
17615       break;
17616     case FIB_API_PATH_TYPE_DROP:
17617       s = format (s, "drop");
17618       break;
17619     case FIB_API_PATH_TYPE_UDP_ENCAP:
17620       s = format (s, "udp-encap");
17621       break;
17622     case FIB_API_PATH_TYPE_BIER_IMP:
17623       s = format (s, "bier-imp");
17624       break;
17625     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17626       s = format (s, "unreach");
17627       break;
17628     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17629       s = format (s, "prohibit");
17630       break;
17631     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17632       s = format (s, "src-lookup");
17633       break;
17634     case FIB_API_PATH_TYPE_DVR:
17635       s = format (s, "dvr");
17636       break;
17637     case FIB_API_PATH_TYPE_INTERFACE_RX:
17638       s = format (s, "interface-rx");
17639       break;
17640     case FIB_API_PATH_TYPE_CLASSIFY:
17641       s = format (s, "classify");
17642       break;
17643     }
17644
17645   return (s);
17646 }
17647
17648 static void
17649 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17650 {
17651   print (vam->ofp,
17652          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17653          ntohl (fp->weight), ntohl (fp->sw_if_index),
17654          format_vl_api_fib_path_type, fp->type,
17655          format_fib_api_path_nh_proto, fp->proto,
17656          format_vl_api_ip_address_union, &fp->nh.address);
17657 }
17658
17659 static void
17660 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17661                                  vl_api_fib_path_t * fp)
17662 {
17663   struct in_addr ip4;
17664   struct in6_addr ip6;
17665
17666   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17667   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17668   vat_json_object_add_uint (node, "type", fp->type);
17669   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17670   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17671     {
17672       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17673       vat_json_object_add_ip4 (node, "next_hop", ip4);
17674     }
17675   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17676     {
17677       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17678       vat_json_object_add_ip6 (node, "next_hop", ip6);
17679     }
17680 }
17681
17682 static void
17683 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17684 {
17685   vat_main_t *vam = &vat_main;
17686   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17687   vl_api_fib_path_t *fp;
17688   i32 i;
17689
17690   print (vam->ofp, "sw_if_index %d via:",
17691          ntohl (mp->mt_tunnel.mt_sw_if_index));
17692   fp = mp->mt_tunnel.mt_paths;
17693   for (i = 0; i < count; i++)
17694     {
17695       vl_api_fib_path_print (vam, fp);
17696       fp++;
17697     }
17698
17699   print (vam->ofp, "");
17700 }
17701
17702 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17703 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17704
17705 static void
17706 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17707 {
17708   vat_main_t *vam = &vat_main;
17709   vat_json_node_t *node = NULL;
17710   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17711   vl_api_fib_path_t *fp;
17712   i32 i;
17713
17714   if (VAT_JSON_ARRAY != vam->json_tree.type)
17715     {
17716       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17717       vat_json_init_array (&vam->json_tree);
17718     }
17719   node = vat_json_array_add (&vam->json_tree);
17720
17721   vat_json_init_object (node);
17722   vat_json_object_add_uint (node, "sw_if_index",
17723                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17724
17725   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17726
17727   fp = mp->mt_tunnel.mt_paths;
17728   for (i = 0; i < count; i++)
17729     {
17730       vl_api_mpls_fib_path_json_print (node, fp);
17731       fp++;
17732     }
17733 }
17734
17735 static int
17736 api_mpls_tunnel_dump (vat_main_t * vam)
17737 {
17738   vl_api_mpls_tunnel_dump_t *mp;
17739   vl_api_control_ping_t *mp_ping;
17740   int ret;
17741
17742   M (MPLS_TUNNEL_DUMP, mp);
17743
17744   S (mp);
17745
17746   /* Use a control ping for synchronization */
17747   MPING (CONTROL_PING, mp_ping);
17748   S (mp_ping);
17749
17750   W (ret);
17751   return ret;
17752 }
17753
17754 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17755 #define vl_api_mpls_table_details_t_print vl_noop_handler
17756
17757
17758 static void
17759 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17760 {
17761   vat_main_t *vam = &vat_main;
17762
17763   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17764 }
17765
17766 static void vl_api_mpls_table_details_t_handler_json
17767   (vl_api_mpls_table_details_t * mp)
17768 {
17769   vat_main_t *vam = &vat_main;
17770   vat_json_node_t *node = NULL;
17771
17772   if (VAT_JSON_ARRAY != vam->json_tree.type)
17773     {
17774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17775       vat_json_init_array (&vam->json_tree);
17776     }
17777   node = vat_json_array_add (&vam->json_tree);
17778
17779   vat_json_init_object (node);
17780   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17781 }
17782
17783 static int
17784 api_mpls_table_dump (vat_main_t * vam)
17785 {
17786   vl_api_mpls_table_dump_t *mp;
17787   vl_api_control_ping_t *mp_ping;
17788   int ret;
17789
17790   M (MPLS_TABLE_DUMP, mp);
17791   S (mp);
17792
17793   /* Use a control ping for synchronization */
17794   MPING (CONTROL_PING, mp_ping);
17795   S (mp_ping);
17796
17797   W (ret);
17798   return ret;
17799 }
17800
17801 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17802 #define vl_api_mpls_route_details_t_print vl_noop_handler
17803
17804 static void
17805 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17806 {
17807   vat_main_t *vam = &vat_main;
17808   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17809   vl_api_fib_path_t *fp;
17810   int i;
17811
17812   print (vam->ofp,
17813          "table-id %d, label %u, ess_bit %u",
17814          ntohl (mp->mr_route.mr_table_id),
17815          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17816   fp = mp->mr_route.mr_paths;
17817   for (i = 0; i < count; i++)
17818     {
17819       vl_api_fib_path_print (vam, fp);
17820       fp++;
17821     }
17822 }
17823
17824 static void vl_api_mpls_route_details_t_handler_json
17825   (vl_api_mpls_route_details_t * mp)
17826 {
17827   vat_main_t *vam = &vat_main;
17828   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17829   vat_json_node_t *node = NULL;
17830   vl_api_fib_path_t *fp;
17831   int i;
17832
17833   if (VAT_JSON_ARRAY != vam->json_tree.type)
17834     {
17835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17836       vat_json_init_array (&vam->json_tree);
17837     }
17838   node = vat_json_array_add (&vam->json_tree);
17839
17840   vat_json_init_object (node);
17841   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17842   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17843   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17844   vat_json_object_add_uint (node, "path_count", count);
17845   fp = mp->mr_route.mr_paths;
17846   for (i = 0; i < count; i++)
17847     {
17848       vl_api_mpls_fib_path_json_print (node, fp);
17849       fp++;
17850     }
17851 }
17852
17853 static int
17854 api_mpls_route_dump (vat_main_t * vam)
17855 {
17856   unformat_input_t *input = vam->input;
17857   vl_api_mpls_route_dump_t *mp;
17858   vl_api_control_ping_t *mp_ping;
17859   u32 table_id;
17860   int ret;
17861
17862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17863     {
17864       if (unformat (input, "table_id %d", &table_id))
17865         ;
17866       else
17867         break;
17868     }
17869   if (table_id == ~0)
17870     {
17871       errmsg ("missing table id");
17872       return -99;
17873     }
17874
17875   M (MPLS_ROUTE_DUMP, mp);
17876
17877   mp->table.mt_table_id = ntohl (table_id);
17878   S (mp);
17879
17880   /* Use a control ping for synchronization */
17881   MPING (CONTROL_PING, mp_ping);
17882   S (mp_ping);
17883
17884   W (ret);
17885   return ret;
17886 }
17887
17888 #define vl_api_ip_table_details_t_endian vl_noop_handler
17889 #define vl_api_ip_table_details_t_print vl_noop_handler
17890
17891 static void
17892 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17893 {
17894   vat_main_t *vam = &vat_main;
17895
17896   print (vam->ofp,
17897          "%s; table-id %d, prefix %U/%d",
17898          mp->table.name, ntohl (mp->table.table_id));
17899 }
17900
17901
17902 static void vl_api_ip_table_details_t_handler_json
17903   (vl_api_ip_table_details_t * mp)
17904 {
17905   vat_main_t *vam = &vat_main;
17906   vat_json_node_t *node = NULL;
17907
17908   if (VAT_JSON_ARRAY != vam->json_tree.type)
17909     {
17910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17911       vat_json_init_array (&vam->json_tree);
17912     }
17913   node = vat_json_array_add (&vam->json_tree);
17914
17915   vat_json_init_object (node);
17916   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17917 }
17918
17919 static int
17920 api_ip_table_dump (vat_main_t * vam)
17921 {
17922   vl_api_ip_table_dump_t *mp;
17923   vl_api_control_ping_t *mp_ping;
17924   int ret;
17925
17926   M (IP_TABLE_DUMP, mp);
17927   S (mp);
17928
17929   /* Use a control ping for synchronization */
17930   MPING (CONTROL_PING, mp_ping);
17931   S (mp_ping);
17932
17933   W (ret);
17934   return ret;
17935 }
17936
17937 static int
17938 api_ip_mtable_dump (vat_main_t * vam)
17939 {
17940   vl_api_ip_mtable_dump_t *mp;
17941   vl_api_control_ping_t *mp_ping;
17942   int ret;
17943
17944   M (IP_MTABLE_DUMP, mp);
17945   S (mp);
17946
17947   /* Use a control ping for synchronization */
17948   MPING (CONTROL_PING, mp_ping);
17949   S (mp_ping);
17950
17951   W (ret);
17952   return ret;
17953 }
17954
17955 static int
17956 api_ip_mroute_dump (vat_main_t * vam)
17957 {
17958   unformat_input_t *input = vam->input;
17959   vl_api_control_ping_t *mp_ping;
17960   vl_api_ip_mroute_dump_t *mp;
17961   int ret, is_ip6;
17962   u32 table_id;
17963
17964   is_ip6 = 0;
17965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17966     {
17967       if (unformat (input, "table_id %d", &table_id))
17968         ;
17969       else if (unformat (input, "ip6"))
17970         is_ip6 = 1;
17971       else if (unformat (input, "ip4"))
17972         is_ip6 = 0;
17973       else
17974         break;
17975     }
17976   if (table_id == ~0)
17977     {
17978       errmsg ("missing table id");
17979       return -99;
17980     }
17981
17982   M (IP_MROUTE_DUMP, mp);
17983   mp->table.table_id = table_id;
17984   mp->table.is_ip6 = is_ip6;
17985   S (mp);
17986
17987   /* Use a control ping for synchronization */
17988   MPING (CONTROL_PING, mp_ping);
17989   S (mp_ping);
17990
17991   W (ret);
17992   return ret;
17993 }
17994
17995 #define vl_api_ip_route_details_t_endian vl_noop_handler
17996 #define vl_api_ip_route_details_t_print vl_noop_handler
17997
17998 static void
17999 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18000 {
18001   vat_main_t *vam = &vat_main;
18002   u8 count = mp->route.n_paths;
18003   vl_api_fib_path_t *fp;
18004   int i;
18005
18006   print (vam->ofp,
18007          "table-id %d, prefix %U/%d",
18008          ntohl (mp->route.table_id),
18009          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18010   for (i = 0; i < count; i++)
18011     {
18012       fp = &mp->route.paths[i];
18013
18014       vl_api_fib_path_print (vam, fp);
18015       fp++;
18016     }
18017 }
18018
18019 static void vl_api_ip_route_details_t_handler_json
18020   (vl_api_ip_route_details_t * mp)
18021 {
18022   vat_main_t *vam = &vat_main;
18023   u8 count = mp->route.n_paths;
18024   vat_json_node_t *node = NULL;
18025   struct in_addr ip4;
18026   struct in6_addr ip6;
18027   vl_api_fib_path_t *fp;
18028   int i;
18029
18030   if (VAT_JSON_ARRAY != vam->json_tree.type)
18031     {
18032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18033       vat_json_init_array (&vam->json_tree);
18034     }
18035   node = vat_json_array_add (&vam->json_tree);
18036
18037   vat_json_init_object (node);
18038   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18039   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18040     {
18041       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18042       vat_json_object_add_ip6 (node, "prefix", ip6);
18043     }
18044   else
18045     {
18046       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18047       vat_json_object_add_ip4 (node, "prefix", ip4);
18048     }
18049   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18050   vat_json_object_add_uint (node, "path_count", count);
18051   for (i = 0; i < count; i++)
18052     {
18053       fp = &mp->route.paths[i];
18054       vl_api_mpls_fib_path_json_print (node, fp);
18055     }
18056 }
18057
18058 static int
18059 api_ip_route_dump (vat_main_t * vam)
18060 {
18061   unformat_input_t *input = vam->input;
18062   vl_api_ip_route_dump_t *mp;
18063   vl_api_control_ping_t *mp_ping;
18064   u32 table_id;
18065   u8 is_ip6;
18066   int ret;
18067
18068   is_ip6 = 0;
18069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18070     {
18071       if (unformat (input, "table_id %d", &table_id))
18072         ;
18073       else if (unformat (input, "ip6"))
18074         is_ip6 = 1;
18075       else if (unformat (input, "ip4"))
18076         is_ip6 = 0;
18077       else
18078         break;
18079     }
18080   if (table_id == ~0)
18081     {
18082       errmsg ("missing table id");
18083       return -99;
18084     }
18085
18086   M (IP_ROUTE_DUMP, mp);
18087
18088   mp->table.table_id = table_id;
18089   mp->table.is_ip6 = is_ip6;
18090
18091   S (mp);
18092
18093   /* Use a control ping for synchronization */
18094   MPING (CONTROL_PING, mp_ping);
18095   S (mp_ping);
18096
18097   W (ret);
18098   return ret;
18099 }
18100
18101 int
18102 api_classify_table_ids (vat_main_t * vam)
18103 {
18104   vl_api_classify_table_ids_t *mp;
18105   int ret;
18106
18107   /* Construct the API message */
18108   M (CLASSIFY_TABLE_IDS, mp);
18109   mp->context = 0;
18110
18111   S (mp);
18112   W (ret);
18113   return ret;
18114 }
18115
18116 int
18117 api_classify_table_by_interface (vat_main_t * vam)
18118 {
18119   unformat_input_t *input = vam->input;
18120   vl_api_classify_table_by_interface_t *mp;
18121
18122   u32 sw_if_index = ~0;
18123   int ret;
18124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18125     {
18126       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18127         ;
18128       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18129         ;
18130       else
18131         break;
18132     }
18133   if (sw_if_index == ~0)
18134     {
18135       errmsg ("missing interface name or sw_if_index");
18136       return -99;
18137     }
18138
18139   /* Construct the API message */
18140   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18141   mp->context = 0;
18142   mp->sw_if_index = ntohl (sw_if_index);
18143
18144   S (mp);
18145   W (ret);
18146   return ret;
18147 }
18148
18149 int
18150 api_classify_table_info (vat_main_t * vam)
18151 {
18152   unformat_input_t *input = vam->input;
18153   vl_api_classify_table_info_t *mp;
18154
18155   u32 table_id = ~0;
18156   int ret;
18157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18158     {
18159       if (unformat (input, "table_id %d", &table_id))
18160         ;
18161       else
18162         break;
18163     }
18164   if (table_id == ~0)
18165     {
18166       errmsg ("missing table id");
18167       return -99;
18168     }
18169
18170   /* Construct the API message */
18171   M (CLASSIFY_TABLE_INFO, mp);
18172   mp->context = 0;
18173   mp->table_id = ntohl (table_id);
18174
18175   S (mp);
18176   W (ret);
18177   return ret;
18178 }
18179
18180 int
18181 api_classify_session_dump (vat_main_t * vam)
18182 {
18183   unformat_input_t *input = vam->input;
18184   vl_api_classify_session_dump_t *mp;
18185   vl_api_control_ping_t *mp_ping;
18186
18187   u32 table_id = ~0;
18188   int ret;
18189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18190     {
18191       if (unformat (input, "table_id %d", &table_id))
18192         ;
18193       else
18194         break;
18195     }
18196   if (table_id == ~0)
18197     {
18198       errmsg ("missing table id");
18199       return -99;
18200     }
18201
18202   /* Construct the API message */
18203   M (CLASSIFY_SESSION_DUMP, mp);
18204   mp->context = 0;
18205   mp->table_id = ntohl (table_id);
18206   S (mp);
18207
18208   /* Use a control ping for synchronization */
18209   MPING (CONTROL_PING, mp_ping);
18210   S (mp_ping);
18211
18212   W (ret);
18213   return ret;
18214 }
18215
18216 static void
18217 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18218 {
18219   vat_main_t *vam = &vat_main;
18220
18221   print (vam->ofp, "collector_address %U, collector_port %d, "
18222          "src_address %U, vrf_id %d, path_mtu %u, "
18223          "template_interval %u, udp_checksum %d",
18224          format_ip4_address, mp->collector_address,
18225          ntohs (mp->collector_port),
18226          format_ip4_address, mp->src_address,
18227          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18228          ntohl (mp->template_interval), mp->udp_checksum);
18229
18230   vam->retval = 0;
18231   vam->result_ready = 1;
18232 }
18233
18234 static void
18235   vl_api_ipfix_exporter_details_t_handler_json
18236   (vl_api_ipfix_exporter_details_t * mp)
18237 {
18238   vat_main_t *vam = &vat_main;
18239   vat_json_node_t node;
18240   struct in_addr collector_address;
18241   struct in_addr src_address;
18242
18243   vat_json_init_object (&node);
18244   clib_memcpy (&collector_address, &mp->collector_address,
18245                sizeof (collector_address));
18246   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18247   vat_json_object_add_uint (&node, "collector_port",
18248                             ntohs (mp->collector_port));
18249   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18250   vat_json_object_add_ip4 (&node, "src_address", src_address);
18251   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18252   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18253   vat_json_object_add_uint (&node, "template_interval",
18254                             ntohl (mp->template_interval));
18255   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18256
18257   vat_json_print (vam->ofp, &node);
18258   vat_json_free (&node);
18259   vam->retval = 0;
18260   vam->result_ready = 1;
18261 }
18262
18263 int
18264 api_ipfix_exporter_dump (vat_main_t * vam)
18265 {
18266   vl_api_ipfix_exporter_dump_t *mp;
18267   int ret;
18268
18269   /* Construct the API message */
18270   M (IPFIX_EXPORTER_DUMP, mp);
18271   mp->context = 0;
18272
18273   S (mp);
18274   W (ret);
18275   return ret;
18276 }
18277
18278 static int
18279 api_ipfix_classify_stream_dump (vat_main_t * vam)
18280 {
18281   vl_api_ipfix_classify_stream_dump_t *mp;
18282   int ret;
18283
18284   /* Construct the API message */
18285   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18286   mp->context = 0;
18287
18288   S (mp);
18289   W (ret);
18290   return ret;
18291   /* NOTREACHED */
18292   return 0;
18293 }
18294
18295 static void
18296   vl_api_ipfix_classify_stream_details_t_handler
18297   (vl_api_ipfix_classify_stream_details_t * mp)
18298 {
18299   vat_main_t *vam = &vat_main;
18300   print (vam->ofp, "domain_id %d, src_port %d",
18301          ntohl (mp->domain_id), ntohs (mp->src_port));
18302   vam->retval = 0;
18303   vam->result_ready = 1;
18304 }
18305
18306 static void
18307   vl_api_ipfix_classify_stream_details_t_handler_json
18308   (vl_api_ipfix_classify_stream_details_t * mp)
18309 {
18310   vat_main_t *vam = &vat_main;
18311   vat_json_node_t node;
18312
18313   vat_json_init_object (&node);
18314   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18315   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18316
18317   vat_json_print (vam->ofp, &node);
18318   vat_json_free (&node);
18319   vam->retval = 0;
18320   vam->result_ready = 1;
18321 }
18322
18323 static int
18324 api_ipfix_classify_table_dump (vat_main_t * vam)
18325 {
18326   vl_api_ipfix_classify_table_dump_t *mp;
18327   vl_api_control_ping_t *mp_ping;
18328   int ret;
18329
18330   if (!vam->json_output)
18331     {
18332       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18333              "transport_protocol");
18334     }
18335
18336   /* Construct the API message */
18337   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18338
18339   /* send it... */
18340   S (mp);
18341
18342   /* Use a control ping for synchronization */
18343   MPING (CONTROL_PING, mp_ping);
18344   S (mp_ping);
18345
18346   W (ret);
18347   return ret;
18348 }
18349
18350 static void
18351   vl_api_ipfix_classify_table_details_t_handler
18352   (vl_api_ipfix_classify_table_details_t * mp)
18353 {
18354   vat_main_t *vam = &vat_main;
18355   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18356          mp->transport_protocol);
18357 }
18358
18359 static void
18360   vl_api_ipfix_classify_table_details_t_handler_json
18361   (vl_api_ipfix_classify_table_details_t * mp)
18362 {
18363   vat_json_node_t *node = NULL;
18364   vat_main_t *vam = &vat_main;
18365
18366   if (VAT_JSON_ARRAY != vam->json_tree.type)
18367     {
18368       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18369       vat_json_init_array (&vam->json_tree);
18370     }
18371
18372   node = vat_json_array_add (&vam->json_tree);
18373   vat_json_init_object (node);
18374
18375   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18376   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18377   vat_json_object_add_uint (node, "transport_protocol",
18378                             mp->transport_protocol);
18379 }
18380
18381 static int
18382 api_sw_interface_span_enable_disable (vat_main_t * vam)
18383 {
18384   unformat_input_t *i = vam->input;
18385   vl_api_sw_interface_span_enable_disable_t *mp;
18386   u32 src_sw_if_index = ~0;
18387   u32 dst_sw_if_index = ~0;
18388   u8 state = 3;
18389   int ret;
18390   u8 is_l2 = 0;
18391
18392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18393     {
18394       if (unformat
18395           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18396         ;
18397       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18398         ;
18399       else
18400         if (unformat
18401             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18402         ;
18403       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18404         ;
18405       else if (unformat (i, "disable"))
18406         state = 0;
18407       else if (unformat (i, "rx"))
18408         state = 1;
18409       else if (unformat (i, "tx"))
18410         state = 2;
18411       else if (unformat (i, "both"))
18412         state = 3;
18413       else if (unformat (i, "l2"))
18414         is_l2 = 1;
18415       else
18416         break;
18417     }
18418
18419   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18420
18421   mp->sw_if_index_from = htonl (src_sw_if_index);
18422   mp->sw_if_index_to = htonl (dst_sw_if_index);
18423   mp->state = state;
18424   mp->is_l2 = is_l2;
18425
18426   S (mp);
18427   W (ret);
18428   return ret;
18429 }
18430
18431 static void
18432 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18433                                             * mp)
18434 {
18435   vat_main_t *vam = &vat_main;
18436   u8 *sw_if_from_name = 0;
18437   u8 *sw_if_to_name = 0;
18438   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18439   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18440   char *states[] = { "none", "rx", "tx", "both" };
18441   hash_pair_t *p;
18442
18443   /* *INDENT-OFF* */
18444   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18445   ({
18446     if ((u32) p->value[0] == sw_if_index_from)
18447       {
18448         sw_if_from_name = (u8 *)(p->key);
18449         if (sw_if_to_name)
18450           break;
18451       }
18452     if ((u32) p->value[0] == sw_if_index_to)
18453       {
18454         sw_if_to_name = (u8 *)(p->key);
18455         if (sw_if_from_name)
18456           break;
18457       }
18458   }));
18459   /* *INDENT-ON* */
18460   print (vam->ofp, "%20s => %20s (%s) %s",
18461          sw_if_from_name, sw_if_to_name, states[mp->state],
18462          mp->is_l2 ? "l2" : "device");
18463 }
18464
18465 static void
18466   vl_api_sw_interface_span_details_t_handler_json
18467   (vl_api_sw_interface_span_details_t * mp)
18468 {
18469   vat_main_t *vam = &vat_main;
18470   vat_json_node_t *node = NULL;
18471   u8 *sw_if_from_name = 0;
18472   u8 *sw_if_to_name = 0;
18473   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18474   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18475   hash_pair_t *p;
18476
18477   /* *INDENT-OFF* */
18478   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18479   ({
18480     if ((u32) p->value[0] == sw_if_index_from)
18481       {
18482         sw_if_from_name = (u8 *)(p->key);
18483         if (sw_if_to_name)
18484           break;
18485       }
18486     if ((u32) p->value[0] == sw_if_index_to)
18487       {
18488         sw_if_to_name = (u8 *)(p->key);
18489         if (sw_if_from_name)
18490           break;
18491       }
18492   }));
18493   /* *INDENT-ON* */
18494
18495   if (VAT_JSON_ARRAY != vam->json_tree.type)
18496     {
18497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18498       vat_json_init_array (&vam->json_tree);
18499     }
18500   node = vat_json_array_add (&vam->json_tree);
18501
18502   vat_json_init_object (node);
18503   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18504   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18505   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18506   if (0 != sw_if_to_name)
18507     {
18508       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18509     }
18510   vat_json_object_add_uint (node, "state", mp->state);
18511   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18512 }
18513
18514 static int
18515 api_sw_interface_span_dump (vat_main_t * vam)
18516 {
18517   unformat_input_t *input = vam->input;
18518   vl_api_sw_interface_span_dump_t *mp;
18519   vl_api_control_ping_t *mp_ping;
18520   u8 is_l2 = 0;
18521   int ret;
18522
18523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18524     {
18525       if (unformat (input, "l2"))
18526         is_l2 = 1;
18527       else
18528         break;
18529     }
18530
18531   M (SW_INTERFACE_SPAN_DUMP, mp);
18532   mp->is_l2 = is_l2;
18533   S (mp);
18534
18535   /* Use a control ping for synchronization */
18536   MPING (CONTROL_PING, mp_ping);
18537   S (mp_ping);
18538
18539   W (ret);
18540   return ret;
18541 }
18542
18543 int
18544 api_pg_create_interface (vat_main_t * vam)
18545 {
18546   unformat_input_t *input = vam->input;
18547   vl_api_pg_create_interface_t *mp;
18548
18549   u32 if_id = ~0, gso_size = 0;
18550   u8 gso_enabled = 0;
18551   int ret;
18552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (input, "if_id %d", &if_id))
18555         ;
18556       else if (unformat (input, "gso-enabled"))
18557         {
18558           gso_enabled = 1;
18559           if (unformat (input, "gso-size %u", &gso_size))
18560             ;
18561           else
18562             {
18563               errmsg ("missing gso-size");
18564               return -99;
18565             }
18566         }
18567       else
18568         break;
18569     }
18570   if (if_id == ~0)
18571     {
18572       errmsg ("missing pg interface index");
18573       return -99;
18574     }
18575
18576   /* Construct the API message */
18577   M (PG_CREATE_INTERFACE, mp);
18578   mp->context = 0;
18579   mp->interface_id = ntohl (if_id);
18580   mp->gso_enabled = gso_enabled;
18581
18582   S (mp);
18583   W (ret);
18584   return ret;
18585 }
18586
18587 int
18588 api_pg_capture (vat_main_t * vam)
18589 {
18590   unformat_input_t *input = vam->input;
18591   vl_api_pg_capture_t *mp;
18592
18593   u32 if_id = ~0;
18594   u8 enable = 1;
18595   u32 count = 1;
18596   u8 pcap_file_set = 0;
18597   u8 *pcap_file = 0;
18598   int ret;
18599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18600     {
18601       if (unformat (input, "if_id %d", &if_id))
18602         ;
18603       else if (unformat (input, "pcap %s", &pcap_file))
18604         pcap_file_set = 1;
18605       else if (unformat (input, "count %d", &count))
18606         ;
18607       else if (unformat (input, "disable"))
18608         enable = 0;
18609       else
18610         break;
18611     }
18612   if (if_id == ~0)
18613     {
18614       errmsg ("missing pg interface index");
18615       return -99;
18616     }
18617   if (pcap_file_set > 0)
18618     {
18619       if (vec_len (pcap_file) > 255)
18620         {
18621           errmsg ("pcap file name is too long");
18622           return -99;
18623         }
18624     }
18625
18626   /* Construct the API message */
18627   M (PG_CAPTURE, mp);
18628   mp->context = 0;
18629   mp->interface_id = ntohl (if_id);
18630   mp->is_enabled = enable;
18631   mp->count = ntohl (count);
18632   if (pcap_file_set != 0)
18633     {
18634       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18635     }
18636   vec_free (pcap_file);
18637
18638   S (mp);
18639   W (ret);
18640   return ret;
18641 }
18642
18643 int
18644 api_pg_enable_disable (vat_main_t * vam)
18645 {
18646   unformat_input_t *input = vam->input;
18647   vl_api_pg_enable_disable_t *mp;
18648
18649   u8 enable = 1;
18650   u8 stream_name_set = 0;
18651   u8 *stream_name = 0;
18652   int ret;
18653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18654     {
18655       if (unformat (input, "stream %s", &stream_name))
18656         stream_name_set = 1;
18657       else if (unformat (input, "disable"))
18658         enable = 0;
18659       else
18660         break;
18661     }
18662
18663   if (stream_name_set > 0)
18664     {
18665       if (vec_len (stream_name) > 255)
18666         {
18667           errmsg ("stream name too long");
18668           return -99;
18669         }
18670     }
18671
18672   /* Construct the API message */
18673   M (PG_ENABLE_DISABLE, mp);
18674   mp->context = 0;
18675   mp->is_enabled = enable;
18676   if (stream_name_set != 0)
18677     {
18678       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18679     }
18680   vec_free (stream_name);
18681
18682   S (mp);
18683   W (ret);
18684   return ret;
18685 }
18686
18687 int
18688 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18689 {
18690   unformat_input_t *input = vam->input;
18691   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18692
18693   u16 *low_ports = 0;
18694   u16 *high_ports = 0;
18695   u16 this_low;
18696   u16 this_hi;
18697   vl_api_prefix_t prefix;
18698   u32 tmp, tmp2;
18699   u8 prefix_set = 0;
18700   u32 vrf_id = ~0;
18701   u8 is_add = 1;
18702   int ret;
18703
18704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18705     {
18706       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18707         prefix_set = 1;
18708       else if (unformat (input, "vrf %d", &vrf_id))
18709         ;
18710       else if (unformat (input, "del"))
18711         is_add = 0;
18712       else if (unformat (input, "port %d", &tmp))
18713         {
18714           if (tmp == 0 || tmp > 65535)
18715             {
18716               errmsg ("port %d out of range", tmp);
18717               return -99;
18718             }
18719           this_low = tmp;
18720           this_hi = this_low + 1;
18721           vec_add1 (low_ports, this_low);
18722           vec_add1 (high_ports, this_hi);
18723         }
18724       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18725         {
18726           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18727             {
18728               errmsg ("incorrect range parameters");
18729               return -99;
18730             }
18731           this_low = tmp;
18732           /* Note: in debug CLI +1 is added to high before
18733              passing to real fn that does "the work"
18734              (ip_source_and_port_range_check_add_del).
18735              This fn is a wrapper around the binary API fn a
18736              control plane will call, which expects this increment
18737              to have occurred. Hence letting the binary API control
18738              plane fn do the increment for consistency between VAT
18739              and other control planes.
18740            */
18741           this_hi = tmp2;
18742           vec_add1 (low_ports, this_low);
18743           vec_add1 (high_ports, this_hi);
18744         }
18745       else
18746         break;
18747     }
18748
18749   if (prefix_set == 0)
18750     {
18751       errmsg ("<address>/<mask> not specified");
18752       return -99;
18753     }
18754
18755   if (vrf_id == ~0)
18756     {
18757       errmsg ("VRF ID required, not specified");
18758       return -99;
18759     }
18760
18761   if (vrf_id == 0)
18762     {
18763       errmsg
18764         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18765       return -99;
18766     }
18767
18768   if (vec_len (low_ports) == 0)
18769     {
18770       errmsg ("At least one port or port range required");
18771       return -99;
18772     }
18773
18774   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18775
18776   mp->is_add = is_add;
18777
18778   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18779
18780   mp->number_of_ranges = vec_len (low_ports);
18781
18782   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18783   vec_free (low_ports);
18784
18785   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18786   vec_free (high_ports);
18787
18788   mp->vrf_id = ntohl (vrf_id);
18789
18790   S (mp);
18791   W (ret);
18792   return ret;
18793 }
18794
18795 int
18796 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18797 {
18798   unformat_input_t *input = vam->input;
18799   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18800   u32 sw_if_index = ~0;
18801   int vrf_set = 0;
18802   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18803   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18804   u8 is_add = 1;
18805   int ret;
18806
18807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18808     {
18809       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18810         ;
18811       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18812         ;
18813       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18814         vrf_set = 1;
18815       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18816         vrf_set = 1;
18817       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18818         vrf_set = 1;
18819       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18820         vrf_set = 1;
18821       else if (unformat (input, "del"))
18822         is_add = 0;
18823       else
18824         break;
18825     }
18826
18827   if (sw_if_index == ~0)
18828     {
18829       errmsg ("Interface required but not specified");
18830       return -99;
18831     }
18832
18833   if (vrf_set == 0)
18834     {
18835       errmsg ("VRF ID required but not specified");
18836       return -99;
18837     }
18838
18839   if (tcp_out_vrf_id == 0
18840       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18841     {
18842       errmsg
18843         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18844       return -99;
18845     }
18846
18847   /* Construct the API message */
18848   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18849
18850   mp->sw_if_index = ntohl (sw_if_index);
18851   mp->is_add = is_add;
18852   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18853   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18854   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18855   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18856
18857   /* send it... */
18858   S (mp);
18859
18860   /* Wait for a reply... */
18861   W (ret);
18862   return ret;
18863 }
18864
18865 static int
18866 api_set_punt (vat_main_t * vam)
18867 {
18868   unformat_input_t *i = vam->input;
18869   vl_api_address_family_t af;
18870   vl_api_set_punt_t *mp;
18871   u32 protocol = ~0;
18872   u32 port = ~0;
18873   int is_add = 1;
18874   int ret;
18875
18876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18877     {
18878       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18879         ;
18880       else if (unformat (i, "protocol %d", &protocol))
18881         ;
18882       else if (unformat (i, "port %d", &port))
18883         ;
18884       else if (unformat (i, "del"))
18885         is_add = 0;
18886       else
18887         {
18888           clib_warning ("parse error '%U'", format_unformat_error, i);
18889           return -99;
18890         }
18891     }
18892
18893   M (SET_PUNT, mp);
18894
18895   mp->is_add = (u8) is_add;
18896   mp->punt.type = PUNT_API_TYPE_L4;
18897   mp->punt.punt.l4.af = af;
18898   mp->punt.punt.l4.protocol = (u8) protocol;
18899   mp->punt.punt.l4.port = htons ((u16) port);
18900
18901   S (mp);
18902   W (ret);
18903   return ret;
18904 }
18905
18906 static int
18907 api_delete_subif (vat_main_t * vam)
18908 {
18909   unformat_input_t *i = vam->input;
18910   vl_api_delete_subif_t *mp;
18911   u32 sw_if_index = ~0;
18912   int ret;
18913
18914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18915     {
18916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18917         ;
18918       if (unformat (i, "sw_if_index %d", &sw_if_index))
18919         ;
18920       else
18921         break;
18922     }
18923
18924   if (sw_if_index == ~0)
18925     {
18926       errmsg ("missing sw_if_index");
18927       return -99;
18928     }
18929
18930   /* Construct the API message */
18931   M (DELETE_SUBIF, mp);
18932   mp->sw_if_index = ntohl (sw_if_index);
18933
18934   S (mp);
18935   W (ret);
18936   return ret;
18937 }
18938
18939 #define foreach_pbb_vtr_op      \
18940 _("disable",  L2_VTR_DISABLED)  \
18941 _("pop",  L2_VTR_POP_2)         \
18942 _("push",  L2_VTR_PUSH_2)
18943
18944 static int
18945 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18946 {
18947   unformat_input_t *i = vam->input;
18948   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18949   u32 sw_if_index = ~0, vtr_op = ~0;
18950   u16 outer_tag = ~0;
18951   u8 dmac[6], smac[6];
18952   u8 dmac_set = 0, smac_set = 0;
18953   u16 vlanid = 0;
18954   u32 sid = ~0;
18955   u32 tmp;
18956   int ret;
18957
18958   /* Shut up coverity */
18959   clib_memset (dmac, 0, sizeof (dmac));
18960   clib_memset (smac, 0, sizeof (smac));
18961
18962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18963     {
18964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18965         ;
18966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18967         ;
18968       else if (unformat (i, "vtr_op %d", &vtr_op))
18969         ;
18970 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18971       foreach_pbb_vtr_op
18972 #undef _
18973         else if (unformat (i, "translate_pbb_stag"))
18974         {
18975           if (unformat (i, "%d", &tmp))
18976             {
18977               vtr_op = L2_VTR_TRANSLATE_2_1;
18978               outer_tag = tmp;
18979             }
18980           else
18981             {
18982               errmsg
18983                 ("translate_pbb_stag operation requires outer tag definition");
18984               return -99;
18985             }
18986         }
18987       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18988         dmac_set++;
18989       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18990         smac_set++;
18991       else if (unformat (i, "sid %d", &sid))
18992         ;
18993       else if (unformat (i, "vlanid %d", &tmp))
18994         vlanid = tmp;
18995       else
18996         {
18997           clib_warning ("parse error '%U'", format_unformat_error, i);
18998           return -99;
18999         }
19000     }
19001
19002   if ((sw_if_index == ~0) || (vtr_op == ~0))
19003     {
19004       errmsg ("missing sw_if_index or vtr operation");
19005       return -99;
19006     }
19007   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19008       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19009     {
19010       errmsg
19011         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19012       return -99;
19013     }
19014
19015   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19016   mp->sw_if_index = ntohl (sw_if_index);
19017   mp->vtr_op = ntohl (vtr_op);
19018   mp->outer_tag = ntohs (outer_tag);
19019   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19020   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19021   mp->b_vlanid = ntohs (vlanid);
19022   mp->i_sid = ntohl (sid);
19023
19024   S (mp);
19025   W (ret);
19026   return ret;
19027 }
19028
19029 static int
19030 api_flow_classify_set_interface (vat_main_t * vam)
19031 {
19032   unformat_input_t *i = vam->input;
19033   vl_api_flow_classify_set_interface_t *mp;
19034   u32 sw_if_index;
19035   int sw_if_index_set;
19036   u32 ip4_table_index = ~0;
19037   u32 ip6_table_index = ~0;
19038   u8 is_add = 1;
19039   int ret;
19040
19041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19042     {
19043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19044         sw_if_index_set = 1;
19045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19046         sw_if_index_set = 1;
19047       else if (unformat (i, "del"))
19048         is_add = 0;
19049       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19050         ;
19051       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19052         ;
19053       else
19054         {
19055           clib_warning ("parse error '%U'", format_unformat_error, i);
19056           return -99;
19057         }
19058     }
19059
19060   if (sw_if_index_set == 0)
19061     {
19062       errmsg ("missing interface name or sw_if_index");
19063       return -99;
19064     }
19065
19066   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19067
19068   mp->sw_if_index = ntohl (sw_if_index);
19069   mp->ip4_table_index = ntohl (ip4_table_index);
19070   mp->ip6_table_index = ntohl (ip6_table_index);
19071   mp->is_add = is_add;
19072
19073   S (mp);
19074   W (ret);
19075   return ret;
19076 }
19077
19078 static int
19079 api_flow_classify_dump (vat_main_t * vam)
19080 {
19081   unformat_input_t *i = vam->input;
19082   vl_api_flow_classify_dump_t *mp;
19083   vl_api_control_ping_t *mp_ping;
19084   u8 type = FLOW_CLASSIFY_N_TABLES;
19085   int ret;
19086
19087   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19088     ;
19089   else
19090     {
19091       errmsg ("classify table type must be specified");
19092       return -99;
19093     }
19094
19095   if (!vam->json_output)
19096     {
19097       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19098     }
19099
19100   M (FLOW_CLASSIFY_DUMP, mp);
19101   mp->type = type;
19102   /* send it... */
19103   S (mp);
19104
19105   /* Use a control ping for synchronization */
19106   MPING (CONTROL_PING, mp_ping);
19107   S (mp_ping);
19108
19109   /* Wait for a reply... */
19110   W (ret);
19111   return ret;
19112 }
19113
19114 static int
19115 api_feature_enable_disable (vat_main_t * vam)
19116 {
19117   unformat_input_t *i = vam->input;
19118   vl_api_feature_enable_disable_t *mp;
19119   u8 *arc_name = 0;
19120   u8 *feature_name = 0;
19121   u32 sw_if_index = ~0;
19122   u8 enable = 1;
19123   int ret;
19124
19125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19126     {
19127       if (unformat (i, "arc_name %s", &arc_name))
19128         ;
19129       else if (unformat (i, "feature_name %s", &feature_name))
19130         ;
19131       else
19132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19133         ;
19134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19135         ;
19136       else if (unformat (i, "disable"))
19137         enable = 0;
19138       else
19139         break;
19140     }
19141
19142   if (arc_name == 0)
19143     {
19144       errmsg ("missing arc name");
19145       return -99;
19146     }
19147   if (vec_len (arc_name) > 63)
19148     {
19149       errmsg ("arc name too long");
19150     }
19151
19152   if (feature_name == 0)
19153     {
19154       errmsg ("missing feature name");
19155       return -99;
19156     }
19157   if (vec_len (feature_name) > 63)
19158     {
19159       errmsg ("feature name too long");
19160     }
19161
19162   if (sw_if_index == ~0)
19163     {
19164       errmsg ("missing interface name or sw_if_index");
19165       return -99;
19166     }
19167
19168   /* Construct the API message */
19169   M (FEATURE_ENABLE_DISABLE, mp);
19170   mp->sw_if_index = ntohl (sw_if_index);
19171   mp->enable = enable;
19172   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19173   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19174   vec_free (arc_name);
19175   vec_free (feature_name);
19176
19177   S (mp);
19178   W (ret);
19179   return ret;
19180 }
19181
19182 static int
19183 api_feature_gso_enable_disable (vat_main_t * vam)
19184 {
19185   unformat_input_t *i = vam->input;
19186   vl_api_feature_gso_enable_disable_t *mp;
19187   u32 sw_if_index = ~0;
19188   u8 enable = 1;
19189   int ret;
19190
19191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19192     {
19193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19194         ;
19195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19196         ;
19197       else if (unformat (i, "enable"))
19198         enable = 1;
19199       else if (unformat (i, "disable"))
19200         enable = 0;
19201       else
19202         break;
19203     }
19204
19205   if (sw_if_index == ~0)
19206     {
19207       errmsg ("missing interface name or sw_if_index");
19208       return -99;
19209     }
19210
19211   /* Construct the API message */
19212   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19213   mp->sw_if_index = ntohl (sw_if_index);
19214   mp->enable_disable = enable;
19215
19216   S (mp);
19217   W (ret);
19218   return ret;
19219 }
19220
19221 static int
19222 api_sw_interface_tag_add_del (vat_main_t * vam)
19223 {
19224   unformat_input_t *i = vam->input;
19225   vl_api_sw_interface_tag_add_del_t *mp;
19226   u32 sw_if_index = ~0;
19227   u8 *tag = 0;
19228   u8 enable = 1;
19229   int ret;
19230
19231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19232     {
19233       if (unformat (i, "tag %s", &tag))
19234         ;
19235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19236         ;
19237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19238         ;
19239       else if (unformat (i, "del"))
19240         enable = 0;
19241       else
19242         break;
19243     }
19244
19245   if (sw_if_index == ~0)
19246     {
19247       errmsg ("missing interface name or sw_if_index");
19248       return -99;
19249     }
19250
19251   if (enable && (tag == 0))
19252     {
19253       errmsg ("no tag specified");
19254       return -99;
19255     }
19256
19257   /* Construct the API message */
19258   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19259   mp->sw_if_index = ntohl (sw_if_index);
19260   mp->is_add = enable;
19261   if (enable)
19262     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19263   vec_free (tag);
19264
19265   S (mp);
19266   W (ret);
19267   return ret;
19268 }
19269
19270 static int
19271 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19272 {
19273   unformat_input_t *i = vam->input;
19274   vl_api_mac_address_t mac = { 0 };
19275   vl_api_sw_interface_add_del_mac_address_t *mp;
19276   u32 sw_if_index = ~0;
19277   u8 is_add = 1;
19278   u8 mac_set = 0;
19279   int ret;
19280
19281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19282     {
19283       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19284         ;
19285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19286         ;
19287       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19288         mac_set++;
19289       else if (unformat (i, "del"))
19290         is_add = 0;
19291       else
19292         break;
19293     }
19294
19295   if (sw_if_index == ~0)
19296     {
19297       errmsg ("missing interface name or sw_if_index");
19298       return -99;
19299     }
19300
19301   if (!mac_set)
19302     {
19303       errmsg ("missing MAC address");
19304       return -99;
19305     }
19306
19307   /* Construct the API message */
19308   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19309   mp->sw_if_index = ntohl (sw_if_index);
19310   mp->is_add = is_add;
19311   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19312
19313   S (mp);
19314   W (ret);
19315   return ret;
19316 }
19317
19318 static void vl_api_l2_xconnect_details_t_handler
19319   (vl_api_l2_xconnect_details_t * mp)
19320 {
19321   vat_main_t *vam = &vat_main;
19322
19323   print (vam->ofp, "%15d%15d",
19324          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19325 }
19326
19327 static void vl_api_l2_xconnect_details_t_handler_json
19328   (vl_api_l2_xconnect_details_t * mp)
19329 {
19330   vat_main_t *vam = &vat_main;
19331   vat_json_node_t *node = NULL;
19332
19333   if (VAT_JSON_ARRAY != vam->json_tree.type)
19334     {
19335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19336       vat_json_init_array (&vam->json_tree);
19337     }
19338   node = vat_json_array_add (&vam->json_tree);
19339
19340   vat_json_init_object (node);
19341   vat_json_object_add_uint (node, "rx_sw_if_index",
19342                             ntohl (mp->rx_sw_if_index));
19343   vat_json_object_add_uint (node, "tx_sw_if_index",
19344                             ntohl (mp->tx_sw_if_index));
19345 }
19346
19347 static int
19348 api_l2_xconnect_dump (vat_main_t * vam)
19349 {
19350   vl_api_l2_xconnect_dump_t *mp;
19351   vl_api_control_ping_t *mp_ping;
19352   int ret;
19353
19354   if (!vam->json_output)
19355     {
19356       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19357     }
19358
19359   M (L2_XCONNECT_DUMP, mp);
19360
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static int
19372 api_hw_interface_set_mtu (vat_main_t * vam)
19373 {
19374   unformat_input_t *i = vam->input;
19375   vl_api_hw_interface_set_mtu_t *mp;
19376   u32 sw_if_index = ~0;
19377   u32 mtu = 0;
19378   int ret;
19379
19380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19381     {
19382       if (unformat (i, "mtu %d", &mtu))
19383         ;
19384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19385         ;
19386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19387         ;
19388       else
19389         break;
19390     }
19391
19392   if (sw_if_index == ~0)
19393     {
19394       errmsg ("missing interface name or sw_if_index");
19395       return -99;
19396     }
19397
19398   if (mtu == 0)
19399     {
19400       errmsg ("no mtu specified");
19401       return -99;
19402     }
19403
19404   /* Construct the API message */
19405   M (HW_INTERFACE_SET_MTU, mp);
19406   mp->sw_if_index = ntohl (sw_if_index);
19407   mp->mtu = ntohs ((u16) mtu);
19408
19409   S (mp);
19410   W (ret);
19411   return ret;
19412 }
19413
19414 static int
19415 api_p2p_ethernet_add (vat_main_t * vam)
19416 {
19417   unformat_input_t *i = vam->input;
19418   vl_api_p2p_ethernet_add_t *mp;
19419   u32 parent_if_index = ~0;
19420   u32 sub_id = ~0;
19421   u8 remote_mac[6];
19422   u8 mac_set = 0;
19423   int ret;
19424
19425   clib_memset (remote_mac, 0, sizeof (remote_mac));
19426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19429         ;
19430       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19431         ;
19432       else
19433         if (unformat
19434             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19435         mac_set++;
19436       else if (unformat (i, "sub_id %d", &sub_id))
19437         ;
19438       else
19439         {
19440           clib_warning ("parse error '%U'", format_unformat_error, i);
19441           return -99;
19442         }
19443     }
19444
19445   if (parent_if_index == ~0)
19446     {
19447       errmsg ("missing interface name or sw_if_index");
19448       return -99;
19449     }
19450   if (mac_set == 0)
19451     {
19452       errmsg ("missing remote mac address");
19453       return -99;
19454     }
19455   if (sub_id == ~0)
19456     {
19457       errmsg ("missing sub-interface id");
19458       return -99;
19459     }
19460
19461   M (P2P_ETHERNET_ADD, mp);
19462   mp->parent_if_index = ntohl (parent_if_index);
19463   mp->subif_id = ntohl (sub_id);
19464   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19465
19466   S (mp);
19467   W (ret);
19468   return ret;
19469 }
19470
19471 static int
19472 api_p2p_ethernet_del (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_p2p_ethernet_del_t *mp;
19476   u32 parent_if_index = ~0;
19477   u8 remote_mac[6];
19478   u8 mac_set = 0;
19479   int ret;
19480
19481   clib_memset (remote_mac, 0, sizeof (remote_mac));
19482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19483     {
19484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19485         ;
19486       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19487         ;
19488       else
19489         if (unformat
19490             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19491         mac_set++;
19492       else
19493         {
19494           clib_warning ("parse error '%U'", format_unformat_error, i);
19495           return -99;
19496         }
19497     }
19498
19499   if (parent_if_index == ~0)
19500     {
19501       errmsg ("missing interface name or sw_if_index");
19502       return -99;
19503     }
19504   if (mac_set == 0)
19505     {
19506       errmsg ("missing remote mac address");
19507       return -99;
19508     }
19509
19510   M (P2P_ETHERNET_DEL, mp);
19511   mp->parent_if_index = ntohl (parent_if_index);
19512   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19513
19514   S (mp);
19515   W (ret);
19516   return ret;
19517 }
19518
19519 static int
19520 api_lldp_config (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_lldp_config_t *mp;
19524   int tx_hold = 0;
19525   int tx_interval = 0;
19526   u8 *sys_name = NULL;
19527   int ret;
19528
19529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19530     {
19531       if (unformat (i, "system-name %s", &sys_name))
19532         ;
19533       else if (unformat (i, "tx-hold %d", &tx_hold))
19534         ;
19535       else if (unformat (i, "tx-interval %d", &tx_interval))
19536         ;
19537       else
19538         {
19539           clib_warning ("parse error '%U'", format_unformat_error, i);
19540           return -99;
19541         }
19542     }
19543
19544   vec_add1 (sys_name, 0);
19545
19546   M (LLDP_CONFIG, mp);
19547   mp->tx_hold = htonl (tx_hold);
19548   mp->tx_interval = htonl (tx_interval);
19549   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19550   vec_free (sys_name);
19551
19552   S (mp);
19553   W (ret);
19554   return ret;
19555 }
19556
19557 static int
19558 api_sw_interface_set_lldp (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_sw_interface_set_lldp_t *mp;
19562   u32 sw_if_index = ~0;
19563   u32 enable = 1;
19564   u8 *port_desc = NULL, *mgmt_oid = NULL;
19565   ip4_address_t ip4_addr;
19566   ip6_address_t ip6_addr;
19567   int ret;
19568
19569   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19570   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19571
19572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19573     {
19574       if (unformat (i, "disable"))
19575         enable = 0;
19576       else
19577         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19578         ;
19579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19580         ;
19581       else if (unformat (i, "port-desc %s", &port_desc))
19582         ;
19583       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19584         ;
19585       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19586         ;
19587       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19588         ;
19589       else
19590         break;
19591     }
19592
19593   if (sw_if_index == ~0)
19594     {
19595       errmsg ("missing interface name or sw_if_index");
19596       return -99;
19597     }
19598
19599   /* Construct the API message */
19600   vec_add1 (port_desc, 0);
19601   vec_add1 (mgmt_oid, 0);
19602   M (SW_INTERFACE_SET_LLDP, mp);
19603   mp->sw_if_index = ntohl (sw_if_index);
19604   mp->enable = enable;
19605   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19606   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19607   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19608   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19609   vec_free (port_desc);
19610   vec_free (mgmt_oid);
19611
19612   S (mp);
19613   W (ret);
19614   return ret;
19615 }
19616
19617 static int
19618 api_tcp_configure_src_addresses (vat_main_t * vam)
19619 {
19620   vl_api_tcp_configure_src_addresses_t *mp;
19621   unformat_input_t *i = vam->input;
19622   vl_api_address_t first, last;
19623   u8 range_set = 0;
19624   u32 vrf_id = 0;
19625   int ret;
19626
19627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19628     {
19629       if (unformat (i, "%U - %U",
19630                     unformat_vl_api_address, &first,
19631                     unformat_vl_api_address, &last))
19632         {
19633           if (range_set)
19634             {
19635               errmsg ("one range per message (range already set)");
19636               return -99;
19637             }
19638           range_set = 1;
19639         }
19640       else if (unformat (i, "vrf %d", &vrf_id))
19641         ;
19642       else
19643         break;
19644     }
19645
19646   if (range_set == 0)
19647     {
19648       errmsg ("address range not set");
19649       return -99;
19650     }
19651
19652   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19653
19654   mp->vrf_id = ntohl (vrf_id);
19655   clib_memcpy (&mp->first_address, &first, sizeof (first));
19656   clib_memcpy (&mp->last_address, &last, sizeof (last));
19657
19658   S (mp);
19659   W (ret);
19660   return ret;
19661 }
19662
19663 static void vl_api_app_namespace_add_del_reply_t_handler
19664   (vl_api_app_namespace_add_del_reply_t * mp)
19665 {
19666   vat_main_t *vam = &vat_main;
19667   i32 retval = ntohl (mp->retval);
19668   if (vam->async_mode)
19669     {
19670       vam->async_errors += (retval < 0);
19671     }
19672   else
19673     {
19674       vam->retval = retval;
19675       if (retval == 0)
19676         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19677       vam->result_ready = 1;
19678     }
19679 }
19680
19681 static void vl_api_app_namespace_add_del_reply_t_handler_json
19682   (vl_api_app_namespace_add_del_reply_t * mp)
19683 {
19684   vat_main_t *vam = &vat_main;
19685   vat_json_node_t node;
19686
19687   vat_json_init_object (&node);
19688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19689   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19690
19691   vat_json_print (vam->ofp, &node);
19692   vat_json_free (&node);
19693
19694   vam->retval = ntohl (mp->retval);
19695   vam->result_ready = 1;
19696 }
19697
19698 static int
19699 api_app_namespace_add_del (vat_main_t * vam)
19700 {
19701   vl_api_app_namespace_add_del_t *mp;
19702   unformat_input_t *i = vam->input;
19703   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19704   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19705   u64 secret;
19706   int ret;
19707
19708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19709     {
19710       if (unformat (i, "id %_%v%_", &ns_id))
19711         ;
19712       else if (unformat (i, "secret %lu", &secret))
19713         secret_set = 1;
19714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19715         sw_if_index_set = 1;
19716       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19717         ;
19718       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19719         ;
19720       else
19721         break;
19722     }
19723   if (!ns_id || !secret_set || !sw_if_index_set)
19724     {
19725       errmsg ("namespace id, secret and sw_if_index must be set");
19726       return -99;
19727     }
19728   if (vec_len (ns_id) > 64)
19729     {
19730       errmsg ("namespace id too long");
19731       return -99;
19732     }
19733   M (APP_NAMESPACE_ADD_DEL, mp);
19734
19735   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19736   mp->namespace_id_len = vec_len (ns_id);
19737   mp->secret = clib_host_to_net_u64 (secret);
19738   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19739   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19740   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19741   vec_free (ns_id);
19742   S (mp);
19743   W (ret);
19744   return ret;
19745 }
19746
19747 static int
19748 api_sock_init_shm (vat_main_t * vam)
19749 {
19750 #if VPP_API_TEST_BUILTIN == 0
19751   unformat_input_t *i = vam->input;
19752   vl_api_shm_elem_config_t *config = 0;
19753   u64 size = 64 << 20;
19754   int rv;
19755
19756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19757     {
19758       if (unformat (i, "size %U", unformat_memory_size, &size))
19759         ;
19760       else
19761         break;
19762     }
19763
19764   /*
19765    * Canned custom ring allocator config.
19766    * Should probably parse all of this
19767    */
19768   vec_validate (config, 6);
19769   config[0].type = VL_API_VLIB_RING;
19770   config[0].size = 256;
19771   config[0].count = 32;
19772
19773   config[1].type = VL_API_VLIB_RING;
19774   config[1].size = 1024;
19775   config[1].count = 16;
19776
19777   config[2].type = VL_API_VLIB_RING;
19778   config[2].size = 4096;
19779   config[2].count = 2;
19780
19781   config[3].type = VL_API_CLIENT_RING;
19782   config[3].size = 256;
19783   config[3].count = 32;
19784
19785   config[4].type = VL_API_CLIENT_RING;
19786   config[4].size = 1024;
19787   config[4].count = 16;
19788
19789   config[5].type = VL_API_CLIENT_RING;
19790   config[5].size = 4096;
19791   config[5].count = 2;
19792
19793   config[6].type = VL_API_QUEUE;
19794   config[6].count = 128;
19795   config[6].size = sizeof (uword);
19796
19797   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19798   if (!rv)
19799     vam->client_index_invalid = 1;
19800   return rv;
19801 #else
19802   return -99;
19803 #endif
19804 }
19805
19806 static void
19807 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19808 {
19809   vat_main_t *vam = &vat_main;
19810
19811   if (mp->is_ip4)
19812     {
19813       print (vam->ofp,
19814              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19815              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19816              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19817              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19818              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19819              clib_net_to_host_u32 (mp->action_index), mp->tag);
19820     }
19821   else
19822     {
19823       print (vam->ofp,
19824              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19825              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19826              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19827              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19828              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19829              clib_net_to_host_u32 (mp->action_index), mp->tag);
19830     }
19831 }
19832
19833 static void
19834 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19835                                              mp)
19836 {
19837   vat_main_t *vam = &vat_main;
19838   vat_json_node_t *node = NULL;
19839   struct in6_addr ip6;
19840   struct in_addr ip4;
19841
19842   if (VAT_JSON_ARRAY != vam->json_tree.type)
19843     {
19844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19845       vat_json_init_array (&vam->json_tree);
19846     }
19847   node = vat_json_array_add (&vam->json_tree);
19848   vat_json_init_object (node);
19849
19850   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19851   vat_json_object_add_uint (node, "appns_index",
19852                             clib_net_to_host_u32 (mp->appns_index));
19853   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19854   vat_json_object_add_uint (node, "scope", mp->scope);
19855   vat_json_object_add_uint (node, "action_index",
19856                             clib_net_to_host_u32 (mp->action_index));
19857   vat_json_object_add_uint (node, "lcl_port",
19858                             clib_net_to_host_u16 (mp->lcl_port));
19859   vat_json_object_add_uint (node, "rmt_port",
19860                             clib_net_to_host_u16 (mp->rmt_port));
19861   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19862   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19863   vat_json_object_add_string_copy (node, "tag", mp->tag);
19864   if (mp->is_ip4)
19865     {
19866       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19867       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19868       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19869       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19870     }
19871   else
19872     {
19873       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19874       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19875       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19876       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19877     }
19878 }
19879
19880 static int
19881 api_session_rule_add_del (vat_main_t * vam)
19882 {
19883   vl_api_session_rule_add_del_t *mp;
19884   unformat_input_t *i = vam->input;
19885   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19886   u32 appns_index = 0, scope = 0;
19887   ip4_address_t lcl_ip4, rmt_ip4;
19888   ip6_address_t lcl_ip6, rmt_ip6;
19889   u8 is_ip4 = 1, conn_set = 0;
19890   u8 is_add = 1, *tag = 0;
19891   int ret;
19892
19893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19894     {
19895       if (unformat (i, "del"))
19896         is_add = 0;
19897       else if (unformat (i, "add"))
19898         ;
19899       else if (unformat (i, "proto tcp"))
19900         proto = 0;
19901       else if (unformat (i, "proto udp"))
19902         proto = 1;
19903       else if (unformat (i, "appns %d", &appns_index))
19904         ;
19905       else if (unformat (i, "scope %d", &scope))
19906         ;
19907       else if (unformat (i, "tag %_%v%_", &tag))
19908         ;
19909       else
19910         if (unformat
19911             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19912              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19913              &rmt_port))
19914         {
19915           is_ip4 = 1;
19916           conn_set = 1;
19917         }
19918       else
19919         if (unformat
19920             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19921              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19922              &rmt_port))
19923         {
19924           is_ip4 = 0;
19925           conn_set = 1;
19926         }
19927       else if (unformat (i, "action %d", &action))
19928         ;
19929       else
19930         break;
19931     }
19932   if (proto == ~0 || !conn_set || action == ~0)
19933     {
19934       errmsg ("transport proto, connection and action must be set");
19935       return -99;
19936     }
19937
19938   if (scope > 3)
19939     {
19940       errmsg ("scope should be 0-3");
19941       return -99;
19942     }
19943
19944   M (SESSION_RULE_ADD_DEL, mp);
19945
19946   mp->is_ip4 = is_ip4;
19947   mp->transport_proto = proto;
19948   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19949   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19950   mp->lcl_plen = lcl_plen;
19951   mp->rmt_plen = rmt_plen;
19952   mp->action_index = clib_host_to_net_u32 (action);
19953   mp->appns_index = clib_host_to_net_u32 (appns_index);
19954   mp->scope = scope;
19955   mp->is_add = is_add;
19956   if (is_ip4)
19957     {
19958       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
19959       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
19960     }
19961   else
19962     {
19963       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
19964       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
19965     }
19966   if (tag)
19967     {
19968       clib_memcpy (mp->tag, tag, vec_len (tag));
19969       vec_free (tag);
19970     }
19971
19972   S (mp);
19973   W (ret);
19974   return ret;
19975 }
19976
19977 static int
19978 api_session_rules_dump (vat_main_t * vam)
19979 {
19980   vl_api_session_rules_dump_t *mp;
19981   vl_api_control_ping_t *mp_ping;
19982   int ret;
19983
19984   if (!vam->json_output)
19985     {
19986       print (vam->ofp, "%=20s", "Session Rules");
19987     }
19988
19989   M (SESSION_RULES_DUMP, mp);
19990   /* send it... */
19991   S (mp);
19992
19993   /* Use a control ping for synchronization */
19994   MPING (CONTROL_PING, mp_ping);
19995   S (mp_ping);
19996
19997   /* Wait for a reply... */
19998   W (ret);
19999   return ret;
20000 }
20001
20002 static int
20003 api_ip_container_proxy_add_del (vat_main_t * vam)
20004 {
20005   vl_api_ip_container_proxy_add_del_t *mp;
20006   unformat_input_t *i = vam->input;
20007   u32 sw_if_index = ~0;
20008   vl_api_prefix_t pfx = { };
20009   u8 is_add = 1;
20010   int ret;
20011
20012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20013     {
20014       if (unformat (i, "del"))
20015         is_add = 0;
20016       else if (unformat (i, "add"))
20017         ;
20018       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20019         ;
20020       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20021         ;
20022       else
20023         break;
20024     }
20025   if (sw_if_index == ~0 || pfx.len == 0)
20026     {
20027       errmsg ("address and sw_if_index must be set");
20028       return -99;
20029     }
20030
20031   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20032
20033   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20034   mp->is_add = is_add;
20035   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20036
20037   S (mp);
20038   W (ret);
20039   return ret;
20040 }
20041
20042 static int
20043 api_qos_record_enable_disable (vat_main_t * vam)
20044 {
20045   unformat_input_t *i = vam->input;
20046   vl_api_qos_record_enable_disable_t *mp;
20047   u32 sw_if_index, qs = 0xff;
20048   u8 sw_if_index_set = 0;
20049   u8 enable = 1;
20050   int ret;
20051
20052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20053     {
20054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20055         sw_if_index_set = 1;
20056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20057         sw_if_index_set = 1;
20058       else if (unformat (i, "%U", unformat_qos_source, &qs))
20059         ;
20060       else if (unformat (i, "disable"))
20061         enable = 0;
20062       else
20063         {
20064           clib_warning ("parse error '%U'", format_unformat_error, i);
20065           return -99;
20066         }
20067     }
20068
20069   if (sw_if_index_set == 0)
20070     {
20071       errmsg ("missing interface name or sw_if_index");
20072       return -99;
20073     }
20074   if (qs == 0xff)
20075     {
20076       errmsg ("input location must be specified");
20077       return -99;
20078     }
20079
20080   M (QOS_RECORD_ENABLE_DISABLE, mp);
20081
20082   mp->record.sw_if_index = ntohl (sw_if_index);
20083   mp->record.input_source = qs;
20084   mp->enable = enable;
20085
20086   S (mp);
20087   W (ret);
20088   return ret;
20089 }
20090
20091
20092 static int
20093 q_or_quit (vat_main_t * vam)
20094 {
20095 #if VPP_API_TEST_BUILTIN == 0
20096   longjmp (vam->jump_buf, 1);
20097 #endif
20098   return 0;                     /* not so much */
20099 }
20100
20101 static int
20102 q (vat_main_t * vam)
20103 {
20104   return q_or_quit (vam);
20105 }
20106
20107 static int
20108 quit (vat_main_t * vam)
20109 {
20110   return q_or_quit (vam);
20111 }
20112
20113 static int
20114 comment (vat_main_t * vam)
20115 {
20116   return 0;
20117 }
20118
20119 static int
20120 elog_save (vat_main_t * vam)
20121 {
20122 #if VPP_API_TEST_BUILTIN == 0
20123   elog_main_t *em = &vam->elog_main;
20124   unformat_input_t *i = vam->input;
20125   char *file, *chroot_file;
20126   clib_error_t *error;
20127
20128   if (!unformat (i, "%s", &file))
20129     {
20130       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20131       return 0;
20132     }
20133
20134   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20135   if (strstr (file, "..") || index (file, '/'))
20136     {
20137       errmsg ("illegal characters in filename '%s'", file);
20138       return 0;
20139     }
20140
20141   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20142
20143   vec_free (file);
20144
20145   errmsg ("Saving %wd of %wd events to %s",
20146           elog_n_events_in_buffer (em),
20147           elog_buffer_capacity (em), chroot_file);
20148
20149   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20150   vec_free (chroot_file);
20151
20152   if (error)
20153     clib_error_report (error);
20154 #else
20155   errmsg ("Use the vpp event loger...");
20156 #endif
20157
20158   return 0;
20159 }
20160
20161 static int
20162 elog_setup (vat_main_t * vam)
20163 {
20164 #if VPP_API_TEST_BUILTIN == 0
20165   elog_main_t *em = &vam->elog_main;
20166   unformat_input_t *i = vam->input;
20167   u32 nevents = 128 << 10;
20168
20169   (void) unformat (i, "nevents %d", &nevents);
20170
20171   elog_init (em, nevents);
20172   vl_api_set_elog_main (em);
20173   vl_api_set_elog_trace_api_messages (1);
20174   errmsg ("Event logger initialized with %u events", nevents);
20175 #else
20176   errmsg ("Use the vpp event loger...");
20177 #endif
20178   return 0;
20179 }
20180
20181 static int
20182 elog_enable (vat_main_t * vam)
20183 {
20184 #if VPP_API_TEST_BUILTIN == 0
20185   elog_main_t *em = &vam->elog_main;
20186
20187   elog_enable_disable (em, 1 /* enable */ );
20188   vl_api_set_elog_trace_api_messages (1);
20189   errmsg ("Event logger enabled...");
20190 #else
20191   errmsg ("Use the vpp event loger...");
20192 #endif
20193   return 0;
20194 }
20195
20196 static int
20197 elog_disable (vat_main_t * vam)
20198 {
20199 #if VPP_API_TEST_BUILTIN == 0
20200   elog_main_t *em = &vam->elog_main;
20201
20202   elog_enable_disable (em, 0 /* enable */ );
20203   vl_api_set_elog_trace_api_messages (1);
20204   errmsg ("Event logger disabled...");
20205 #else
20206   errmsg ("Use the vpp event loger...");
20207 #endif
20208   return 0;
20209 }
20210
20211 static int
20212 statseg (vat_main_t * vam)
20213 {
20214   ssvm_private_t *ssvmp = &vam->stat_segment;
20215   ssvm_shared_header_t *shared_header = ssvmp->sh;
20216   vlib_counter_t **counters;
20217   u64 thread0_index1_packets;
20218   u64 thread0_index1_bytes;
20219   f64 vector_rate, input_rate;
20220   uword *p;
20221
20222   uword *counter_vector_by_name;
20223   if (vam->stat_segment_lockp == 0)
20224     {
20225       errmsg ("Stat segment not mapped...");
20226       return -99;
20227     }
20228
20229   /* look up "/if/rx for sw_if_index 1 as a test */
20230
20231   clib_spinlock_lock (vam->stat_segment_lockp);
20232
20233   counter_vector_by_name = (uword *) shared_header->opaque[1];
20234
20235   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20236   if (p == 0)
20237     {
20238       clib_spinlock_unlock (vam->stat_segment_lockp);
20239       errmsg ("/if/tx not found?");
20240       return -99;
20241     }
20242
20243   /* Fish per-thread vector of combined counters from shared memory */
20244   counters = (vlib_counter_t **) p[0];
20245
20246   if (vec_len (counters[0]) < 2)
20247     {
20248       clib_spinlock_unlock (vam->stat_segment_lockp);
20249       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20250       return -99;
20251     }
20252
20253   /* Read thread 0 sw_if_index 1 counter */
20254   thread0_index1_packets = counters[0][1].packets;
20255   thread0_index1_bytes = counters[0][1].bytes;
20256
20257   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20258   if (p == 0)
20259     {
20260       clib_spinlock_unlock (vam->stat_segment_lockp);
20261       errmsg ("vector_rate not found?");
20262       return -99;
20263     }
20264
20265   vector_rate = *(f64 *) (p[0]);
20266   p = hash_get_mem (counter_vector_by_name, "input_rate");
20267   if (p == 0)
20268     {
20269       clib_spinlock_unlock (vam->stat_segment_lockp);
20270       errmsg ("input_rate not found?");
20271       return -99;
20272     }
20273   input_rate = *(f64 *) (p[0]);
20274
20275   clib_spinlock_unlock (vam->stat_segment_lockp);
20276
20277   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20278          vector_rate, input_rate);
20279   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20280          thread0_index1_packets, thread0_index1_bytes);
20281
20282   return 0;
20283 }
20284
20285 static int
20286 cmd_cmp (void *a1, void *a2)
20287 {
20288   u8 **c1 = a1;
20289   u8 **c2 = a2;
20290
20291   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20292 }
20293
20294 static int
20295 help (vat_main_t * vam)
20296 {
20297   u8 **cmds = 0;
20298   u8 *name = 0;
20299   hash_pair_t *p;
20300   unformat_input_t *i = vam->input;
20301   int j;
20302
20303   if (unformat (i, "%s", &name))
20304     {
20305       uword *hs;
20306
20307       vec_add1 (name, 0);
20308
20309       hs = hash_get_mem (vam->help_by_name, name);
20310       if (hs)
20311         print (vam->ofp, "usage: %s %s", name, hs[0]);
20312       else
20313         print (vam->ofp, "No such msg / command '%s'", name);
20314       vec_free (name);
20315       return 0;
20316     }
20317
20318   print (vam->ofp, "Help is available for the following:");
20319
20320     /* *INDENT-OFF* */
20321     hash_foreach_pair (p, vam->function_by_name,
20322     ({
20323       vec_add1 (cmds, (u8 *)(p->key));
20324     }));
20325     /* *INDENT-ON* */
20326
20327   vec_sort_with_function (cmds, cmd_cmp);
20328
20329   for (j = 0; j < vec_len (cmds); j++)
20330     print (vam->ofp, "%s", cmds[j]);
20331
20332   vec_free (cmds);
20333   return 0;
20334 }
20335
20336 static int
20337 set (vat_main_t * vam)
20338 {
20339   u8 *name = 0, *value = 0;
20340   unformat_input_t *i = vam->input;
20341
20342   if (unformat (i, "%s", &name))
20343     {
20344       /* The input buffer is a vector, not a string. */
20345       value = vec_dup (i->buffer);
20346       vec_delete (value, i->index, 0);
20347       /* Almost certainly has a trailing newline */
20348       if (value[vec_len (value) - 1] == '\n')
20349         value[vec_len (value) - 1] = 0;
20350       /* Make sure it's a proper string, one way or the other */
20351       vec_add1 (value, 0);
20352       (void) clib_macro_set_value (&vam->macro_main,
20353                                    (char *) name, (char *) value);
20354     }
20355   else
20356     errmsg ("usage: set <name> <value>");
20357
20358   vec_free (name);
20359   vec_free (value);
20360   return 0;
20361 }
20362
20363 static int
20364 unset (vat_main_t * vam)
20365 {
20366   u8 *name = 0;
20367
20368   if (unformat (vam->input, "%s", &name))
20369     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20370       errmsg ("unset: %s wasn't set", name);
20371   vec_free (name);
20372   return 0;
20373 }
20374
20375 typedef struct
20376 {
20377   u8 *name;
20378   u8 *value;
20379 } macro_sort_t;
20380
20381
20382 static int
20383 macro_sort_cmp (void *a1, void *a2)
20384 {
20385   macro_sort_t *s1 = a1;
20386   macro_sort_t *s2 = a2;
20387
20388   return strcmp ((char *) (s1->name), (char *) (s2->name));
20389 }
20390
20391 static int
20392 dump_macro_table (vat_main_t * vam)
20393 {
20394   macro_sort_t *sort_me = 0, *sm;
20395   int i;
20396   hash_pair_t *p;
20397
20398     /* *INDENT-OFF* */
20399     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20400     ({
20401       vec_add2 (sort_me, sm, 1);
20402       sm->name = (u8 *)(p->key);
20403       sm->value = (u8 *) (p->value[0]);
20404     }));
20405     /* *INDENT-ON* */
20406
20407   vec_sort_with_function (sort_me, macro_sort_cmp);
20408
20409   if (vec_len (sort_me))
20410     print (vam->ofp, "%-15s%s", "Name", "Value");
20411   else
20412     print (vam->ofp, "The macro table is empty...");
20413
20414   for (i = 0; i < vec_len (sort_me); i++)
20415     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20416   return 0;
20417 }
20418
20419 static int
20420 dump_node_table (vat_main_t * vam)
20421 {
20422   int i, j;
20423   vlib_node_t *node, *next_node;
20424
20425   if (vec_len (vam->graph_nodes) == 0)
20426     {
20427       print (vam->ofp, "Node table empty, issue get_node_graph...");
20428       return 0;
20429     }
20430
20431   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20432     {
20433       node = vam->graph_nodes[0][i];
20434       print (vam->ofp, "[%d] %s", i, node->name);
20435       for (j = 0; j < vec_len (node->next_nodes); j++)
20436         {
20437           if (node->next_nodes[j] != ~0)
20438             {
20439               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20440               print (vam->ofp, "  [%d] %s", j, next_node->name);
20441             }
20442         }
20443     }
20444   return 0;
20445 }
20446
20447 static int
20448 value_sort_cmp (void *a1, void *a2)
20449 {
20450   name_sort_t *n1 = a1;
20451   name_sort_t *n2 = a2;
20452
20453   if (n1->value < n2->value)
20454     return -1;
20455   if (n1->value > n2->value)
20456     return 1;
20457   return 0;
20458 }
20459
20460
20461 static int
20462 dump_msg_api_table (vat_main_t * vam)
20463 {
20464   api_main_t *am = vlibapi_get_main ();
20465   name_sort_t *nses = 0, *ns;
20466   hash_pair_t *hp;
20467   int i;
20468
20469   /* *INDENT-OFF* */
20470   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20471   ({
20472     vec_add2 (nses, ns, 1);
20473     ns->name = (u8 *)(hp->key);
20474     ns->value = (u32) hp->value[0];
20475   }));
20476   /* *INDENT-ON* */
20477
20478   vec_sort_with_function (nses, value_sort_cmp);
20479
20480   for (i = 0; i < vec_len (nses); i++)
20481     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20482   vec_free (nses);
20483   return 0;
20484 }
20485
20486 static int
20487 get_msg_id (vat_main_t * vam)
20488 {
20489   u8 *name_and_crc;
20490   u32 message_index;
20491
20492   if (unformat (vam->input, "%s", &name_and_crc))
20493     {
20494       message_index = vl_msg_api_get_msg_index (name_and_crc);
20495       if (message_index == ~0)
20496         {
20497           print (vam->ofp, " '%s' not found", name_and_crc);
20498           return 0;
20499         }
20500       print (vam->ofp, " '%s' has message index %d",
20501              name_and_crc, message_index);
20502       return 0;
20503     }
20504   errmsg ("name_and_crc required...");
20505   return 0;
20506 }
20507
20508 static int
20509 search_node_table (vat_main_t * vam)
20510 {
20511   unformat_input_t *line_input = vam->input;
20512   u8 *node_to_find;
20513   int j;
20514   vlib_node_t *node, *next_node;
20515   uword *p;
20516
20517   if (vam->graph_node_index_by_name == 0)
20518     {
20519       print (vam->ofp, "Node table empty, issue get_node_graph...");
20520       return 0;
20521     }
20522
20523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20524     {
20525       if (unformat (line_input, "%s", &node_to_find))
20526         {
20527           vec_add1 (node_to_find, 0);
20528           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20529           if (p == 0)
20530             {
20531               print (vam->ofp, "%s not found...", node_to_find);
20532               goto out;
20533             }
20534           node = vam->graph_nodes[0][p[0]];
20535           print (vam->ofp, "[%d] %s", p[0], node->name);
20536           for (j = 0; j < vec_len (node->next_nodes); j++)
20537             {
20538               if (node->next_nodes[j] != ~0)
20539                 {
20540                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20541                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20542                 }
20543             }
20544         }
20545
20546       else
20547         {
20548           clib_warning ("parse error '%U'", format_unformat_error,
20549                         line_input);
20550           return -99;
20551         }
20552
20553     out:
20554       vec_free (node_to_find);
20555
20556     }
20557
20558   return 0;
20559 }
20560
20561
20562 static int
20563 script (vat_main_t * vam)
20564 {
20565 #if (VPP_API_TEST_BUILTIN==0)
20566   u8 *s = 0;
20567   char *save_current_file;
20568   unformat_input_t save_input;
20569   jmp_buf save_jump_buf;
20570   u32 save_line_number;
20571
20572   FILE *new_fp, *save_ifp;
20573
20574   if (unformat (vam->input, "%s", &s))
20575     {
20576       new_fp = fopen ((char *) s, "r");
20577       if (new_fp == 0)
20578         {
20579           errmsg ("Couldn't open script file %s", s);
20580           vec_free (s);
20581           return -99;
20582         }
20583     }
20584   else
20585     {
20586       errmsg ("Missing script name");
20587       return -99;
20588     }
20589
20590   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20591   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20592   save_ifp = vam->ifp;
20593   save_line_number = vam->input_line_number;
20594   save_current_file = (char *) vam->current_file;
20595
20596   vam->input_line_number = 0;
20597   vam->ifp = new_fp;
20598   vam->current_file = s;
20599   do_one_file (vam);
20600
20601   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20602   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20603   vam->ifp = save_ifp;
20604   vam->input_line_number = save_line_number;
20605   vam->current_file = (u8 *) save_current_file;
20606   vec_free (s);
20607
20608   return 0;
20609 #else
20610   clib_warning ("use the exec command...");
20611   return -99;
20612 #endif
20613 }
20614
20615 static int
20616 echo (vat_main_t * vam)
20617 {
20618   print (vam->ofp, "%v", vam->input->buffer);
20619   return 0;
20620 }
20621
20622 /* List of API message constructors, CLI names map to api_xxx */
20623 #define foreach_vpe_api_msg                                             \
20624 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20625 _(sw_interface_dump,"")                                                 \
20626 _(sw_interface_set_flags,                                               \
20627   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20628 _(sw_interface_add_del_address,                                         \
20629   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20630 _(sw_interface_set_rx_mode,                                             \
20631   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20632 _(sw_interface_set_rx_placement,                                        \
20633   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20634 _(sw_interface_rx_placement_dump,                                       \
20635   "[<intfc> | sw_if_index <id>]")                                         \
20636 _(sw_interface_set_table,                                               \
20637   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20638 _(sw_interface_set_mpls_enable,                                         \
20639   "<intfc> | sw_if_index [disable | dis]")                              \
20640 _(sw_interface_set_vpath,                                               \
20641   "<intfc> | sw_if_index <id> enable | disable")                        \
20642 _(sw_interface_set_vxlan_bypass,                                        \
20643   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20644 _(sw_interface_set_geneve_bypass,                                       \
20645   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20646 _(sw_interface_set_l2_xconnect,                                         \
20647   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20648   "enable | disable")                                                   \
20649 _(sw_interface_set_l2_bridge,                                           \
20650   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20651   "[shg <split-horizon-group>] [bvi]\n"                                 \
20652   "enable | disable")                                                   \
20653 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20654 _(bridge_domain_add_del,                                                \
20655   "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") \
20656 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20657 _(l2fib_add_del,                                                        \
20658   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20659 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20660 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20661 _(l2_flags,                                                             \
20662   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20663 _(bridge_flags,                                                         \
20664   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20665 _(tap_create_v2,                                                        \
20666   "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]") \
20667 _(tap_delete_v2,                                                        \
20668   "<vpp-if-name> | sw_if_index <id>")                                   \
20669 _(sw_interface_tap_v2_dump, "")                                         \
20670 _(virtio_pci_create,                                                    \
20671   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20672 _(virtio_pci_delete,                                                    \
20673   "<vpp-if-name> | sw_if_index <id>")                                   \
20674 _(sw_interface_virtio_pci_dump, "")                                     \
20675 _(bond_create,                                                          \
20676   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20677   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20678   "[id <if-id>]")                                                       \
20679 _(bond_delete,                                                          \
20680   "<vpp-if-name> | sw_if_index <id>")                                   \
20681 _(bond_enslave,                                                         \
20682   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20683 _(bond_detach_slave,                                                    \
20684   "sw_if_index <n>")                                                    \
20685  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20686 _(sw_interface_bond_dump, "")                                           \
20687 _(sw_interface_slave_dump,                                              \
20688   "<vpp-if-name> | sw_if_index <id>")                                   \
20689 _(ip_table_add_del,                                                     \
20690   "table <n> [ipv6] [add | del]\n")                                     \
20691 _(ip_route_add_del,                                                     \
20692   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20693   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20694   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20695   "[multipath] [count <n>] [del]")                                      \
20696 _(ip_mroute_add_del,                                                    \
20697   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20698   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20699 _(mpls_table_add_del,                                                   \
20700   "table <n> [add | del]\n")                                            \
20701 _(mpls_route_add_del,                                                   \
20702   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20703   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20704   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20705   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20706   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20707   "[count <n>] [del]")                                                  \
20708 _(mpls_ip_bind_unbind,                                                  \
20709   "<label> <addr/len>")                                                 \
20710 _(mpls_tunnel_add_del,                                                  \
20711   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20712   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20713   "[l2-only]  [out-label <n>]")                                         \
20714 _(sr_mpls_policy_add,                                                   \
20715   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20716 _(sr_mpls_policy_del,                                                   \
20717   "bsid <id>")                                                          \
20718 _(bier_table_add_del,                                                   \
20719   "<label> <sub-domain> <set> <bsl> [del]")                             \
20720 _(bier_route_add_del,                                                   \
20721   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20722   "[<intfc> | sw_if_index <id>]"                                        \
20723   "[weight <n>] [del] [multipath]")                                     \
20724 _(sw_interface_set_unnumbered,                                          \
20725   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20726 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20727 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20728   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20729   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20730   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20731 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20732 _(ip_table_flush, "table <n> [ipv6]")                                   \
20733 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20734 _(set_ip_flow_hash,                                                     \
20735   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20736 _(sw_interface_ip6_enable_disable,                                      \
20737   "<intfc> | sw_if_index <id> enable | disable")                        \
20738 _(l2_patch_add_del,                                                     \
20739   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20740   "enable | disable")                                                   \
20741 _(sr_localsid_add_del,                                                  \
20742   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20743   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20744 _(classify_add_del_table,                                               \
20745   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20746   " [del] [del-chain] mask <mask-value>\n"                              \
20747   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20748   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20749 _(classify_add_del_session,                                             \
20750   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20751   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20752   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20753   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20754 _(classify_set_interface_ip_table,                                      \
20755   "<intfc> | sw_if_index <nn> table <nn>")                              \
20756 _(classify_set_interface_l2_tables,                                     \
20757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20758   "  [other-table <nn>]")                                               \
20759 _(get_node_index, "node <node-name")                                    \
20760 _(add_node_next, "node <node-name> next <next-node-name>")              \
20761 _(l2tpv3_create_tunnel,                                                 \
20762   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20763   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20764   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20765 _(l2tpv3_set_tunnel_cookies,                                            \
20766   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20767   "[new_remote_cookie <nn>]\n")                                         \
20768 _(l2tpv3_interface_enable_disable,                                      \
20769   "<intfc> | sw_if_index <nn> enable | disable")                        \
20770 _(l2tpv3_set_lookup_key,                                                \
20771   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20772 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20773 _(vxlan_offload_rx,                                                     \
20774   "hw { <interface name> | hw_if_index <nn>} "                          \
20775   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20776 _(vxlan_add_del_tunnel,                                                 \
20777   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20778   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20779   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20780 _(geneve_add_del_tunnel,                                                \
20781   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20782   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20783   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20784 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20785 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20786 _(gre_tunnel_add_del,                                                   \
20787   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20788   "[teb | erspan <session-id>] [del]")                                  \
20789 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20790 _(l2_fib_clear_table, "")                                               \
20791 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20792 _(l2_interface_vlan_tag_rewrite,                                        \
20793   "<intfc> | sw_if_index <nn> \n"                                       \
20794   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20795   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20796 _(create_vhost_user_if,                                                 \
20797         "socket <filename> [server] [renumber <dev_instance>] "         \
20798         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20799         "[mac <mac_address>]")                                          \
20800 _(modify_vhost_user_if,                                                 \
20801         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20802         "[server] [renumber <dev_instance>] [gso]")                     \
20803 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20804 _(sw_interface_vhost_user_dump, "")                                     \
20805 _(show_version, "")                                                     \
20806 _(show_threads, "")                                                     \
20807 _(vxlan_gpe_add_del_tunnel,                                             \
20808   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20809   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20810   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20811   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20812 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20813 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20814 _(interface_name_renumber,                                              \
20815   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20816 _(input_acl_set_interface,                                              \
20817   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20818   "  [l2-table <nn>] [del]")                                            \
20819 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20820 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20821 _(ip_dump, "ipv4 | ipv6")                                               \
20822 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20823 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20824   "  spid_id <n> ")                                                     \
20825 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20826   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20827   "  integ_alg <alg> integ_key <hex>")                                  \
20828 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20829   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20830   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20831   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20832 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20833   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20834   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20835   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20836   "  [instance <n>]")     \
20837 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20838 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20839 _(delete_loopback,"sw_if_index <nn>")                                   \
20840 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20841 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20842 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20843 _(want_interface_events,  "enable|disable")                             \
20844 _(get_first_msg_id, "client <name>")                                    \
20845 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20846 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20847   "fib-id <nn> [ip4][ip6][default]")                                    \
20848 _(get_node_graph, " ")                                                  \
20849 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20850 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20851 _(ioam_disable, "")                                                     \
20852 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20853                             " sw_if_index <sw_if_index> p <priority> "  \
20854                             "w <weight>] [del]")                        \
20855 _(one_add_del_locator, "locator-set <locator_name> "                    \
20856                         "iface <intf> | sw_if_index <sw_if_index> "     \
20857                         "p <priority> w <weight> [del]")                \
20858 _(one_add_del_local_eid,"vni <vni> eid "                                \
20859                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20860                          "locator-set <locator_name> [del]"             \
20861                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20862 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20863 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20864 _(one_enable_disable, "enable|disable")                                 \
20865 _(one_map_register_enable_disable, "enable|disable")                    \
20866 _(one_map_register_fallback_threshold, "<value>")                       \
20867 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20868 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20869                                "[seid <seid>] "                         \
20870                                "rloc <locator> p <prio> "               \
20871                                "w <weight> [rloc <loc> ... ] "          \
20872                                "action <action> [del-all]")             \
20873 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20874                           "<local-eid>")                                \
20875 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20876 _(one_use_petr, "ip-address> | disable")                                \
20877 _(one_map_request_mode, "src-dst|dst-only")                             \
20878 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20879 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20880 _(one_locator_set_dump, "[local | remote]")                             \
20881 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20882 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20883                        "[local] | [remote]")                            \
20884 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20885 _(one_ndp_bd_get, "")                                                   \
20886 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20887 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20888 _(one_l2_arp_bd_get, "")                                                \
20889 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20890 _(one_stats_enable_disable, "enable|disable")                           \
20891 _(show_one_stats_enable_disable, "")                                    \
20892 _(one_eid_table_vni_dump, "")                                           \
20893 _(one_eid_table_map_dump, "l2|l3")                                      \
20894 _(one_map_resolver_dump, "")                                            \
20895 _(one_map_server_dump, "")                                              \
20896 _(one_adjacencies_get, "vni <vni>")                                     \
20897 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20898 _(show_one_rloc_probe_state, "")                                        \
20899 _(show_one_map_register_state, "")                                      \
20900 _(show_one_status, "")                                                  \
20901 _(one_stats_dump, "")                                                   \
20902 _(one_stats_flush, "")                                                  \
20903 _(one_get_map_request_itr_rlocs, "")                                    \
20904 _(one_map_register_set_ttl, "<ttl>")                                    \
20905 _(one_set_transport_protocol, "udp|api")                                \
20906 _(one_get_transport_protocol, "")                                       \
20907 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20908 _(one_show_xtr_mode, "")                                                \
20909 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20910 _(one_show_pitr_mode, "")                                               \
20911 _(one_enable_disable_petr_mode, "enable|disable")                       \
20912 _(one_show_petr_mode, "")                                               \
20913 _(show_one_nsh_mapping, "")                                             \
20914 _(show_one_pitr, "")                                                    \
20915 _(show_one_use_petr, "")                                                \
20916 _(show_one_map_request_mode, "")                                        \
20917 _(show_one_map_register_ttl, "")                                        \
20918 _(show_one_map_register_fallback_threshold, "")                         \
20919 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20920                             " sw_if_index <sw_if_index> p <priority> "  \
20921                             "w <weight>] [del]")                        \
20922 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20923                         "iface <intf> | sw_if_index <sw_if_index> "     \
20924                         "p <priority> w <weight> [del]")                \
20925 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20926                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20927                          "locator-set <locator_name> [del]"             \
20928                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20929 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20930 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20931 _(lisp_enable_disable, "enable|disable")                                \
20932 _(lisp_map_register_enable_disable, "enable|disable")                   \
20933 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20934 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20935                                "[seid <seid>] "                         \
20936                                "rloc <locator> p <prio> "               \
20937                                "w <weight> [rloc <loc> ... ] "          \
20938                                "action <action> [del-all]")             \
20939 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20940                           "<local-eid>")                                \
20941 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20942 _(lisp_use_petr, "<ip-address> | disable")                              \
20943 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20944 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20945 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20946 _(lisp_locator_set_dump, "[local | remote]")                            \
20947 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20948 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20949                        "[local] | [remote]")                            \
20950 _(lisp_eid_table_vni_dump, "")                                          \
20951 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20952 _(lisp_map_resolver_dump, "")                                           \
20953 _(lisp_map_server_dump, "")                                             \
20954 _(lisp_adjacencies_get, "vni <vni>")                                    \
20955 _(gpe_fwd_entry_vnis_get, "")                                           \
20956 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20957 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20958                                 "[table <table-id>]")                   \
20959 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20960 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20961 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20962 _(gpe_get_encap_mode, "")                                               \
20963 _(lisp_gpe_add_del_iface, "up|down")                                    \
20964 _(lisp_gpe_enable_disable, "enable|disable")                            \
20965 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20966   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20967 _(show_lisp_rloc_probe_state, "")                                       \
20968 _(show_lisp_map_register_state, "")                                     \
20969 _(show_lisp_status, "")                                                 \
20970 _(lisp_get_map_request_itr_rlocs, "")                                   \
20971 _(show_lisp_pitr, "")                                                   \
20972 _(show_lisp_use_petr, "")                                               \
20973 _(show_lisp_map_request_mode, "")                                       \
20974 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20975 _(af_packet_delete, "name <host interface name>")                       \
20976 _(af_packet_dump, "")                                                   \
20977 _(policer_add_del, "name <policer name> <params> [del]")                \
20978 _(policer_dump, "[name <policer name>]")                                \
20979 _(policer_classify_set_interface,                                       \
20980   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20981   "  [l2-table <nn>] [del]")                                            \
20982 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20983 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20984 _(mpls_table_dump, "")                                                  \
20985 _(mpls_route_dump, "table-id <ID>")                                     \
20986 _(classify_table_ids, "")                                               \
20987 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20988 _(classify_table_info, "table_id <nn>")                                 \
20989 _(classify_session_dump, "table_id <nn>")                               \
20990 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20991     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20992     "[template_interval <nn>] [udp_checksum]")                          \
20993 _(ipfix_exporter_dump, "")                                              \
20994 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20995 _(ipfix_classify_stream_dump, "")                                       \
20996 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20997 _(ipfix_classify_table_dump, "")                                        \
20998 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20999 _(sw_interface_span_dump, "[l2]")                                           \
21000 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21001 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21002 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21003 _(pg_enable_disable, "[stream <id>] disable")                           \
21004 _(ip_source_and_port_range_check_add_del,                               \
21005   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21006 _(ip_source_and_port_range_check_interface_add_del,                     \
21007   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21008   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21009 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21010 _(l2_interface_pbb_tag_rewrite,                                         \
21011   "<intfc> | sw_if_index <nn> \n"                                       \
21012   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21013   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21014 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21015 _(flow_classify_set_interface,                                          \
21016   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21017 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21018 _(ip_table_dump, "")                                                    \
21019 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21020 _(ip_mtable_dump, "")                                                   \
21021 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21022 _(feature_enable_disable, "arc_name <arc_name> "                        \
21023   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21024 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21025   "[enable | disable] ")                                                \
21026 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21027 "[disable]")                                                            \
21028 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21029   "mac <mac-address> [del]")                                            \
21030 _(l2_xconnect_dump, "")                                                 \
21031 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21032 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21033 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21034 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21035 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21036 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21037   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21038 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21039 _(sock_init_shm, "size <nnn>")                                          \
21040 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21041 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21042   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21043 _(session_rules_dump, "")                                               \
21044 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21045 _(output_acl_set_interface,                                             \
21046   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21047   "  [l2-table <nn>] [del]")                                            \
21048 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21049
21050 /* List of command functions, CLI names map directly to functions */
21051 #define foreach_cli_function                                    \
21052 _(comment, "usage: comment <ignore-rest-of-line>")              \
21053 _(dump_interface_table, "usage: dump_interface_table")          \
21054 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21055 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21056 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21057 _(dump_macro_table, "usage: dump_macro_table ")                 \
21058 _(dump_node_table, "usage: dump_node_table")                    \
21059 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21060 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21061 _(elog_disable, "usage: elog_disable")                          \
21062 _(elog_enable, "usage: elog_enable")                            \
21063 _(elog_save, "usage: elog_save <filename>")                     \
21064 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21065 _(echo, "usage: echo <message>")                                \
21066 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21067 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21068 _(help, "usage: help")                                          \
21069 _(q, "usage: quit")                                             \
21070 _(quit, "usage: quit")                                          \
21071 _(search_node_table, "usage: search_node_table <name>...")      \
21072 _(set, "usage: set <variable-name> <value>")                    \
21073 _(script, "usage: script <file-name>")                          \
21074 _(statseg, "usage: statseg")                                    \
21075 _(unset, "usage: unset <variable-name>")
21076
21077 #define _(N,n)                                  \
21078     static void vl_api_##n##_t_handler_uni      \
21079     (vl_api_##n##_t * mp)                       \
21080     {                                           \
21081         vat_main_t * vam = &vat_main;           \
21082         if (vam->json_output) {                 \
21083             vl_api_##n##_t_handler_json(mp);    \
21084         } else {                                \
21085             vl_api_##n##_t_handler(mp);         \
21086         }                                       \
21087     }
21088 foreach_vpe_api_reply_msg;
21089 #if VPP_API_TEST_BUILTIN == 0
21090 foreach_standalone_reply_msg;
21091 #endif
21092 #undef _
21093
21094 void
21095 vat_api_hookup (vat_main_t * vam)
21096 {
21097 #define _(N,n)                                                  \
21098     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21099                            vl_api_##n##_t_handler_uni,          \
21100                            vl_noop_handler,                     \
21101                            vl_api_##n##_t_endian,               \
21102                            vl_api_##n##_t_print,                \
21103                            sizeof(vl_api_##n##_t), 1);
21104   foreach_vpe_api_reply_msg;
21105 #if VPP_API_TEST_BUILTIN == 0
21106   foreach_standalone_reply_msg;
21107 #endif
21108 #undef _
21109
21110 #if (VPP_API_TEST_BUILTIN==0)
21111   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21112
21113   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21114
21115   vam->function_by_name = hash_create_string (0, sizeof (uword));
21116
21117   vam->help_by_name = hash_create_string (0, sizeof (uword));
21118 #endif
21119
21120   /* API messages we can send */
21121 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21122   foreach_vpe_api_msg;
21123 #undef _
21124
21125   /* Help strings */
21126 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21127   foreach_vpe_api_msg;
21128 #undef _
21129
21130   /* CLI functions */
21131 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21132   foreach_cli_function;
21133 #undef _
21134
21135   /* Help strings */
21136 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21137   foreach_cli_function;
21138 #undef _
21139 }
21140
21141 #if VPP_API_TEST_BUILTIN
21142 static clib_error_t *
21143 vat_api_hookup_shim (vlib_main_t * vm)
21144 {
21145   vat_api_hookup (&vat_main);
21146   return 0;
21147 }
21148
21149 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21150 #endif
21151
21152 /*
21153  * fd.io coding-style-patch-verification: ON
21154  *
21155  * Local Variables:
21156  * eval: (c-set-style "gnu")
21157  * End:
21158  */