misc: Move l2tp to plugin
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 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/vxlan/vxlan.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <inttypes.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51 #include <vnet/bonding/node.h>
52 #include <vnet/qos/qos_types.h>
53 #include <vnet/ethernet/ethernet_types_api.h>
54 #include <vnet/ip/ip_types_api.h>
55 #include "vat/json_format.h"
56 #include <vnet/ip/ip_types_api.h>
57 #include <vnet/ethernet/ethernet_types_api.h>
58
59 #include <inttypes.h>
60 #include <sys/stat.h>
61
62 #define vl_typedefs             /* define message structures */
63 #include <vpp/api/vpe_all_api_h.h>
64 #undef vl_typedefs
65
66 /* declare message handlers for each api */
67
68 #define vl_endianfun            /* define message structures */
69 #include <vpp/api/vpe_all_api_h.h>
70 #undef vl_endianfun
71
72 /* instantiate all the print functions we know about */
73 #if VPP_API_TEST_BUILTIN == 0
74 #define vl_print(handle, ...)
75 #else
76 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
77 #endif
78 #define vl_printfun
79 #include <vpp/api/vpe_all_api_h.h>
80 #undef vl_printfun
81
82 #define __plugin_msg_base 0
83 #include <vlibapi/vat_helper_macros.h>
84
85 #include <vnet/format_fns.h>
86
87 void vl_api_set_elog_main (elog_main_t * m);
88 int vl_api_set_elog_trace_api_messages (int enable);
89
90 #if VPP_API_TEST_BUILTIN == 0
91 #include <netdb.h>
92
93 u32
94 vl (void *p)
95 {
96   return vec_len (p);
97 }
98
99 int
100 vat_socket_connect (vat_main_t * vam)
101 {
102   int rv;
103   api_main_t *am = vlibapi_get_main ();
104   vam->socket_client_main = &socket_client_main;
105   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
106                                       "vpp_api_test",
107                                       0 /* default socket rx, tx buffer */ )))
108     return rv;
109
110   /* vpp expects the client index in network order */
111   vam->my_client_index = htonl (socket_client_main.client_index);
112   am->my_client_index = vam->my_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 (a->af == ADDRESS_IP4)
767     increment_v4_address (&a->un.ip4);
768   else if (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, &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, &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_create_v2_reply_t_handler
1831   (vl_api_virtio_pci_create_v2_reply_t * 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->sw_if_index = ntohl (mp->sw_if_index);
1843       vam->result_ready = 1;
1844     }
1845 }
1846
1847 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1848   (vl_api_virtio_pci_create_v2_reply_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851   vat_json_node_t node;
1852
1853   vat_json_init_object (&node);
1854   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1855   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1856
1857   vat_json_print (vam->ofp, &node);
1858   vat_json_free (&node);
1859
1860   vam->retval = ntohl (mp->retval);
1861   vam->result_ready = 1;
1862 }
1863
1864 static void
1865 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1866                                           mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   i32 retval = ntohl (mp->retval);
1870   if (vam->async_mode)
1871     {
1872       vam->async_errors += (retval < 0);
1873     }
1874   else
1875     {
1876       vam->retval = retval;
1877       vam->result_ready = 1;
1878     }
1879 }
1880
1881 static void vl_api_virtio_pci_delete_reply_t_handler_json
1882   (vl_api_virtio_pci_delete_reply_t * mp)
1883 {
1884   vat_main_t *vam = &vat_main;
1885   vat_json_node_t node;
1886
1887   vat_json_init_object (&node);
1888   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_create_reply_t_handler (vl_api_bond_create_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->sw_if_index = ntohl (mp->sw_if_index);
1911       vam->result_ready = 1;
1912     }
1913 }
1914
1915 static void vl_api_bond_create_reply_t_handler_json
1916   (vl_api_bond_create_reply_t * mp)
1917 {
1918   vat_main_t *vam = &vat_main;
1919   vat_json_node_t node;
1920
1921   vat_json_init_object (&node);
1922   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1923   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1924
1925   vat_json_print (vam->ofp, &node);
1926   vat_json_free (&node);
1927
1928   vam->retval = ntohl (mp->retval);
1929   vam->result_ready = 1;
1930 }
1931
1932 static void
1933 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1934 {
1935   vat_main_t *vam = &vat_main;
1936   i32 retval = ntohl (mp->retval);
1937
1938   if (vam->async_mode)
1939     {
1940       vam->async_errors += (retval < 0);
1941     }
1942   else
1943     {
1944       vam->retval = retval;
1945       vam->sw_if_index = ntohl (mp->sw_if_index);
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_create2_reply_t_handler_json
1951   (vl_api_bond_create2_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static void
1968 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_delete_reply_t_handler_json
1985   (vl_api_bond_delete_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static void
2001 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
2002 {
2003   vat_main_t *vam = &vat_main;
2004   i32 retval = ntohl (mp->retval);
2005
2006   if (vam->async_mode)
2007     {
2008       vam->async_errors += (retval < 0);
2009     }
2010   else
2011     {
2012       vam->retval = retval;
2013       vam->result_ready = 1;
2014     }
2015 }
2016
2017 static void vl_api_bond_add_member_reply_t_handler_json
2018   (vl_api_bond_add_member_reply_t * mp)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   vat_json_node_t node;
2022
2023   vat_json_init_object (&node);
2024   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2025
2026   vat_json_print (vam->ofp, &node);
2027   vat_json_free (&node);
2028
2029   vam->retval = ntohl (mp->retval);
2030   vam->result_ready = 1;
2031 }
2032
2033 static void
2034 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2035                                            mp)
2036 {
2037   vat_main_t *vam = &vat_main;
2038   i32 retval = ntohl (mp->retval);
2039
2040   if (vam->async_mode)
2041     {
2042       vam->async_errors += (retval < 0);
2043     }
2044   else
2045     {
2046       vam->retval = retval;
2047       vam->result_ready = 1;
2048     }
2049 }
2050
2051 static void vl_api_bond_detach_member_reply_t_handler_json
2052   (vl_api_bond_detach_member_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   vat_json_node_t node;
2056
2057   vat_json_init_object (&node);
2058   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2059
2060   vat_json_print (vam->ofp, &node);
2061   vat_json_free (&node);
2062
2063   vam->retval = ntohl (mp->retval);
2064   vam->result_ready = 1;
2065 }
2066
2067 static int
2068 api_sw_interface_set_bond_weight (vat_main_t * vam)
2069 {
2070   unformat_input_t *i = vam->input;
2071   vl_api_sw_interface_set_bond_weight_t *mp;
2072   u32 sw_if_index = ~0;
2073   u32 weight = 0;
2074   u8 weight_enter = 0;
2075   int ret;
2076
2077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2078     {
2079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2080         ;
2081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2082         ;
2083       else if (unformat (i, "weight %u", &weight))
2084         weight_enter = 1;
2085       else
2086         break;
2087     }
2088
2089   if (sw_if_index == ~0)
2090     {
2091       errmsg ("missing interface name or sw_if_index");
2092       return -99;
2093     }
2094   if (weight_enter == 0)
2095     {
2096       errmsg ("missing valid weight");
2097       return -99;
2098     }
2099
2100   /* Construct the API message */
2101   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2102   mp->sw_if_index = ntohl (sw_if_index);
2103   mp->weight = ntohl (weight);
2104
2105   S (mp);
2106   W (ret);
2107   return ret;
2108 }
2109
2110 static void vl_api_sw_bond_interface_details_t_handler
2111   (vl_api_sw_bond_interface_details_t * mp)
2112 {
2113   vat_main_t *vam = &vat_main;
2114
2115   print (vam->ofp,
2116          "%-16s %-12d %-12U %-13U %-14u %-14u",
2117          mp->interface_name, ntohl (mp->sw_if_index),
2118          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2119          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2120 }
2121
2122 static void vl_api_sw_bond_interface_details_t_handler_json
2123   (vl_api_sw_bond_interface_details_t * mp)
2124 {
2125   vat_main_t *vam = &vat_main;
2126   vat_json_node_t *node = NULL;
2127
2128   if (VAT_JSON_ARRAY != vam->json_tree.type)
2129     {
2130       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2131       vat_json_init_array (&vam->json_tree);
2132     }
2133   node = vat_json_array_add (&vam->json_tree);
2134
2135   vat_json_init_object (node);
2136   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2137   vat_json_object_add_string_copy (node, "interface_name",
2138                                    mp->interface_name);
2139   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2140   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2141   vat_json_object_add_uint (node, "active_members",
2142                             ntohl (mp->active_members));
2143   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2144 }
2145
2146 static int
2147 api_sw_bond_interface_dump (vat_main_t * vam)
2148 {
2149   unformat_input_t *i = vam->input;
2150   vl_api_sw_bond_interface_dump_t *mp;
2151   vl_api_control_ping_t *mp_ping;
2152   int ret;
2153   u32 sw_if_index = ~0;
2154
2155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2156     {
2157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2158         ;
2159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2160         ;
2161       else
2162         break;
2163     }
2164
2165   print (vam->ofp,
2166          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2167          "interface name", "sw_if_index", "mode", "load balance",
2168          "active members", "members");
2169
2170   /* Get list of bond interfaces */
2171   M (SW_BOND_INTERFACE_DUMP, mp);
2172   mp->sw_if_index = ntohl (sw_if_index);
2173   S (mp);
2174
2175   /* Use a control ping for synchronization */
2176   MPING (CONTROL_PING, mp_ping);
2177   S (mp_ping);
2178
2179   W (ret);
2180   return ret;
2181 }
2182
2183 static void vl_api_sw_member_interface_details_t_handler
2184   (vl_api_sw_member_interface_details_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187
2188   print (vam->ofp,
2189          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2190          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2191          ntohl (mp->weight), mp->is_local_numa);
2192 }
2193
2194 static void vl_api_sw_member_interface_details_t_handler_json
2195   (vl_api_sw_member_interface_details_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   vat_json_node_t *node = NULL;
2199
2200   if (VAT_JSON_ARRAY != vam->json_tree.type)
2201     {
2202       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2203       vat_json_init_array (&vam->json_tree);
2204     }
2205   node = vat_json_array_add (&vam->json_tree);
2206
2207   vat_json_init_object (node);
2208   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2209   vat_json_object_add_string_copy (node, "interface_name",
2210                                    mp->interface_name);
2211   vat_json_object_add_uint (node, "passive", mp->is_passive);
2212   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2213   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2214   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2215 }
2216
2217 static int
2218 api_sw_member_interface_dump (vat_main_t * vam)
2219 {
2220   unformat_input_t *i = vam->input;
2221   vl_api_sw_member_interface_dump_t *mp;
2222   vl_api_control_ping_t *mp_ping;
2223   u32 sw_if_index = ~0;
2224   u8 sw_if_index_set = 0;
2225   int ret;
2226
2227   /* Parse args required to build the message */
2228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2229     {
2230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2231         sw_if_index_set = 1;
2232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2233         sw_if_index_set = 1;
2234       else
2235         break;
2236     }
2237
2238   if (sw_if_index_set == 0)
2239     {
2240       errmsg ("missing vpp interface name. ");
2241       return -99;
2242     }
2243
2244   print (vam->ofp,
2245          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2246          "member interface name", "sw_if_index", "passive", "long_timeout",
2247          "weight", "local numa");
2248
2249   /* Get list of bond interfaces */
2250   M (SW_MEMBER_INTERFACE_DUMP, mp);
2251   mp->sw_if_index = ntohl (sw_if_index);
2252   S (mp);
2253
2254   /* Use a control ping for synchronization */
2255   MPING (CONTROL_PING, mp_ping);
2256   S (mp_ping);
2257
2258   W (ret);
2259   return ret;
2260 }
2261
2262 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2263   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2264 {
2265   vat_main_t *vam = &vat_main;
2266   i32 retval = ntohl (mp->retval);
2267   if (vam->async_mode)
2268     {
2269       vam->async_errors += (retval < 0);
2270     }
2271   else
2272     {
2273       vam->retval = retval;
2274       vam->sw_if_index = ntohl (mp->sw_if_index);
2275       vam->result_ready = 1;
2276     }
2277   vam->regenerate_interface_table = 1;
2278 }
2279
2280 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2281   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2282 {
2283   vat_main_t *vam = &vat_main;
2284   vat_json_node_t node;
2285
2286   vat_json_init_object (&node);
2287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2289                             ntohl (mp->sw_if_index));
2290
2291   vat_json_print (vam->ofp, &node);
2292   vat_json_free (&node);
2293
2294   vam->retval = ntohl (mp->retval);
2295   vam->result_ready = 1;
2296 }
2297
2298 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2299   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2300 {
2301   vat_main_t *vam = &vat_main;
2302   i32 retval = ntohl (mp->retval);
2303   if (vam->async_mode)
2304     {
2305       vam->async_errors += (retval < 0);
2306     }
2307   else
2308     {
2309       vam->retval = retval;
2310       vam->result_ready = 1;
2311     }
2312 }
2313
2314 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2315   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   vat_json_node_t node;
2319
2320   vat_json_init_object (&node);
2321   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2322   vat_json_object_add_uint (&node, "fwd_entry_index",
2323                             clib_net_to_host_u32 (mp->fwd_entry_index));
2324
2325   vat_json_print (vam->ofp, &node);
2326   vat_json_free (&node);
2327
2328   vam->retval = ntohl (mp->retval);
2329   vam->result_ready = 1;
2330 }
2331
2332 u8 *
2333 format_lisp_transport_protocol (u8 * s, va_list * args)
2334 {
2335   u32 proto = va_arg (*args, u32);
2336
2337   switch (proto)
2338     {
2339     case 1:
2340       return format (s, "udp");
2341     case 2:
2342       return format (s, "api");
2343     default:
2344       return 0;
2345     }
2346   return 0;
2347 }
2348
2349 static void vl_api_one_get_transport_protocol_reply_t_handler
2350   (vl_api_one_get_transport_protocol_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   i32 retval = ntohl (mp->retval);
2354   if (vam->async_mode)
2355     {
2356       vam->async_errors += (retval < 0);
2357     }
2358   else
2359     {
2360       u32 proto = mp->protocol;
2361       print (vam->ofp, "Transport protocol: %U",
2362              format_lisp_transport_protocol, proto);
2363       vam->retval = retval;
2364       vam->result_ready = 1;
2365     }
2366 }
2367
2368 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2369   (vl_api_one_get_transport_protocol_reply_t * mp)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   vat_json_node_t node;
2373   u8 *s;
2374
2375   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2376   vec_add1 (s, 0);
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2381
2382   vec_free (s);
2383   vat_json_print (vam->ofp, &node);
2384   vat_json_free (&node);
2385
2386   vam->retval = ntohl (mp->retval);
2387   vam->result_ready = 1;
2388 }
2389
2390 static void vl_api_one_add_del_locator_set_reply_t_handler
2391   (vl_api_one_add_del_locator_set_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   i32 retval = ntohl (mp->retval);
2395   if (vam->async_mode)
2396     {
2397       vam->async_errors += (retval < 0);
2398     }
2399   else
2400     {
2401       vam->retval = retval;
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2407   (vl_api_one_add_del_locator_set_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2424   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2442   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_vxlan_offload_rx_reply_t_handler
2459   (vl_api_vxlan_offload_rx_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471     }
2472 }
2473
2474 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2475   (vl_api_vxlan_offload_rx_reply_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t node;
2479
2480   vat_json_init_object (&node);
2481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2482
2483   vat_json_print (vam->ofp, &node);
2484   vat_json_free (&node);
2485
2486   vam->retval = ntohl (mp->retval);
2487   vam->result_ready = 1;
2488 }
2489
2490 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2491   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   i32 retval = ntohl (mp->retval);
2495   if (vam->async_mode)
2496     {
2497       vam->async_errors += (retval < 0);
2498     }
2499   else
2500     {
2501       vam->retval = retval;
2502       vam->sw_if_index = ntohl (mp->sw_if_index);
2503       vam->result_ready = 1;
2504     }
2505   vam->regenerate_interface_table = 1;
2506 }
2507
2508 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2509   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t node;
2513
2514   vat_json_init_object (&node);
2515   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2516   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2517
2518   vat_json_print (vam->ofp, &node);
2519   vat_json_free (&node);
2520
2521   vam->retval = ntohl (mp->retval);
2522   vam->result_ready = 1;
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540 }
2541
2542 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2543   (vl_api_gre_tunnel_add_del_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t node;
2547
2548   vat_json_init_object (&node);
2549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2551
2552   vat_json_print (vam->ofp, &node);
2553   vat_json_free (&node);
2554
2555   vam->retval = ntohl (mp->retval);
2556   vam->result_ready = 1;
2557 }
2558
2559 static void vl_api_create_vhost_user_if_reply_t_handler
2560   (vl_api_create_vhost_user_if_reply_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563   i32 retval = ntohl (mp->retval);
2564   if (vam->async_mode)
2565     {
2566       vam->async_errors += (retval < 0);
2567     }
2568   else
2569     {
2570       vam->retval = retval;
2571       vam->sw_if_index = ntohl (mp->sw_if_index);
2572       vam->result_ready = 1;
2573     }
2574   vam->regenerate_interface_table = 1;
2575 }
2576
2577 static void vl_api_create_vhost_user_if_reply_t_handler_json
2578   (vl_api_create_vhost_user_if_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_ip_address_details_t_handler
2595   (vl_api_ip_address_details_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   static ip_address_details_t empty_ip_address_details = { {0} };
2599   ip_address_details_t *address = NULL;
2600   ip_details_t *current_ip_details = NULL;
2601   ip_details_t *details = NULL;
2602
2603   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2604
2605   if (!details || vam->current_sw_if_index >= vec_len (details)
2606       || !details[vam->current_sw_if_index].present)
2607     {
2608       errmsg ("ip address details arrived but not stored");
2609       errmsg ("ip_dump should be called first");
2610       return;
2611     }
2612
2613   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2614
2615 #define addresses (current_ip_details->addr)
2616
2617   vec_validate_init_empty (addresses, vec_len (addresses),
2618                            empty_ip_address_details);
2619
2620   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2621
2622   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2623   address->prefix_length = mp->prefix.len;
2624 #undef addresses
2625 }
2626
2627 static void vl_api_ip_address_details_t_handler_json
2628   (vl_api_ip_address_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639
2640   vat_json_init_object (node);
2641   vat_json_object_add_prefix (node, &mp->prefix);
2642 }
2643
2644 static void
2645 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   static ip_details_t empty_ip_details = { 0 };
2649   ip_details_t *ip = NULL;
2650   u32 sw_if_index = ~0;
2651
2652   sw_if_index = ntohl (mp->sw_if_index);
2653
2654   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2655                            sw_if_index, empty_ip_details);
2656
2657   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2658                          sw_if_index);
2659
2660   ip->present = 1;
2661 }
2662
2663 static void
2664 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   vat_json_array_add_uint (&vam->json_tree,
2674                            clib_net_to_host_u32 (mp->sw_if_index));
2675 }
2676
2677 static void vl_api_get_first_msg_id_reply_t_handler
2678   (vl_api_get_first_msg_id_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (vam->async_mode)
2684     {
2685       vam->async_errors += (retval < 0);
2686     }
2687   else
2688     {
2689       vam->retval = retval;
2690       vam->result_ready = 1;
2691     }
2692   if (retval >= 0)
2693     {
2694       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2695     }
2696 }
2697
2698 static void vl_api_get_first_msg_id_reply_t_handler_json
2699   (vl_api_get_first_msg_id_reply_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t node;
2703
2704   vat_json_init_object (&node);
2705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2706   vat_json_object_add_uint (&node, "first_msg_id",
2707                             (uint) ntohs (mp->first_msg_id));
2708
2709   vat_json_print (vam->ofp, &node);
2710   vat_json_free (&node);
2711
2712   vam->retval = ntohl (mp->retval);
2713   vam->result_ready = 1;
2714 }
2715
2716 static void vl_api_get_node_graph_reply_t_handler
2717   (vl_api_get_node_graph_reply_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720   i32 retval = ntohl (mp->retval);
2721   u8 *pvt_copy, *reply;
2722   void *oldheap;
2723   vlib_node_t *node;
2724   int i;
2725
2726   if (vam->async_mode)
2727     {
2728       vam->async_errors += (retval < 0);
2729     }
2730   else
2731     {
2732       vam->retval = retval;
2733       vam->result_ready = 1;
2734     }
2735
2736   /* "Should never happen..." */
2737   if (retval != 0)
2738     return;
2739
2740   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2741   pvt_copy = vec_dup (reply);
2742
2743   /* Toss the shared-memory original... */
2744   oldheap = vl_msg_push_heap ();
2745
2746   vec_free (reply);
2747
2748   vl_msg_pop_heap (oldheap);
2749
2750   if (vam->graph_nodes)
2751     {
2752       hash_free (vam->graph_node_index_by_name);
2753
2754       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2755         {
2756           node = vam->graph_nodes[0][i];
2757           vec_free (node->name);
2758           vec_free (node->next_nodes);
2759           vec_free (node);
2760         }
2761       vec_free (vam->graph_nodes[0]);
2762       vec_free (vam->graph_nodes);
2763     }
2764
2765   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2766   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2767   vec_free (pvt_copy);
2768
2769   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2770     {
2771       node = vam->graph_nodes[0][i];
2772       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2773     }
2774 }
2775
2776 static void vl_api_get_node_graph_reply_t_handler_json
2777   (vl_api_get_node_graph_reply_t * mp)
2778 {
2779   vat_main_t *vam = &vat_main;
2780   void *oldheap;
2781   vat_json_node_t node;
2782   u8 *reply;
2783
2784   /* $$$$ make this real? */
2785   vat_json_init_object (&node);
2786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2787   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790
2791   /* Toss the shared-memory original... */
2792   oldheap = vl_msg_push_heap ();
2793
2794   vec_free (reply);
2795
2796   vl_msg_pop_heap (oldheap);
2797
2798   vat_json_print (vam->ofp, &node);
2799   vat_json_free (&node);
2800
2801   vam->retval = ntohl (mp->retval);
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   u8 *s = 0;
2810
2811   if (mp->local)
2812     {
2813       s = format (s, "%=16d%=16d%=16d",
2814                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2815     }
2816   else
2817     {
2818       s = format (s, "%=16U%=16d%=16d",
2819                   format_ip46_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->ip_address.af)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 static u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2928
2929   switch (eid->type)
2930     {
2931     case EID_TYPE_API_PREFIX:
2932       if (eid->address.prefix.address.af)
2933         return format (s, "%U/%d", format_ip6_address,
2934                        eid->address.prefix.address.un.ip6,
2935                        eid->address.prefix.len);
2936       return format (s, "%U/%d", format_ip4_address,
2937                      eid->address.prefix.address.un.ip4,
2938                      eid->address.prefix.len);
2939     case EID_TYPE_API_MAC:
2940       return format (s, "%U", format_ethernet_address, eid->address.mac);
2941     case EID_TYPE_API_NSH:
2942       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2943     }
2944   return 0;
2945 }
2946
2947 static u8 *
2948 format_lisp_eid_vat (u8 * s, va_list * args)
2949 {
2950   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2951   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2952   u8 is_src_dst = (u8) va_arg (*args, int);
2953
2954   if (is_src_dst)
2955     s = format (s, "%U|", format_lisp_flat_eid, seid);
2956
2957   s = format (s, "%U", format_lisp_flat_eid, deid);
2958
2959   return s;
2960 }
2961
2962 static void
2963 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   u8 *s = 0, *eid = 0;
2967
2968   if (~0 == mp->locator_set_index)
2969     s = format (0, "action: %d", mp->action);
2970   else
2971     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   eid = format (0, "%U", format_lisp_eid_vat,
2974                 &mp->deid, &mp->seid, mp->is_src_dst);
2975   vec_add1 (eid, 0);
2976
2977   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2978          clib_net_to_host_u32 (mp->vni),
2979          eid,
2980          mp->is_local ? "local" : "remote",
2981          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2982          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2983
2984   vec_free (s);
2985   vec_free (eid);
2986 }
2987
2988 static void
2989 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2990                                              * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   vat_json_node_t *node = 0;
2994   u8 *eid = 0;
2995
2996   if (VAT_JSON_ARRAY != vam->json_tree.type)
2997     {
2998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2999       vat_json_init_array (&vam->json_tree);
3000     }
3001   node = vat_json_array_add (&vam->json_tree);
3002
3003   vat_json_init_object (node);
3004   if (~0 == mp->locator_set_index)
3005     vat_json_object_add_uint (node, "action", mp->action);
3006   else
3007     vat_json_object_add_uint (node, "locator_set_index",
3008                               clib_net_to_host_u32 (mp->locator_set_index));
3009
3010   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3011   if (mp->deid.type == 3)
3012     {
3013       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3014       vat_json_init_object (nsh_json);
3015       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3016       vat_json_object_add_uint (nsh_json, "spi",
3017                                 clib_net_to_host_u32 (nsh->spi));
3018       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3019     }
3020   else
3021     {
3022       eid = format (0, "%U", format_lisp_eid_vat,
3023                     &mp->deid, &mp->seid, mp->is_src_dst);
3024       vec_add1 (eid, 0);
3025       vat_json_object_add_string_copy (node, "eid", eid);
3026       vec_free (eid);
3027     }
3028   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3029   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3030   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3031
3032   if (mp->key.id)
3033     {
3034       vat_json_object_add_uint (node, "key_id",
3035                                 clib_net_to_host_u16 (mp->key.id));
3036       vat_json_object_add_string_copy (node, "key", mp->key.key);
3037     }
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3042 {
3043   vat_main_t *vam = &vat_main;
3044   u8 *seid = 0, *deid = 0;
3045   ip46_address_t lloc, rloc;
3046
3047   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3048
3049   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3050
3051   vec_add1 (deid, 0);
3052   vec_add1 (seid, 0);
3053
3054   if (mp->lloc.af)
3055     {
3056       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3057       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3058     }
3059   else
3060     {
3061       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3062       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3063     }
3064
3065
3066   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3067          clib_net_to_host_u32 (mp->vni),
3068          seid, deid,
3069          format_ip46_address, lloc,
3070          format_ip46_address, rloc,
3071          clib_net_to_host_u32 (mp->pkt_count),
3072          clib_net_to_host_u32 (mp->bytes));
3073
3074   vec_free (deid);
3075   vec_free (seid);
3076 }
3077
3078 static void
3079 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3080 {
3081   struct in6_addr ip6;
3082   struct in_addr ip4;
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t *node = 0;
3085   u8 *deid = 0, *seid = 0;
3086
3087   if (VAT_JSON_ARRAY != vam->json_tree.type)
3088     {
3089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3090       vat_json_init_array (&vam->json_tree);
3091     }
3092   node = vat_json_array_add (&vam->json_tree);
3093
3094   vat_json_init_object (node);
3095   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3096
3097   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3098
3099   vec_add1 (deid, 0);
3100   vec_add1 (seid, 0);
3101
3102   vat_json_object_add_string_copy (node, "seid", seid);
3103   vat_json_object_add_string_copy (node, "deid", deid);
3104   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3105
3106   if (mp->lloc.af)
3107     {
3108       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112
3113     }
3114   else
3115     {
3116       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3117       vat_json_object_add_ip4 (node, "lloc", ip4);
3118       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3119       vat_json_object_add_ip4 (node, "rloc", ip4);
3120     }
3121   vat_json_object_add_uint (node, "pkt_count",
3122                             clib_net_to_host_u32 (mp->pkt_count));
3123   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3124
3125   vec_free (deid);
3126   vec_free (seid);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134
3135   u8 *line = format (0, "%=10d%=10d",
3136                      clib_net_to_host_u32 (mp->vni),
3137                      clib_net_to_host_u32 (mp->dp_table));
3138   print (vam->ofp, "%v", line);
3139   vec_free (line);
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_map_details_t_handler_json
3144   (vl_api_one_eid_table_map_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   vat_json_node_t *node = NULL;
3148
3149   if (VAT_JSON_ARRAY != vam->json_tree.type)
3150     {
3151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3152       vat_json_init_array (&vam->json_tree);
3153     }
3154   node = vat_json_array_add (&vam->json_tree);
3155   vat_json_init_object (node);
3156   vat_json_object_add_uint (node, "dp_table",
3157                             clib_net_to_host_u32 (mp->dp_table));
3158   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3159 }
3160
3161 static void
3162   vl_api_one_eid_table_vni_details_t_handler
3163   (vl_api_one_eid_table_vni_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166
3167   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_vni_details_t_handler_json
3174   (vl_api_one_eid_table_vni_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3187 }
3188
3189 static void
3190   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3191   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   int retval = clib_net_to_host_u32 (mp->retval);
3195
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3197   print (vam->ofp, "fallback threshold value: %d", mp->value);
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3205   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t _node, *node = &_node;
3209   int retval = clib_net_to_host_u32 (mp->retval);
3210
3211   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3212   vat_json_init_object (node);
3213   vat_json_object_add_uint (node, "value", mp->value);
3214
3215   vat_json_print (vam->ofp, node);
3216   vat_json_free (node);
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   int retval = clib_net_to_host_u32 (mp->retval);
3228
3229   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3230
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_map_register_state_reply_t_handler_json
3237   (vl_api_show_one_map_register_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_string_copy (node, "state", s);
3247
3248   vat_json_print (vam->ofp, node);
3249   vat_json_free (node);
3250
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253   vec_free (s);
3254 }
3255
3256 static void
3257   vl_api_show_one_rloc_probe_state_reply_t_handler
3258   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   if (retval)
3264     goto end;
3265
3266   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3267 end:
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3274   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t _node, *node = &_node;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_stats_enable_disable_reply_t_handler
3294   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3310   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3330 {
3331   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3332   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3333   e->vni = clib_net_to_host_u32 (e->vni);
3334 }
3335
3336 static void
3337   gpe_fwd_entries_get_reply_t_net_to_host
3338   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3339 {
3340   u32 i;
3341
3342   mp->count = clib_net_to_host_u32 (mp->count);
3343   for (i = 0; i < mp->count; i++)
3344     {
3345       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3346     }
3347 }
3348
3349 static u8 *
3350 format_gpe_encap_mode (u8 * s, va_list * args)
3351 {
3352   u32 mode = va_arg (*args, u32);
3353
3354   switch (mode)
3355     {
3356     case 0:
3357       return format (s, "lisp");
3358     case 1:
3359       return format (s, "vxlan");
3360     }
3361   return 0;
3362 }
3363
3364 static void
3365   vl_api_gpe_get_encap_mode_reply_t_handler
3366   (vl_api_gpe_get_encap_mode_reply_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369
3370   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3371   vam->retval = ntohl (mp->retval);
3372   vam->result_ready = 1;
3373 }
3374
3375 static void
3376   vl_api_gpe_get_encap_mode_reply_t_handler_json
3377   (vl_api_gpe_get_encap_mode_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   vat_json_node_t node;
3381
3382   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3383   vec_add1 (encap_mode, 0);
3384
3385   vat_json_init_object (&node);
3386   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3387
3388   vec_free (encap_mode);
3389   vat_json_print (vam->ofp, &node);
3390   vat_json_free (&node);
3391
3392   vam->retval = ntohl (mp->retval);
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_gpe_fwd_entry_path_details_t_handler
3398   (vl_api_gpe_fwd_entry_path_details_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3402
3403   if (mp->lcl_loc.addr.af)
3404     format_ip_address_fcn = format_ip6_address;
3405   else
3406     format_ip_address_fcn = format_ip4_address;
3407
3408   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3409          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3410          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3411 }
3412
3413 static void
3414 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3415 {
3416   struct in6_addr ip6;
3417   struct in_addr ip4;
3418
3419   if (loc->addr.af)
3420     {
3421       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3422       vat_json_object_add_ip6 (n, "address", ip6);
3423     }
3424   else
3425     {
3426       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3427       vat_json_object_add_ip4 (n, "address", ip4);
3428     }
3429   vat_json_object_add_uint (n, "weight", loc->weight);
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler_json
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   vat_json_node_t *node = NULL;
3438   vat_json_node_t *loc_node;
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446   vat_json_init_object (node);
3447
3448   loc_node = vat_json_object_add (node, "local_locator");
3449   vat_json_init_object (loc_node);
3450   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3451
3452   loc_node = vat_json_object_add (node, "remote_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3455 }
3456
3457 static void
3458   vl_api_gpe_fwd_entries_get_reply_t_handler
3459   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   u32 i;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464   vl_api_gpe_fwd_entry_t *e;
3465
3466   if (retval)
3467     goto end;
3468
3469   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3470
3471   for (i = 0; i < mp->count; i++)
3472     {
3473       e = &mp->entries[i];
3474       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3475              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3485   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3486 {
3487   u8 *s = 0;
3488   vat_main_t *vam = &vat_main;
3489   vat_json_node_t *e = 0, root;
3490   u32 i;
3491   int retval = clib_net_to_host_u32 (mp->retval);
3492   vl_api_gpe_fwd_entry_t *fwd;
3493
3494   if (retval)
3495     goto end;
3496
3497   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3498   vat_json_init_array (&root);
3499
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       e = vat_json_array_add (&root);
3503       fwd = &mp->entries[i];
3504
3505       vat_json_init_object (e);
3506       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3507       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3508       vat_json_object_add_int (e, "vni", fwd->vni);
3509       vat_json_object_add_int (e, "action", fwd->action);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "leid", s);
3514       vec_free (s);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3517       vec_add1 (s, 0);
3518       vat_json_object_add_string_copy (e, "reid", s);
3519       vec_free (s);
3520     }
3521
3522   vat_json_print (vam->ofp, &root);
3523   vat_json_free (&root);
3524
3525 end:
3526   vam->retval = retval;
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3532   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u32 i, n;
3536   int retval = clib_net_to_host_u32 (mp->retval);
3537   vl_api_gpe_native_fwd_rpath_t *r;
3538
3539   if (retval)
3540     goto end;
3541
3542   n = clib_net_to_host_u32 (mp->count);
3543
3544   for (i = 0; i < n; i++)
3545     {
3546       r = &mp->entries[i];
3547       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3548              clib_net_to_host_u32 (r->fib_index),
3549              clib_net_to_host_u32 (r->nh_sw_if_index),
3550              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3551              r->nh_addr.un);
3552     }
3553
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3561   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t root, *e;
3565   u32 i, n;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567   vl_api_gpe_native_fwd_rpath_t *r;
3568   u8 *s;
3569
3570   if (retval)
3571     goto end;
3572
3573   n = clib_net_to_host_u32 (mp->count);
3574   vat_json_init_array (&root);
3575
3576   for (i = 0; i < n; i++)
3577     {
3578       e = vat_json_array_add (&root);
3579       vat_json_init_object (e);
3580       r = &mp->entries[i];
3581       s =
3582         format (0, "%U",
3583                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3584                 r->nh_addr.un);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "ip4", s);
3587       vec_free (s);
3588
3589       vat_json_object_add_uint (e, "fib_index",
3590                                 clib_net_to_host_u32 (r->fib_index));
3591       vat_json_object_add_uint (e, "nh_sw_if_index",
3592                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3593     }
3594
3595   vat_json_print (vam->ofp, &root);
3596   vat_json_free (&root);
3597
3598 end:
3599   vam->retval = retval;
3600   vam->result_ready = 1;
3601 }
3602
3603 static void
3604   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3605   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3606 {
3607   vat_main_t *vam = &vat_main;
3608   u32 i, n;
3609   int retval = clib_net_to_host_u32 (mp->retval);
3610
3611   if (retval)
3612     goto end;
3613
3614   n = clib_net_to_host_u32 (mp->count);
3615
3616   for (i = 0; i < n; i++)
3617     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3618
3619 end:
3620   vam->retval = retval;
3621   vam->result_ready = 1;
3622 }
3623
3624 static void
3625   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3626   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3627 {
3628   vat_main_t *vam = &vat_main;
3629   vat_json_node_t root;
3630   u32 i, n;
3631   int retval = clib_net_to_host_u32 (mp->retval);
3632
3633   if (retval)
3634     goto end;
3635
3636   n = clib_net_to_host_u32 (mp->count);
3637   vat_json_init_array (&root);
3638
3639   for (i = 0; i < n; i++)
3640     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3641
3642   vat_json_print (vam->ofp, &root);
3643   vat_json_free (&root);
3644
3645 end:
3646   vam->retval = retval;
3647   vam->result_ready = 1;
3648 }
3649
3650 static void
3651   vl_api_one_ndp_entries_get_reply_t_handler
3652   (vl_api_one_ndp_entries_get_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662
3663   for (i = 0; i < n; i++)
3664     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3665            format_ethernet_address, mp->entries[i].mac);
3666
3667 end:
3668   vam->retval = retval;
3669   vam->result_ready = 1;
3670 }
3671
3672 static void
3673   vl_api_one_ndp_entries_get_reply_t_handler_json
3674   (vl_api_one_ndp_entries_get_reply_t * mp)
3675 {
3676   u8 *s = 0;
3677   vat_main_t *vam = &vat_main;
3678   vat_json_node_t *e = 0, root;
3679   u32 i, n;
3680   int retval = clib_net_to_host_u32 (mp->retval);
3681   vl_api_one_ndp_entry_t *arp_entry;
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687   vat_json_init_array (&root);
3688
3689   for (i = 0; i < n; i++)
3690     {
3691       e = vat_json_array_add (&root);
3692       arp_entry = &mp->entries[i];
3693
3694       vat_json_init_object (e);
3695       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3696       vec_add1 (s, 0);
3697
3698       vat_json_object_add_string_copy (e, "mac", s);
3699       vec_free (s);
3700
3701       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3702       vec_add1 (s, 0);
3703       vat_json_object_add_string_copy (e, "ip6", s);
3704       vec_free (s);
3705     }
3706
3707   vat_json_print (vam->ofp, &root);
3708   vat_json_free (&root);
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_one_l2_arp_entries_get_reply_t_handler
3717   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722
3723   if (retval)
3724     goto end;
3725
3726   n = clib_net_to_host_u32 (mp->count);
3727
3728   for (i = 0; i < n; i++)
3729     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3730            format_ethernet_address, mp->entries[i].mac);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3739   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3740 {
3741   u8 *s = 0;
3742   vat_main_t *vam = &vat_main;
3743   vat_json_node_t *e = 0, root;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746   vl_api_one_l2_arp_entry_t *arp_entry;
3747
3748   if (retval)
3749     goto end;
3750
3751   n = clib_net_to_host_u32 (mp->count);
3752   vat_json_init_array (&root);
3753
3754   for (i = 0; i < n; i++)
3755     {
3756       e = vat_json_array_add (&root);
3757       arp_entry = &mp->entries[i];
3758
3759       vat_json_init_object (e);
3760       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3761       vec_add1 (s, 0);
3762
3763       vat_json_object_add_string_copy (e, "mac", s);
3764       vec_free (s);
3765
3766       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3767       vec_add1 (s, 0);
3768       vat_json_object_add_string_copy (e, "ip4", s);
3769       vec_free (s);
3770     }
3771
3772   vat_json_print (vam->ofp, &root);
3773   vat_json_free (&root);
3774
3775 end:
3776   vam->retval = retval;
3777   vam->result_ready = 1;
3778 }
3779
3780 static void
3781 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3782 {
3783   vat_main_t *vam = &vat_main;
3784   u32 i, n;
3785   int retval = clib_net_to_host_u32 (mp->retval);
3786
3787   if (retval)
3788     goto end;
3789
3790   n = clib_net_to_host_u32 (mp->count);
3791
3792   for (i = 0; i < n; i++)
3793     {
3794       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3795     }
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_ndp_bd_get_reply_t_handler_json
3804   (vl_api_one_ndp_bd_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   vat_json_node_t root;
3808   u32 i, n;
3809   int retval = clib_net_to_host_u32 (mp->retval);
3810
3811   if (retval)
3812     goto end;
3813
3814   n = clib_net_to_host_u32 (mp->count);
3815   vat_json_init_array (&root);
3816
3817   for (i = 0; i < n; i++)
3818     {
3819       vat_json_array_add_uint (&root,
3820                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3821     }
3822
3823   vat_json_print (vam->ofp, &root);
3824   vat_json_free (&root);
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_one_l2_arp_bd_get_reply_t_handler
3833   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   u32 i, n;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838
3839   if (retval)
3840     goto end;
3841
3842   n = clib_net_to_host_u32 (mp->count);
3843
3844   for (i = 0; i < n; i++)
3845     {
3846       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3847     }
3848
3849 end:
3850   vam->retval = retval;
3851   vam->result_ready = 1;
3852 }
3853
3854 static void
3855   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3856   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3857 {
3858   vat_main_t *vam = &vat_main;
3859   vat_json_node_t root;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867   vat_json_init_array (&root);
3868
3869   for (i = 0; i < n; i++)
3870     {
3871       vat_json_array_add_uint (&root,
3872                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3873     }
3874
3875   vat_json_print (vam->ofp, &root);
3876   vat_json_free (&root);
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_one_adjacencies_get_reply_t_handler
3885   (vl_api_one_adjacencies_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   u32 i, n;
3889   int retval = clib_net_to_host_u32 (mp->retval);
3890   vl_api_one_adjacency_t *a;
3891
3892   if (retval)
3893     goto end;
3894
3895   n = clib_net_to_host_u32 (mp->count);
3896
3897   for (i = 0; i < n; i++)
3898     {
3899       a = &mp->adjacencies[i];
3900       print (vam->ofp, "%U %40U",
3901              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3902     }
3903
3904 end:
3905   vam->retval = retval;
3906   vam->result_ready = 1;
3907 }
3908
3909 static void
3910   vl_api_one_adjacencies_get_reply_t_handler_json
3911   (vl_api_one_adjacencies_get_reply_t * mp)
3912 {
3913   u8 *s = 0;
3914   vat_main_t *vam = &vat_main;
3915   vat_json_node_t *e = 0, root;
3916   u32 i, n;
3917   int retval = clib_net_to_host_u32 (mp->retval);
3918   vl_api_one_adjacency_t *a;
3919
3920   if (retval)
3921     goto end;
3922
3923   n = clib_net_to_host_u32 (mp->count);
3924   vat_json_init_array (&root);
3925
3926   for (i = 0; i < n; i++)
3927     {
3928       e = vat_json_array_add (&root);
3929       a = &mp->adjacencies[i];
3930
3931       vat_json_init_object (e);
3932       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3933       vec_add1 (s, 0);
3934       vat_json_object_add_string_copy (e, "leid", s);
3935       vec_free (s);
3936
3937       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "reid", s);
3940       vec_free (s);
3941     }
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955
3956   print (vam->ofp, "%=20U",
3957          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3958          mp->ip_address.un);
3959 }
3960
3961 static void
3962   vl_api_one_map_server_details_t_handler_json
3963   (vl_api_one_map_server_details_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t *node = NULL;
3967   struct in6_addr ip6;
3968   struct in_addr ip4;
3969
3970   if (VAT_JSON_ARRAY != vam->json_tree.type)
3971     {
3972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3973       vat_json_init_array (&vam->json_tree);
3974     }
3975   node = vat_json_array_add (&vam->json_tree);
3976
3977   vat_json_init_object (node);
3978   if (mp->ip_address.af)
3979     {
3980       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3981       vat_json_object_add_ip6 (node, "map-server", ip6);
3982     }
3983   else
3984     {
3985       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3986       vat_json_object_add_ip4 (node, "map-server", ip4);
3987     }
3988 }
3989
3990 static void
3991 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3992                                            * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3998          mp->ip_address.un);
3999 }
4000
4001 static void
4002   vl_api_one_map_resolver_details_t_handler_json
4003   (vl_api_one_map_resolver_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->ip_address.af)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map resolver", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map resolver", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   i32 retval = ntohl (mp->retval);
4035
4036   if (0 <= retval)
4037     {
4038       print (vam->ofp, "feature: %s\ngpe: %s",
4039              mp->feature_status ? "enabled" : "disabled",
4040              mp->gpe_status ? "enabled" : "disabled");
4041     }
4042
4043   vam->retval = retval;
4044   vam->result_ready = 1;
4045 }
4046
4047 static void
4048   vl_api_show_one_status_reply_t_handler_json
4049   (vl_api_show_one_status_reply_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t node;
4053   u8 *gpe_status = NULL;
4054   u8 *feature_status = NULL;
4055
4056   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4057   feature_status = format (0, "%s",
4058                            mp->feature_status ? "enabled" : "disabled");
4059   vec_add1 (gpe_status, 0);
4060   vec_add1 (feature_status, 0);
4061
4062   vat_json_init_object (&node);
4063   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4064   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4065
4066   vec_free (gpe_status);
4067   vec_free (feature_status);
4068
4069   vat_json_print (vam->ofp, &node);
4070   vat_json_free (&node);
4071
4072   vam->retval = ntohl (mp->retval);
4073   vam->result_ready = 1;
4074 }
4075
4076 static void
4077   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4078   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   i32 retval = ntohl (mp->retval);
4082
4083   if (retval >= 0)
4084     {
4085       print (vam->ofp, "%=20s", mp->locator_set_name);
4086     }
4087
4088   vam->retval = retval;
4089   vam->result_ready = 1;
4090 }
4091
4092 static void
4093   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4094   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t *node = NULL;
4098
4099   if (VAT_JSON_ARRAY != vam->json_tree.type)
4100     {
4101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4102       vat_json_init_array (&vam->json_tree);
4103     }
4104   node = vat_json_array_add (&vam->json_tree);
4105
4106   vat_json_init_object (node);
4107   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4108
4109   vat_json_print (vam->ofp, node);
4110   vat_json_free (node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static u8 *
4117 format_lisp_map_request_mode (u8 * s, va_list * args)
4118 {
4119   u32 mode = va_arg (*args, u32);
4120
4121   switch (mode)
4122     {
4123     case 0:
4124       return format (0, "dst-only");
4125     case 1:
4126       return format (0, "src-dst");
4127     }
4128   return 0;
4129 }
4130
4131 static void
4132   vl_api_show_one_map_request_mode_reply_t_handler
4133   (vl_api_show_one_map_request_mode_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   i32 retval = ntohl (mp->retval);
4137
4138   if (0 <= retval)
4139     {
4140       u32 mode = mp->mode;
4141       print (vam->ofp, "map_request_mode: %U",
4142              format_lisp_map_request_mode, mode);
4143     }
4144
4145   vam->retval = retval;
4146   vam->result_ready = 1;
4147 }
4148
4149 static void
4150   vl_api_show_one_map_request_mode_reply_t_handler_json
4151   (vl_api_show_one_map_request_mode_reply_t * mp)
4152 {
4153   vat_main_t *vam = &vat_main;
4154   vat_json_node_t node;
4155   u8 *s = 0;
4156   u32 mode;
4157
4158   mode = mp->mode;
4159   s = format (0, "%U", format_lisp_map_request_mode, mode);
4160   vec_add1 (s, 0);
4161
4162   vat_json_init_object (&node);
4163   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4164   vat_json_print (vam->ofp, &node);
4165   vat_json_free (&node);
4166
4167   vec_free (s);
4168   vam->retval = ntohl (mp->retval);
4169   vam->result_ready = 1;
4170 }
4171
4172 static void
4173   vl_api_one_show_xtr_mode_reply_t_handler
4174   (vl_api_one_show_xtr_mode_reply_t * mp)
4175 {
4176   vat_main_t *vam = &vat_main;
4177   i32 retval = ntohl (mp->retval);
4178
4179   if (0 <= retval)
4180     {
4181       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4182     }
4183
4184   vam->retval = retval;
4185   vam->result_ready = 1;
4186 }
4187
4188 static void
4189   vl_api_one_show_xtr_mode_reply_t_handler_json
4190   (vl_api_one_show_xtr_mode_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194   u8 *status = 0;
4195
4196   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4197   vec_add1 (status, 0);
4198
4199   vat_json_init_object (&node);
4200   vat_json_object_add_string_copy (&node, "status", status);
4201
4202   vec_free (status);
4203
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vam->retval = ntohl (mp->retval);
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_show_pitr_mode_reply_t_handler
4213   (vl_api_one_show_pitr_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   i32 retval = ntohl (mp->retval);
4217
4218   if (0 <= retval)
4219     {
4220       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4221     }
4222
4223   vam->retval = retval;
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_show_pitr_mode_reply_t_handler_json
4229   (vl_api_one_show_pitr_mode_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   vat_json_node_t node;
4233   u8 *status = 0;
4234
4235   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4236   vec_add1 (status, 0);
4237
4238   vat_json_init_object (&node);
4239   vat_json_object_add_string_copy (&node, "status", status);
4240
4241   vec_free (status);
4242
4243   vat_json_print (vam->ofp, &node);
4244   vat_json_free (&node);
4245
4246   vam->retval = ntohl (mp->retval);
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_petr_mode_reply_t_handler
4252   (vl_api_one_show_petr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   i32 retval = ntohl (mp->retval);
4256
4257   if (0 <= retval)
4258     {
4259       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4260     }
4261
4262   vam->retval = retval;
4263   vam->result_ready = 1;
4264 }
4265
4266 static void
4267   vl_api_one_show_petr_mode_reply_t_handler_json
4268   (vl_api_one_show_petr_mode_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   vat_json_node_t node;
4272   u8 *status = 0;
4273
4274   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4275   vec_add1 (status, 0);
4276
4277   vat_json_init_object (&node);
4278   vat_json_object_add_string_copy (&node, "status", status);
4279
4280   vec_free (status);
4281
4282   vat_json_print (vam->ofp, &node);
4283   vat_json_free (&node);
4284
4285   vam->retval = ntohl (mp->retval);
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_show_one_use_petr_reply_t_handler
4291   (vl_api_show_one_use_petr_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   i32 retval = ntohl (mp->retval);
4295
4296   if (0 <= retval)
4297     {
4298       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4299       if (mp->status)
4300         {
4301           print (vam->ofp, "Proxy-ETR address; %U",
4302                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4303                  mp->ip_address.un);
4304         }
4305     }
4306
4307   vam->retval = retval;
4308   vam->result_ready = 1;
4309 }
4310
4311 static void
4312   vl_api_show_one_use_petr_reply_t_handler_json
4313   (vl_api_show_one_use_petr_reply_t * mp)
4314 {
4315   vat_main_t *vam = &vat_main;
4316   vat_json_node_t node;
4317   u8 *status = 0;
4318   struct in_addr ip4;
4319   struct in6_addr ip6;
4320
4321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326   if (mp->status)
4327     {
4328       if (mp->ip_address.af)
4329         {
4330           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4331           vat_json_object_add_ip6 (&node, "address", ip6);
4332         }
4333       else
4334         {
4335           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4336           vat_json_object_add_ip4 (&node, "address", ip4);
4337         }
4338     }
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_show_one_nsh_mapping_reply_t_handler
4351   (vl_api_show_one_nsh_mapping_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%-20s%-16s",
4359              mp->is_set ? "set" : "not-set",
4360              mp->is_set ? (char *) mp->locator_set_name : "");
4361     }
4362
4363   vam->retval = retval;
4364   vam->result_ready = 1;
4365 }
4366
4367 static void
4368   vl_api_show_one_nsh_mapping_reply_t_handler_json
4369   (vl_api_show_one_nsh_mapping_reply_t * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   vat_json_node_t node;
4373   u8 *status = 0;
4374
4375   status = format (0, "%s", mp->is_set ? "yes" : "no");
4376   vec_add1 (status, 0);
4377
4378   vat_json_init_object (&node);
4379   vat_json_object_add_string_copy (&node, "is_set", status);
4380   if (mp->is_set)
4381     {
4382       vat_json_object_add_string_copy (&node, "locator_set",
4383                                        mp->locator_set_name);
4384     }
4385
4386   vec_free (status);
4387
4388   vat_json_print (vam->ofp, &node);
4389   vat_json_free (&node);
4390
4391   vam->retval = ntohl (mp->retval);
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_show_one_map_register_ttl_reply_t_handler
4397   (vl_api_show_one_map_register_ttl_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   i32 retval = ntohl (mp->retval);
4401
4402   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "ttl: %u", mp->ttl);
4407     }
4408
4409   vam->retval = retval;
4410   vam->result_ready = 1;
4411 }
4412
4413 static void
4414   vl_api_show_one_map_register_ttl_reply_t_handler_json
4415   (vl_api_show_one_map_register_ttl_reply_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   vat_json_node_t node;
4419
4420   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4421   vat_json_init_object (&node);
4422   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4423
4424   vat_json_print (vam->ofp, &node);
4425   vat_json_free (&node);
4426
4427   vam->retval = ntohl (mp->retval);
4428   vam->result_ready = 1;
4429 }
4430
4431 static void
4432 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "%-20s%-16s",
4440              mp->status ? "enabled" : "disabled",
4441              mp->status ? (char *) mp->locator_set_name : "");
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453   u8 *status = 0;
4454
4455   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4456   vec_add1 (status, 0);
4457
4458   vat_json_init_object (&node);
4459   vat_json_object_add_string_copy (&node, "status", status);
4460   if (mp->status)
4461     {
4462       vat_json_object_add_string_copy (&node, "locator_set",
4463                                        mp->locator_set_name);
4464     }
4465
4466   vec_free (status);
4467
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static u8 *
4476 format_policer_type (u8 * s, va_list * va)
4477 {
4478   u32 i = va_arg (*va, u32);
4479
4480   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4481     s = format (s, "1r2c");
4482   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4483     s = format (s, "1r3c");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4485     s = format (s, "2r3c-2698");
4486   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4487     s = format (s, "2r3c-4115");
4488   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4489     s = format (s, "2r3c-mef5cf1");
4490   else
4491     s = format (s, "ILLEGAL");
4492   return s;
4493 }
4494
4495 static u8 *
4496 format_policer_rate_type (u8 * s, va_list * va)
4497 {
4498   u32 i = va_arg (*va, u32);
4499
4500   if (i == SSE2_QOS_RATE_KBPS)
4501     s = format (s, "kbps");
4502   else if (i == SSE2_QOS_RATE_PPS)
4503     s = format (s, "pps");
4504   else
4505     s = format (s, "ILLEGAL");
4506   return s;
4507 }
4508
4509 static u8 *
4510 format_policer_round_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4515     s = format (s, "closest");
4516   else if (i == SSE2_QOS_ROUND_TO_UP)
4517     s = format (s, "up");
4518   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4519     s = format (s, "down");
4520   else
4521     s = format (s, "ILLEGAL");
4522   return s;
4523 }
4524
4525 static u8 *
4526 format_policer_action_type (u8 * s, va_list * va)
4527 {
4528   u32 i = va_arg (*va, u32);
4529
4530   if (i == SSE2_QOS_ACTION_DROP)
4531     s = format (s, "drop");
4532   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4533     s = format (s, "transmit");
4534   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4535     s = format (s, "mark-and-transmit");
4536   else
4537     s = format (s, "ILLEGAL");
4538   return s;
4539 }
4540
4541 static u8 *
4542 format_dscp (u8 * s, va_list * va)
4543 {
4544   u32 i = va_arg (*va, u32);
4545   char *t = 0;
4546
4547   switch (i)
4548     {
4549 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4550       foreach_vnet_dscp
4551 #undef _
4552     default:
4553       return format (s, "ILLEGAL");
4554     }
4555   s = format (s, "%s", t);
4556   return s;
4557 }
4558
4559 static void
4560 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4561 {
4562   vat_main_t *vam = &vat_main;
4563   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4564
4565   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4566     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4567   else
4568     conform_dscp_str = format (0, "");
4569
4570   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4571     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4572   else
4573     exceed_dscp_str = format (0, "");
4574
4575   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4576     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4577   else
4578     violate_dscp_str = format (0, "");
4579
4580   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4581          "rate type %U, round type %U, %s rate, %s color-aware, "
4582          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4583          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4584          "conform action %U%s, exceed action %U%s, violate action %U%s",
4585          mp->name,
4586          format_policer_type, mp->type,
4587          ntohl (mp->cir),
4588          ntohl (mp->eir),
4589          clib_net_to_host_u64 (mp->cb),
4590          clib_net_to_host_u64 (mp->eb),
4591          format_policer_rate_type, mp->rate_type,
4592          format_policer_round_type, mp->round_type,
4593          mp->single_rate ? "single" : "dual",
4594          mp->color_aware ? "is" : "not",
4595          ntohl (mp->cir_tokens_per_period),
4596          ntohl (mp->pir_tokens_per_period),
4597          ntohl (mp->scale),
4598          ntohl (mp->current_limit),
4599          ntohl (mp->current_bucket),
4600          ntohl (mp->extended_limit),
4601          ntohl (mp->extended_bucket),
4602          clib_net_to_host_u64 (mp->last_update_time),
4603          format_policer_action_type, mp->conform_action.type,
4604          conform_dscp_str,
4605          format_policer_action_type, mp->exceed_action.type,
4606          exceed_dscp_str,
4607          format_policer_action_type, mp->violate_action.type,
4608          violate_dscp_str);
4609
4610   vec_free (conform_dscp_str);
4611   vec_free (exceed_dscp_str);
4612   vec_free (violate_dscp_str);
4613 }
4614
4615 static void vl_api_policer_details_t_handler_json
4616   (vl_api_policer_details_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t *node;
4620   u8 *rate_type_str, *round_type_str, *type_str;
4621   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4622
4623   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4624   round_type_str =
4625     format (0, "%U", format_policer_round_type, mp->round_type);
4626   type_str = format (0, "%U", format_policer_type, mp->type);
4627   conform_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->conform_action.type);
4629   exceed_action_str = format (0, "%U", format_policer_action_type,
4630                               mp->exceed_action.type);
4631   violate_action_str = format (0, "%U", format_policer_action_type,
4632                                mp->violate_action.type);
4633
4634   if (VAT_JSON_ARRAY != vam->json_tree.type)
4635     {
4636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4637       vat_json_init_array (&vam->json_tree);
4638     }
4639   node = vat_json_array_add (&vam->json_tree);
4640
4641   vat_json_init_object (node);
4642   vat_json_object_add_string_copy (node, "name", mp->name);
4643   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4644   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4645   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4646   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4647   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4648   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4649   vat_json_object_add_string_copy (node, "type", type_str);
4650   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4651   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4652   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4653   vat_json_object_add_uint (node, "cir_tokens_per_period",
4654                             ntohl (mp->cir_tokens_per_period));
4655   vat_json_object_add_uint (node, "eir_tokens_per_period",
4656                             ntohl (mp->pir_tokens_per_period));
4657   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4658   vat_json_object_add_uint (node, "current_bucket",
4659                             ntohl (mp->current_bucket));
4660   vat_json_object_add_uint (node, "extended_limit",
4661                             ntohl (mp->extended_limit));
4662   vat_json_object_add_uint (node, "extended_bucket",
4663                             ntohl (mp->extended_bucket));
4664   vat_json_object_add_uint (node, "last_update_time",
4665                             ntohl (mp->last_update_time));
4666   vat_json_object_add_string_copy (node, "conform_action",
4667                                    conform_action_str);
4668   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4671       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4675   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4676     {
4677       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4678       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4679       vec_free (dscp_str);
4680     }
4681   vat_json_object_add_string_copy (node, "violate_action",
4682                                    violate_action_str);
4683   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4686       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689
4690   vec_free (rate_type_str);
4691   vec_free (round_type_str);
4692   vec_free (type_str);
4693   vec_free (conform_action_str);
4694   vec_free (exceed_action_str);
4695   vec_free (violate_action_str);
4696 }
4697
4698 static void
4699 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4700                                            mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   int i, count = ntohl (mp->count);
4704
4705   if (count > 0)
4706     print (vam->ofp, "classify table ids (%d) : ", count);
4707   for (i = 0; i < count; i++)
4708     {
4709       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4710       print (vam->ofp, (i < count - 1) ? "," : "");
4711     }
4712   vam->retval = ntohl (mp->retval);
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_classify_table_ids_reply_t_handler_json
4718   (vl_api_classify_table_ids_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   int i, count = ntohl (mp->count);
4722
4723   if (count > 0)
4724     {
4725       vat_json_node_t node;
4726
4727       vat_json_init_object (&node);
4728       for (i = 0; i < count; i++)
4729         {
4730           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4731         }
4732       vat_json_print (vam->ofp, &node);
4733       vat_json_free (&node);
4734     }
4735   vam->retval = ntohl (mp->retval);
4736   vam->result_ready = 1;
4737 }
4738
4739 static void
4740   vl_api_classify_table_by_interface_reply_t_handler
4741   (vl_api_classify_table_by_interface_reply_t * mp)
4742 {
4743   vat_main_t *vam = &vat_main;
4744   u32 table_id;
4745
4746   table_id = ntohl (mp->l2_table_id);
4747   if (table_id != ~0)
4748     print (vam->ofp, "l2 table id : %d", table_id);
4749   else
4750     print (vam->ofp, "l2 table id : No input ACL tables configured");
4751   table_id = ntohl (mp->ip4_table_id);
4752   if (table_id != ~0)
4753     print (vam->ofp, "ip4 table id : %d", table_id);
4754   else
4755     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4756   table_id = ntohl (mp->ip6_table_id);
4757   if (table_id != ~0)
4758     print (vam->ofp, "ip6 table id : %d", table_id);
4759   else
4760     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4761   vam->retval = ntohl (mp->retval);
4762   vam->result_ready = 1;
4763 }
4764
4765 static void
4766   vl_api_classify_table_by_interface_reply_t_handler_json
4767   (vl_api_classify_table_by_interface_reply_t * mp)
4768 {
4769   vat_main_t *vam = &vat_main;
4770   vat_json_node_t node;
4771
4772   vat_json_init_object (&node);
4773
4774   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4775   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4776   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4777
4778   vat_json_print (vam->ofp, &node);
4779   vat_json_free (&node);
4780
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void vl_api_policer_add_del_reply_t_handler
4786   (vl_api_policer_add_del_reply_t * mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   i32 retval = ntohl (mp->retval);
4790   if (vam->async_mode)
4791     {
4792       vam->async_errors += (retval < 0);
4793     }
4794   else
4795     {
4796       vam->retval = retval;
4797       vam->result_ready = 1;
4798       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4799         /*
4800          * Note: this is just barely thread-safe, depends on
4801          * the main thread spinning waiting for an answer...
4802          */
4803         errmsg ("policer index %d", ntohl (mp->policer_index));
4804     }
4805 }
4806
4807 static void vl_api_policer_add_del_reply_t_handler_json
4808   (vl_api_policer_add_del_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   vat_json_node_t node;
4812
4813   vat_json_init_object (&node);
4814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4815   vat_json_object_add_uint (&node, "policer_index",
4816                             ntohl (mp->policer_index));
4817
4818   vat_json_print (vam->ofp, &node);
4819   vat_json_free (&node);
4820
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 /* Format hex dump. */
4826 u8 *
4827 format_hex_bytes (u8 * s, va_list * va)
4828 {
4829   u8 *bytes = va_arg (*va, u8 *);
4830   int n_bytes = va_arg (*va, int);
4831   uword i;
4832
4833   /* Print short or long form depending on byte count. */
4834   uword short_form = n_bytes <= 32;
4835   u32 indent = format_get_indent (s);
4836
4837   if (n_bytes == 0)
4838     return s;
4839
4840   for (i = 0; i < n_bytes; i++)
4841     {
4842       if (!short_form && (i % 32) == 0)
4843         s = format (s, "%08x: ", i);
4844       s = format (s, "%02x", bytes[i]);
4845       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4846         s = format (s, "\n%U", format_white_space, indent);
4847     }
4848
4849   return s;
4850 }
4851
4852 static void
4853 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4854                                             * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858   if (retval == 0)
4859     {
4860       print (vam->ofp, "classify table info :");
4861       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4862              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4863              ntohl (mp->miss_next_index));
4864       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4865              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4866              ntohl (mp->match_n_vectors));
4867       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4868              ntohl (mp->mask_length));
4869     }
4870   vam->retval = retval;
4871   vam->result_ready = 1;
4872 }
4873
4874 static void
4875   vl_api_classify_table_info_reply_t_handler_json
4876   (vl_api_classify_table_info_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sessions",
4887                                ntohl (mp->active_sessions));
4888       vat_json_object_add_int (&node, "nexttbl",
4889                                ntohl (mp->next_table_index));
4890       vat_json_object_add_int (&node, "nextnode",
4891                                ntohl (mp->miss_next_index));
4892       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4893       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4894       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4895       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4896                       ntohl (mp->mask_length), 0);
4897       vat_json_object_add_string_copy (&node, "mask", s);
4898
4899       vat_json_print (vam->ofp, &node);
4900       vat_json_free (&node);
4901     }
4902   vam->retval = ntohl (mp->retval);
4903   vam->result_ready = 1;
4904 }
4905
4906 static void
4907 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4908                                            mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911
4912   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4913          ntohl (mp->hit_next_index), ntohl (mp->advance),
4914          ntohl (mp->opaque_index));
4915   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4916          ntohl (mp->match_length));
4917 }
4918
4919 static void
4920   vl_api_classify_session_details_t_handler_json
4921   (vl_api_classify_session_details_t * mp)
4922 {
4923   vat_main_t *vam = &vat_main;
4924   vat_json_node_t *node = NULL;
4925
4926   if (VAT_JSON_ARRAY != vam->json_tree.type)
4927     {
4928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4929       vat_json_init_array (&vam->json_tree);
4930     }
4931   node = vat_json_array_add (&vam->json_tree);
4932
4933   vat_json_init_object (node);
4934   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4935   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4936   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4937   u8 *s =
4938     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4939             0);
4940   vat_json_object_add_string_copy (node, "match", s);
4941 }
4942
4943 static void vl_api_pg_create_interface_reply_t_handler
4944   (vl_api_pg_create_interface_reply_t * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947
4948   vam->retval = ntohl (mp->retval);
4949   vam->result_ready = 1;
4950 }
4951
4952 static void vl_api_pg_create_interface_reply_t_handler_json
4953   (vl_api_pg_create_interface_reply_t * mp)
4954 {
4955   vat_main_t *vam = &vat_main;
4956   vat_json_node_t node;
4957
4958   i32 retval = ntohl (mp->retval);
4959   if (retval == 0)
4960     {
4961       vat_json_init_object (&node);
4962
4963       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4964
4965       vat_json_print (vam->ofp, &node);
4966       vat_json_free (&node);
4967     }
4968   vam->retval = ntohl (mp->retval);
4969   vam->result_ready = 1;
4970 }
4971
4972 static void vl_api_policer_classify_details_t_handler
4973   (vl_api_policer_classify_details_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976
4977   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4978          ntohl (mp->table_index));
4979 }
4980
4981 static void vl_api_policer_classify_details_t_handler_json
4982   (vl_api_policer_classify_details_t * mp)
4983 {
4984   vat_main_t *vam = &vat_main;
4985   vat_json_node_t *node;
4986
4987   if (VAT_JSON_ARRAY != vam->json_tree.type)
4988     {
4989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4990       vat_json_init_array (&vam->json_tree);
4991     }
4992   node = vat_json_array_add (&vam->json_tree);
4993
4994   vat_json_init_object (node);
4995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4996   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4997 }
4998
4999 static void vl_api_flow_classify_details_t_handler
5000   (vl_api_flow_classify_details_t * mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5005          ntohl (mp->table_index));
5006 }
5007
5008 static void vl_api_flow_classify_details_t_handler_json
5009   (vl_api_flow_classify_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5023   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5024 }
5025
5026 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5027 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5032 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5033 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5035 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5036
5037 /*
5038  * Generate boilerplate reply handlers, which
5039  * dig the return value out of the xxx_reply_t API message,
5040  * stick it into vam->retval, and set vam->result_ready
5041  *
5042  * Could also do this by pointing N message decode slots at
5043  * a single function, but that could break in subtle ways.
5044  */
5045
5046 #define foreach_standard_reply_retval_handler           \
5047 _(sw_interface_set_flags_reply)                         \
5048 _(sw_interface_add_del_address_reply)                   \
5049 _(sw_interface_set_rx_mode_reply)                       \
5050 _(sw_interface_set_rx_placement_reply)                  \
5051 _(sw_interface_set_table_reply)                         \
5052 _(sw_interface_set_mpls_enable_reply)                   \
5053 _(sw_interface_set_vpath_reply)                         \
5054 _(sw_interface_set_vxlan_bypass_reply)                  \
5055 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5056 _(sw_interface_set_l2_bridge_reply)                     \
5057 _(sw_interface_set_bond_weight_reply)                   \
5058 _(bridge_domain_add_del_reply)                          \
5059 _(sw_interface_set_l2_xconnect_reply)                   \
5060 _(l2fib_add_del_reply)                                  \
5061 _(l2fib_flush_int_reply)                                \
5062 _(l2fib_flush_bd_reply)                                 \
5063 _(ip_route_add_del_reply)                               \
5064 _(ip_table_add_del_reply)                               \
5065 _(ip_table_replace_begin_reply)                         \
5066 _(ip_table_flush_reply)                                 \
5067 _(ip_table_replace_end_reply)                           \
5068 _(ip_mroute_add_del_reply)                              \
5069 _(mpls_route_add_del_reply)                             \
5070 _(mpls_table_add_del_reply)                             \
5071 _(mpls_ip_bind_unbind_reply)                            \
5072 _(bier_route_add_del_reply)                             \
5073 _(bier_table_add_del_reply)                             \
5074 _(sw_interface_set_unnumbered_reply)                    \
5075 _(set_ip_flow_hash_reply)                               \
5076 _(sw_interface_ip6_enable_disable_reply)                \
5077 _(l2_patch_add_del_reply)                               \
5078 _(sr_mpls_policy_add_reply)                             \
5079 _(sr_mpls_policy_mod_reply)                             \
5080 _(sr_mpls_policy_del_reply)                             \
5081 _(sr_policy_add_reply)                                  \
5082 _(sr_policy_mod_reply)                                  \
5083 _(sr_policy_del_reply)                                  \
5084 _(sr_localsid_add_del_reply)                            \
5085 _(sr_steering_add_del_reply)                            \
5086 _(classify_add_del_session_reply)                       \
5087 _(classify_set_interface_ip_table_reply)                \
5088 _(classify_set_interface_l2_tables_reply)               \
5089 _(l2_fib_clear_table_reply)                             \
5090 _(l2_interface_efp_filter_reply)                        \
5091 _(l2_interface_vlan_tag_rewrite_reply)                  \
5092 _(modify_vhost_user_if_reply)                           \
5093 _(delete_vhost_user_if_reply)                           \
5094 _(want_l2_macs_events_reply)                            \
5095 _(input_acl_set_interface_reply)                        \
5096 _(ipsec_spd_add_del_reply)                              \
5097 _(ipsec_interface_add_del_spd_reply)                    \
5098 _(ipsec_spd_entry_add_del_reply)                        \
5099 _(ipsec_sad_entry_add_del_reply)                        \
5100 _(ipsec_tunnel_if_add_del_reply)                        \
5101 _(ipsec_tunnel_if_set_sa_reply)                         \
5102 _(delete_loopback_reply)                                \
5103 _(bd_ip_mac_add_del_reply)                              \
5104 _(bd_ip_mac_flush_reply)                                \
5105 _(want_interface_events_reply)                          \
5106 _(cop_interface_enable_disable_reply)                   \
5107 _(cop_whitelist_enable_disable_reply)                   \
5108 _(sw_interface_clear_stats_reply)                       \
5109 _(ioam_enable_reply)                                    \
5110 _(ioam_disable_reply)                                   \
5111 _(one_add_del_locator_reply)                            \
5112 _(one_add_del_local_eid_reply)                          \
5113 _(one_add_del_remote_mapping_reply)                     \
5114 _(one_add_del_adjacency_reply)                          \
5115 _(one_add_del_map_resolver_reply)                       \
5116 _(one_add_del_map_server_reply)                         \
5117 _(one_enable_disable_reply)                             \
5118 _(one_rloc_probe_enable_disable_reply)                  \
5119 _(one_map_register_enable_disable_reply)                \
5120 _(one_map_register_set_ttl_reply)                       \
5121 _(one_set_transport_protocol_reply)                     \
5122 _(one_map_register_fallback_threshold_reply)            \
5123 _(one_pitr_set_locator_set_reply)                       \
5124 _(one_map_request_mode_reply)                           \
5125 _(one_add_del_map_request_itr_rlocs_reply)              \
5126 _(one_eid_table_add_del_map_reply)                      \
5127 _(one_use_petr_reply)                                   \
5128 _(one_stats_enable_disable_reply)                       \
5129 _(one_add_del_l2_arp_entry_reply)                       \
5130 _(one_add_del_ndp_entry_reply)                          \
5131 _(one_stats_flush_reply)                                \
5132 _(one_enable_disable_xtr_mode_reply)                    \
5133 _(one_enable_disable_pitr_mode_reply)                   \
5134 _(one_enable_disable_petr_mode_reply)                   \
5135 _(gpe_enable_disable_reply)                             \
5136 _(gpe_set_encap_mode_reply)                             \
5137 _(gpe_add_del_iface_reply)                              \
5138 _(gpe_add_del_native_fwd_rpath_reply)                   \
5139 _(af_packet_delete_reply)                               \
5140 _(policer_classify_set_interface_reply)                 \
5141 _(set_ipfix_exporter_reply)                             \
5142 _(set_ipfix_classify_stream_reply)                      \
5143 _(ipfix_classify_table_add_del_reply)                   \
5144 _(flow_classify_set_interface_reply)                    \
5145 _(sw_interface_span_enable_disable_reply)               \
5146 _(pg_capture_reply)                                     \
5147 _(pg_enable_disable_reply)                              \
5148 _(pg_interface_enable_disable_coalesce_reply)           \
5149 _(ip_source_and_port_range_check_add_del_reply)         \
5150 _(ip_source_and_port_range_check_interface_add_del_reply)\
5151 _(delete_subif_reply)                                   \
5152 _(l2_interface_pbb_tag_rewrite_reply)                   \
5153 _(set_punt_reply)                                       \
5154 _(feature_enable_disable_reply)                         \
5155 _(feature_gso_enable_disable_reply)                     \
5156 _(sw_interface_tag_add_del_reply)                       \
5157 _(sw_interface_add_del_mac_address_reply)               \
5158 _(hw_interface_set_mtu_reply)                           \
5159 _(p2p_ethernet_add_reply)                               \
5160 _(p2p_ethernet_del_reply)                               \
5161 _(tcp_configure_src_addresses_reply)                    \
5162 _(session_rule_add_del_reply)                           \
5163 _(ip_container_proxy_add_del_reply)                     \
5164 _(output_acl_set_interface_reply)                       \
5165 _(qos_record_enable_disable_reply)                      \
5166 _(flow_add_reply)
5167
5168 #define _(n)                                    \
5169     static void vl_api_##n##_t_handler          \
5170     (vl_api_##n##_t * mp)                       \
5171     {                                           \
5172         vat_main_t * vam = &vat_main;           \
5173         i32 retval = ntohl(mp->retval);         \
5174         if (vam->async_mode) {                  \
5175             vam->async_errors += (retval < 0);  \
5176         } else {                                \
5177             vam->retval = retval;               \
5178             vam->result_ready = 1;              \
5179         }                                       \
5180     }
5181 foreach_standard_reply_retval_handler;
5182 #undef _
5183
5184 #define _(n)                                    \
5185     static void vl_api_##n##_t_handler_json     \
5186     (vl_api_##n##_t * mp)                       \
5187     {                                           \
5188         vat_main_t * vam = &vat_main;           \
5189         vat_json_node_t node;                   \
5190         vat_json_init_object(&node);            \
5191         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5192         vat_json_print(vam->ofp, &node);        \
5193         vam->retval = ntohl(mp->retval);        \
5194         vam->result_ready = 1;                  \
5195     }
5196 foreach_standard_reply_retval_handler;
5197 #undef _
5198
5199 /*
5200  * Table of message reply handlers, must include boilerplate handlers
5201  * we just generated
5202  */
5203
5204 #define foreach_vpe_api_reply_msg                                       \
5205 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5206 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5207 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5208 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5209 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5210 _(CLI_REPLY, cli_reply)                                                 \
5211 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5212 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5213   sw_interface_add_del_address_reply)                                   \
5214 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5215 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5216 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5217 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5218 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5219 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5220 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5221 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5222 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5223   sw_interface_set_l2_xconnect_reply)                                   \
5224 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5225   sw_interface_set_l2_bridge_reply)                                     \
5226 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5227 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5228 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5229 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5230 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5231 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5232 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5233 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5234 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5235 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5236 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5237 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5238 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
5239 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5240 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5241 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5242 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
5243 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5244 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5245 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5246 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5247 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5248 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5249 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5250 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5251 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5252 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5253 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5254 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5255 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5256 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5257 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5258 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5259 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5260 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5261 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5262   sw_interface_set_unnumbered_reply)                                    \
5263 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5264 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5265 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5266 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5267   sw_interface_ip6_enable_disable_reply)                                \
5268 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5269 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5270 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5271 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5272 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5273 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5274 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5275 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5276 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5277 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5278 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5279 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5280 classify_set_interface_ip_table_reply)                                  \
5281 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5282   classify_set_interface_l2_tables_reply)                               \
5283 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5284 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5285 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5286 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5287 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5288 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5289 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5290 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5291 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5292 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5293 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5294 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5295 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5296 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5297 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5298 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5299 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5300 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5301 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5302 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5303 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5304 _(L2_MACS_EVENT, l2_macs_event)                                         \
5305 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5306 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5307 _(IP_DETAILS, ip_details)                                               \
5308 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5309 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5310 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5311 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5312 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5313 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5314 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5315 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5316 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5317 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5318 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5319 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5320 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5321 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5322 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5323 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5324 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5325 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5326 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5327 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5328 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5329 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5330 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5331 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5332 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5333 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5334 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5335 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5336   one_map_register_enable_disable_reply)                                \
5337 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5338 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5339 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5340 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5341   one_map_register_fallback_threshold_reply)                            \
5342 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5343   one_rloc_probe_enable_disable_reply)                                  \
5344 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5345 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5346 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5347 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5348 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5349 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5350 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5351 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5352 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5353 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5354 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5355 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5356 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5357 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5358 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5359 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5360   show_one_stats_enable_disable_reply)                                  \
5361 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5362 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5363 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5364 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5365 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5366 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5367 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5368 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5369   one_enable_disable_pitr_mode_reply)                                   \
5370 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5371   one_enable_disable_petr_mode_reply)                                   \
5372 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5373 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5374 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5375 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5376 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5377 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5378 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5379 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5380 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5381 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5382 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5383 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5384   gpe_add_del_native_fwd_rpath_reply)                                   \
5385 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5386   gpe_fwd_entry_path_details)                                           \
5387 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5388 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5389   one_add_del_map_request_itr_rlocs_reply)                              \
5390 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5391   one_get_map_request_itr_rlocs_reply)                                  \
5392 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5393 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5394 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5395 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5396 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5397 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5398   show_one_map_register_state_reply)                                    \
5399 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5400 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5401   show_one_map_register_fallback_threshold_reply)                       \
5402 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5403 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5404 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5405 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5406 _(POLICER_DETAILS, policer_details)                                     \
5407 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5408 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5409 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5410 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5411 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5412 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5413 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5414 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5415 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5416 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5417 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5418 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5419 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5420 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5421 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5422 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5423 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5424 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5425 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5426 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5427 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5428 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5429 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5430 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5431 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5432  ip_source_and_port_range_check_add_del_reply)                          \
5433 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5434  ip_source_and_port_range_check_interface_add_del_reply)                \
5435 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5436 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5437 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5438 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5439 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5440 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5441 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5442 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5443 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5444 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5445 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5446 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5447 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5448 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5449 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5450 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5451 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5452 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5453 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5454 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5455 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5456 _(FLOW_ADD_REPLY, flow_add_reply)   \
5457
5458 #define foreach_standalone_reply_msg                                    \
5459 _(SW_INTERFACE_EVENT, sw_interface_event)
5460
5461 typedef struct
5462 {
5463   u8 *name;
5464   u32 value;
5465 } name_sort_t;
5466
5467 #define STR_VTR_OP_CASE(op)     \
5468     case L2_VTR_ ## op:         \
5469         return "" # op;
5470
5471 static const char *
5472 str_vtr_op (u32 vtr_op)
5473 {
5474   switch (vtr_op)
5475     {
5476       STR_VTR_OP_CASE (DISABLED);
5477       STR_VTR_OP_CASE (PUSH_1);
5478       STR_VTR_OP_CASE (PUSH_2);
5479       STR_VTR_OP_CASE (POP_1);
5480       STR_VTR_OP_CASE (POP_2);
5481       STR_VTR_OP_CASE (TRANSLATE_1_1);
5482       STR_VTR_OP_CASE (TRANSLATE_1_2);
5483       STR_VTR_OP_CASE (TRANSLATE_2_1);
5484       STR_VTR_OP_CASE (TRANSLATE_2_2);
5485     }
5486
5487   return "UNKNOWN";
5488 }
5489
5490 static int
5491 dump_sub_interface_table (vat_main_t * vam)
5492 {
5493   const sw_interface_subif_t *sub = NULL;
5494
5495   if (vam->json_output)
5496     {
5497       clib_warning
5498         ("JSON output supported only for VPE API calls and dump_stats_table");
5499       return -99;
5500     }
5501
5502   print (vam->ofp,
5503          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5504          "Interface", "sw_if_index",
5505          "sub id", "dot1ad", "tags", "outer id",
5506          "inner id", "exact", "default", "outer any", "inner any");
5507
5508   vec_foreach (sub, vam->sw_if_subif_table)
5509   {
5510     print (vam->ofp,
5511            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5512            sub->interface_name,
5513            sub->sw_if_index,
5514            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5515            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5516            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5517            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5518     if (sub->vtr_op != L2_VTR_DISABLED)
5519       {
5520         print (vam->ofp,
5521                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5522                "tag1: %d tag2: %d ]",
5523                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5524                sub->vtr_tag1, sub->vtr_tag2);
5525       }
5526   }
5527
5528   return 0;
5529 }
5530
5531 static int
5532 name_sort_cmp (void *a1, void *a2)
5533 {
5534   name_sort_t *n1 = a1;
5535   name_sort_t *n2 = a2;
5536
5537   return strcmp ((char *) n1->name, (char *) n2->name);
5538 }
5539
5540 static int
5541 dump_interface_table (vat_main_t * vam)
5542 {
5543   hash_pair_t *p;
5544   name_sort_t *nses = 0, *ns;
5545
5546   if (vam->json_output)
5547     {
5548       clib_warning
5549         ("JSON output supported only for VPE API calls and dump_stats_table");
5550       return -99;
5551     }
5552
5553   /* *INDENT-OFF* */
5554   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5555   ({
5556     vec_add2 (nses, ns, 1);
5557     ns->name = (u8 *)(p->key);
5558     ns->value = (u32) p->value[0];
5559   }));
5560   /* *INDENT-ON* */
5561
5562   vec_sort_with_function (nses, name_sort_cmp);
5563
5564   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5565   vec_foreach (ns, nses)
5566   {
5567     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5568   }
5569   vec_free (nses);
5570   return 0;
5571 }
5572
5573 static int
5574 dump_ip_table (vat_main_t * vam, int is_ipv6)
5575 {
5576   const ip_details_t *det = NULL;
5577   const ip_address_details_t *address = NULL;
5578   u32 i = ~0;
5579
5580   print (vam->ofp, "%-12s", "sw_if_index");
5581
5582   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5583   {
5584     i++;
5585     if (!det->present)
5586       {
5587         continue;
5588       }
5589     print (vam->ofp, "%-12d", i);
5590     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5591     if (!det->addr)
5592       {
5593         continue;
5594       }
5595     vec_foreach (address, det->addr)
5596     {
5597       print (vam->ofp,
5598              "            %-30U%-13d",
5599              is_ipv6 ? format_ip6_address : format_ip4_address,
5600              address->ip, address->prefix_length);
5601     }
5602   }
5603
5604   return 0;
5605 }
5606
5607 static int
5608 dump_ipv4_table (vat_main_t * vam)
5609 {
5610   if (vam->json_output)
5611     {
5612       clib_warning
5613         ("JSON output supported only for VPE API calls and dump_stats_table");
5614       return -99;
5615     }
5616
5617   return dump_ip_table (vam, 0);
5618 }
5619
5620 static int
5621 dump_ipv6_table (vat_main_t * vam)
5622 {
5623   if (vam->json_output)
5624     {
5625       clib_warning
5626         ("JSON output supported only for VPE API calls and dump_stats_table");
5627       return -99;
5628     }
5629
5630   return dump_ip_table (vam, 1);
5631 }
5632
5633 /*
5634  * Pass CLI buffers directly in the CLI_INBAND API message,
5635  * instead of an additional shared memory area.
5636  */
5637 static int
5638 exec_inband (vat_main_t * vam)
5639 {
5640   vl_api_cli_inband_t *mp;
5641   unformat_input_t *i = vam->input;
5642   int ret;
5643
5644   if (vec_len (i->buffer) == 0)
5645     return -1;
5646
5647   if (vam->exec_mode == 0 && unformat (i, "mode"))
5648     {
5649       vam->exec_mode = 1;
5650       return 0;
5651     }
5652   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5653     {
5654       vam->exec_mode = 0;
5655       return 0;
5656     }
5657
5658   /*
5659    * In order for the CLI command to work, it
5660    * must be a vector ending in \n, not a C-string ending
5661    * in \n\0.
5662    */
5663   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5664   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5665
5666   S (mp);
5667   W (ret);
5668   /* json responses may or may not include a useful reply... */
5669   if (vec_len (vam->cmd_reply))
5670     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5671   return ret;
5672 }
5673
5674 int
5675 exec (vat_main_t * vam)
5676 {
5677   return exec_inband (vam);
5678 }
5679
5680 static int
5681 api_create_loopback (vat_main_t * vam)
5682 {
5683   unformat_input_t *i = vam->input;
5684   vl_api_create_loopback_t *mp;
5685   vl_api_create_loopback_instance_t *mp_lbi;
5686   u8 mac_address[6];
5687   u8 mac_set = 0;
5688   u8 is_specified = 0;
5689   u32 user_instance = 0;
5690   int ret;
5691
5692   clib_memset (mac_address, 0, sizeof (mac_address));
5693
5694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5695     {
5696       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5697         mac_set = 1;
5698       if (unformat (i, "instance %d", &user_instance))
5699         is_specified = 1;
5700       else
5701         break;
5702     }
5703
5704   if (is_specified)
5705     {
5706       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5707       mp_lbi->is_specified = is_specified;
5708       if (is_specified)
5709         mp_lbi->user_instance = htonl (user_instance);
5710       if (mac_set)
5711         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5712       S (mp_lbi);
5713     }
5714   else
5715     {
5716       /* Construct the API message */
5717       M (CREATE_LOOPBACK, mp);
5718       if (mac_set)
5719         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5720       S (mp);
5721     }
5722
5723   W (ret);
5724   return ret;
5725 }
5726
5727 static int
5728 api_delete_loopback (vat_main_t * vam)
5729 {
5730   unformat_input_t *i = vam->input;
5731   vl_api_delete_loopback_t *mp;
5732   u32 sw_if_index = ~0;
5733   int ret;
5734
5735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5736     {
5737       if (unformat (i, "sw_if_index %d", &sw_if_index))
5738         ;
5739       else
5740         break;
5741     }
5742
5743   if (sw_if_index == ~0)
5744     {
5745       errmsg ("missing sw_if_index");
5746       return -99;
5747     }
5748
5749   /* Construct the API message */
5750   M (DELETE_LOOPBACK, mp);
5751   mp->sw_if_index = ntohl (sw_if_index);
5752
5753   S (mp);
5754   W (ret);
5755   return ret;
5756 }
5757
5758 static int
5759 api_want_interface_events (vat_main_t * vam)
5760 {
5761   unformat_input_t *i = vam->input;
5762   vl_api_want_interface_events_t *mp;
5763   int enable = -1;
5764   int ret;
5765
5766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5767     {
5768       if (unformat (i, "enable"))
5769         enable = 1;
5770       else if (unformat (i, "disable"))
5771         enable = 0;
5772       else
5773         break;
5774     }
5775
5776   if (enable == -1)
5777     {
5778       errmsg ("missing enable|disable");
5779       return -99;
5780     }
5781
5782   M (WANT_INTERFACE_EVENTS, mp);
5783   mp->enable_disable = enable;
5784
5785   vam->interface_event_display = enable;
5786
5787   S (mp);
5788   W (ret);
5789   return ret;
5790 }
5791
5792
5793 /* Note: non-static, called once to set up the initial intfc table */
5794 int
5795 api_sw_interface_dump (vat_main_t * vam)
5796 {
5797   vl_api_sw_interface_dump_t *mp;
5798   vl_api_control_ping_t *mp_ping;
5799   hash_pair_t *p;
5800   name_sort_t *nses = 0, *ns;
5801   sw_interface_subif_t *sub = NULL;
5802   int ret;
5803
5804   /* Toss the old name table */
5805   /* *INDENT-OFF* */
5806   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5807   ({
5808     vec_add2 (nses, ns, 1);
5809     ns->name = (u8 *)(p->key);
5810     ns->value = (u32) p->value[0];
5811   }));
5812   /* *INDENT-ON* */
5813
5814   hash_free (vam->sw_if_index_by_interface_name);
5815
5816   vec_foreach (ns, nses) vec_free (ns->name);
5817
5818   vec_free (nses);
5819
5820   vec_foreach (sub, vam->sw_if_subif_table)
5821   {
5822     vec_free (sub->interface_name);
5823   }
5824   vec_free (vam->sw_if_subif_table);
5825
5826   /* recreate the interface name hash table */
5827   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5828
5829   /*
5830    * Ask for all interface names. Otherwise, the epic catalog of
5831    * name filters becomes ridiculously long, and vat ends up needing
5832    * to be taught about new interface types.
5833    */
5834   M (SW_INTERFACE_DUMP, mp);
5835   S (mp);
5836
5837   /* Use a control ping for synchronization */
5838   MPING (CONTROL_PING, mp_ping);
5839   S (mp_ping);
5840
5841   W (ret);
5842   return ret;
5843 }
5844
5845 static int
5846 api_sw_interface_set_flags (vat_main_t * vam)
5847 {
5848   unformat_input_t *i = vam->input;
5849   vl_api_sw_interface_set_flags_t *mp;
5850   u32 sw_if_index;
5851   u8 sw_if_index_set = 0;
5852   u8 admin_up = 0;
5853   int ret;
5854
5855   /* Parse args required to build the message */
5856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5857     {
5858       if (unformat (i, "admin-up"))
5859         admin_up = 1;
5860       else if (unformat (i, "admin-down"))
5861         admin_up = 0;
5862       else
5863         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5864         sw_if_index_set = 1;
5865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5866         sw_if_index_set = 1;
5867       else
5868         break;
5869     }
5870
5871   if (sw_if_index_set == 0)
5872     {
5873       errmsg ("missing interface name or sw_if_index");
5874       return -99;
5875     }
5876
5877   /* Construct the API message */
5878   M (SW_INTERFACE_SET_FLAGS, mp);
5879   mp->sw_if_index = ntohl (sw_if_index);
5880   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5881
5882   /* send it... */
5883   S (mp);
5884
5885   /* Wait for a reply, return the good/bad news... */
5886   W (ret);
5887   return ret;
5888 }
5889
5890 static int
5891 api_sw_interface_set_rx_mode (vat_main_t * vam)
5892 {
5893   unformat_input_t *i = vam->input;
5894   vl_api_sw_interface_set_rx_mode_t *mp;
5895   u32 sw_if_index;
5896   u8 sw_if_index_set = 0;
5897   int ret;
5898   u8 queue_id_valid = 0;
5899   u32 queue_id;
5900   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5901
5902   /* Parse args required to build the message */
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "queue %d", &queue_id))
5906         queue_id_valid = 1;
5907       else if (unformat (i, "polling"))
5908         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5909       else if (unformat (i, "interrupt"))
5910         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5911       else if (unformat (i, "adaptive"))
5912         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5913       else
5914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5915         sw_if_index_set = 1;
5916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5917         sw_if_index_set = 1;
5918       else
5919         break;
5920     }
5921
5922   if (sw_if_index_set == 0)
5923     {
5924       errmsg ("missing interface name or sw_if_index");
5925       return -99;
5926     }
5927   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5928     {
5929       errmsg ("missing rx-mode");
5930       return -99;
5931     }
5932
5933   /* Construct the API message */
5934   M (SW_INTERFACE_SET_RX_MODE, mp);
5935   mp->sw_if_index = ntohl (sw_if_index);
5936   mp->mode = (vl_api_rx_mode_t) mode;
5937   mp->queue_id_valid = queue_id_valid;
5938   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5939
5940   /* send it... */
5941   S (mp);
5942
5943   /* Wait for a reply, return the good/bad news... */
5944   W (ret);
5945   return ret;
5946 }
5947
5948 static int
5949 api_sw_interface_set_rx_placement (vat_main_t * vam)
5950 {
5951   unformat_input_t *i = vam->input;
5952   vl_api_sw_interface_set_rx_placement_t *mp;
5953   u32 sw_if_index;
5954   u8 sw_if_index_set = 0;
5955   int ret;
5956   u8 is_main = 0;
5957   u32 queue_id, thread_index;
5958
5959   /* Parse args required to build the message */
5960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5961     {
5962       if (unformat (i, "queue %d", &queue_id))
5963         ;
5964       else if (unformat (i, "main"))
5965         is_main = 1;
5966       else if (unformat (i, "worker %d", &thread_index))
5967         ;
5968       else
5969         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5970         sw_if_index_set = 1;
5971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5972         sw_if_index_set = 1;
5973       else
5974         break;
5975     }
5976
5977   if (sw_if_index_set == 0)
5978     {
5979       errmsg ("missing interface name or sw_if_index");
5980       return -99;
5981     }
5982
5983   if (is_main)
5984     thread_index = 0;
5985   /* Construct the API message */
5986   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5987   mp->sw_if_index = ntohl (sw_if_index);
5988   mp->worker_id = ntohl (thread_index);
5989   mp->queue_id = ntohl (queue_id);
5990   mp->is_main = is_main;
5991
5992   /* send it... */
5993   S (mp);
5994   /* Wait for a reply, return the good/bad news... */
5995   W (ret);
5996   return ret;
5997 }
5998
5999 static void vl_api_sw_interface_rx_placement_details_t_handler
6000   (vl_api_sw_interface_rx_placement_details_t * mp)
6001 {
6002   vat_main_t *vam = &vat_main;
6003   u32 worker_id = ntohl (mp->worker_id);
6004
6005   print (vam->ofp,
6006          "\n%-11d %-11s %-6d %-5d %-9s",
6007          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6008          worker_id, ntohl (mp->queue_id),
6009          (mp->mode ==
6010           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6011 }
6012
6013 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6014   (vl_api_sw_interface_rx_placement_details_t * mp)
6015 {
6016   vat_main_t *vam = &vat_main;
6017   vat_json_node_t *node = NULL;
6018
6019   if (VAT_JSON_ARRAY != vam->json_tree.type)
6020     {
6021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6022       vat_json_init_array (&vam->json_tree);
6023     }
6024   node = vat_json_array_add (&vam->json_tree);
6025
6026   vat_json_init_object (node);
6027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6028   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6029   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6030   vat_json_object_add_uint (node, "mode", mp->mode);
6031 }
6032
6033 static int
6034 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6035 {
6036   unformat_input_t *i = vam->input;
6037   vl_api_sw_interface_rx_placement_dump_t *mp;
6038   vl_api_control_ping_t *mp_ping;
6039   int ret;
6040   u32 sw_if_index;
6041   u8 sw_if_index_set = 0;
6042
6043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6044     {
6045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6046         sw_if_index_set++;
6047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6048         sw_if_index_set++;
6049       else
6050         break;
6051     }
6052
6053   print (vam->ofp,
6054          "\n%-11s %-11s %-6s %-5s %-4s",
6055          "sw_if_index", "main/worker", "thread", "queue", "mode");
6056
6057   /* Dump Interface rx placement */
6058   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6059
6060   if (sw_if_index_set)
6061     mp->sw_if_index = htonl (sw_if_index);
6062   else
6063     mp->sw_if_index = ~0;
6064
6065   S (mp);
6066
6067   /* Use a control ping for synchronization */
6068   MPING (CONTROL_PING, mp_ping);
6069   S (mp_ping);
6070
6071   W (ret);
6072   return ret;
6073 }
6074
6075 static int
6076 api_sw_interface_clear_stats (vat_main_t * vam)
6077 {
6078   unformat_input_t *i = vam->input;
6079   vl_api_sw_interface_clear_stats_t *mp;
6080   u32 sw_if_index;
6081   u8 sw_if_index_set = 0;
6082   int ret;
6083
6084   /* Parse args required to build the message */
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6088         sw_if_index_set = 1;
6089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6090         sw_if_index_set = 1;
6091       else
6092         break;
6093     }
6094
6095   /* Construct the API message */
6096   M (SW_INTERFACE_CLEAR_STATS, mp);
6097
6098   if (sw_if_index_set == 1)
6099     mp->sw_if_index = ntohl (sw_if_index);
6100   else
6101     mp->sw_if_index = ~0;
6102
6103   /* send it... */
6104   S (mp);
6105
6106   /* Wait for a reply, return the good/bad news... */
6107   W (ret);
6108   return ret;
6109 }
6110
6111 static int
6112 api_sw_interface_add_del_address (vat_main_t * vam)
6113 {
6114   unformat_input_t *i = vam->input;
6115   vl_api_sw_interface_add_del_address_t *mp;
6116   u32 sw_if_index;
6117   u8 sw_if_index_set = 0;
6118   u8 is_add = 1, del_all = 0;
6119   u32 address_length = 0;
6120   u8 v4_address_set = 0;
6121   u8 v6_address_set = 0;
6122   ip4_address_t v4address;
6123   ip6_address_t v6address;
6124   int ret;
6125
6126   /* Parse args required to build the message */
6127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6128     {
6129       if (unformat (i, "del-all"))
6130         del_all = 1;
6131       else if (unformat (i, "del"))
6132         is_add = 0;
6133       else
6134         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6137         sw_if_index_set = 1;
6138       else if (unformat (i, "%U/%d",
6139                          unformat_ip4_address, &v4address, &address_length))
6140         v4_address_set = 1;
6141       else if (unformat (i, "%U/%d",
6142                          unformat_ip6_address, &v6address, &address_length))
6143         v6_address_set = 1;
6144       else
6145         break;
6146     }
6147
6148   if (sw_if_index_set == 0)
6149     {
6150       errmsg ("missing interface name or sw_if_index");
6151       return -99;
6152     }
6153   if (v4_address_set && v6_address_set)
6154     {
6155       errmsg ("both v4 and v6 addresses set");
6156       return -99;
6157     }
6158   if (!v4_address_set && !v6_address_set && !del_all)
6159     {
6160       errmsg ("no addresses set");
6161       return -99;
6162     }
6163
6164   /* Construct the API message */
6165   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6166
6167   mp->sw_if_index = ntohl (sw_if_index);
6168   mp->is_add = is_add;
6169   mp->del_all = del_all;
6170   if (v6_address_set)
6171     {
6172       mp->prefix.address.af = ADDRESS_IP6;
6173       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6174     }
6175   else
6176     {
6177       mp->prefix.address.af = ADDRESS_IP4;
6178       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6179     }
6180   mp->prefix.len = address_length;
6181
6182   /* send it... */
6183   S (mp);
6184
6185   /* Wait for a reply, return good/bad news  */
6186   W (ret);
6187   return ret;
6188 }
6189
6190 static int
6191 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6192 {
6193   unformat_input_t *i = vam->input;
6194   vl_api_sw_interface_set_mpls_enable_t *mp;
6195   u32 sw_if_index;
6196   u8 sw_if_index_set = 0;
6197   u8 enable = 1;
6198   int ret;
6199
6200   /* Parse args required to build the message */
6201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6202     {
6203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6204         sw_if_index_set = 1;
6205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6206         sw_if_index_set = 1;
6207       else if (unformat (i, "disable"))
6208         enable = 0;
6209       else if (unformat (i, "dis"))
6210         enable = 0;
6211       else
6212         break;
6213     }
6214
6215   if (sw_if_index_set == 0)
6216     {
6217       errmsg ("missing interface name or sw_if_index");
6218       return -99;
6219     }
6220
6221   /* Construct the API message */
6222   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6223
6224   mp->sw_if_index = ntohl (sw_if_index);
6225   mp->enable = enable;
6226
6227   /* send it... */
6228   S (mp);
6229
6230   /* Wait for a reply... */
6231   W (ret);
6232   return ret;
6233 }
6234
6235 static int
6236 api_sw_interface_set_table (vat_main_t * vam)
6237 {
6238   unformat_input_t *i = vam->input;
6239   vl_api_sw_interface_set_table_t *mp;
6240   u32 sw_if_index, vrf_id = 0;
6241   u8 sw_if_index_set = 0;
6242   u8 is_ipv6 = 0;
6243   int ret;
6244
6245   /* Parse args required to build the message */
6246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6247     {
6248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6251         sw_if_index_set = 1;
6252       else if (unformat (i, "vrf %d", &vrf_id))
6253         ;
6254       else if (unformat (i, "ipv6"))
6255         is_ipv6 = 1;
6256       else
6257         break;
6258     }
6259
6260   if (sw_if_index_set == 0)
6261     {
6262       errmsg ("missing interface name or sw_if_index");
6263       return -99;
6264     }
6265
6266   /* Construct the API message */
6267   M (SW_INTERFACE_SET_TABLE, mp);
6268
6269   mp->sw_if_index = ntohl (sw_if_index);
6270   mp->is_ipv6 = is_ipv6;
6271   mp->vrf_id = ntohl (vrf_id);
6272
6273   /* send it... */
6274   S (mp);
6275
6276   /* Wait for a reply... */
6277   W (ret);
6278   return ret;
6279 }
6280
6281 static void vl_api_sw_interface_get_table_reply_t_handler
6282   (vl_api_sw_interface_get_table_reply_t * mp)
6283 {
6284   vat_main_t *vam = &vat_main;
6285
6286   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6287
6288   vam->retval = ntohl (mp->retval);
6289   vam->result_ready = 1;
6290
6291 }
6292
6293 static void vl_api_sw_interface_get_table_reply_t_handler_json
6294   (vl_api_sw_interface_get_table_reply_t * mp)
6295 {
6296   vat_main_t *vam = &vat_main;
6297   vat_json_node_t node;
6298
6299   vat_json_init_object (&node);
6300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6301   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6302
6303   vat_json_print (vam->ofp, &node);
6304   vat_json_free (&node);
6305
6306   vam->retval = ntohl (mp->retval);
6307   vam->result_ready = 1;
6308 }
6309
6310 static int
6311 api_sw_interface_get_table (vat_main_t * vam)
6312 {
6313   unformat_input_t *i = vam->input;
6314   vl_api_sw_interface_get_table_t *mp;
6315   u32 sw_if_index;
6316   u8 sw_if_index_set = 0;
6317   u8 is_ipv6 = 0;
6318   int ret;
6319
6320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6321     {
6322       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6323         sw_if_index_set = 1;
6324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6325         sw_if_index_set = 1;
6326       else if (unformat (i, "ipv6"))
6327         is_ipv6 = 1;
6328       else
6329         break;
6330     }
6331
6332   if (sw_if_index_set == 0)
6333     {
6334       errmsg ("missing interface name or sw_if_index");
6335       return -99;
6336     }
6337
6338   M (SW_INTERFACE_GET_TABLE, mp);
6339   mp->sw_if_index = htonl (sw_if_index);
6340   mp->is_ipv6 = is_ipv6;
6341
6342   S (mp);
6343   W (ret);
6344   return ret;
6345 }
6346
6347 static int
6348 api_sw_interface_set_vpath (vat_main_t * vam)
6349 {
6350   unformat_input_t *i = vam->input;
6351   vl_api_sw_interface_set_vpath_t *mp;
6352   u32 sw_if_index = 0;
6353   u8 sw_if_index_set = 0;
6354   u8 is_enable = 0;
6355   int ret;
6356
6357   /* Parse args required to build the message */
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "enable"))
6365         is_enable = 1;
6366       else if (unformat (i, "disable"))
6367         is_enable = 0;
6368       else
6369         break;
6370     }
6371
6372   if (sw_if_index_set == 0)
6373     {
6374       errmsg ("missing interface name or sw_if_index");
6375       return -99;
6376     }
6377
6378   /* Construct the API message */
6379   M (SW_INTERFACE_SET_VPATH, mp);
6380
6381   mp->sw_if_index = ntohl (sw_if_index);
6382   mp->enable = is_enable;
6383
6384   /* send it... */
6385   S (mp);
6386
6387   /* Wait for a reply... */
6388   W (ret);
6389   return ret;
6390 }
6391
6392 static int
6393 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6394 {
6395   unformat_input_t *i = vam->input;
6396   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6397   u32 sw_if_index = 0;
6398   u8 sw_if_index_set = 0;
6399   u8 is_enable = 1;
6400   u8 is_ipv6 = 0;
6401   int ret;
6402
6403   /* Parse args required to build the message */
6404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6405     {
6406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6409         sw_if_index_set = 1;
6410       else if (unformat (i, "enable"))
6411         is_enable = 1;
6412       else if (unformat (i, "disable"))
6413         is_enable = 0;
6414       else if (unformat (i, "ip4"))
6415         is_ipv6 = 0;
6416       else if (unformat (i, "ip6"))
6417         is_ipv6 = 1;
6418       else
6419         break;
6420     }
6421
6422   if (sw_if_index_set == 0)
6423     {
6424       errmsg ("missing interface name or sw_if_index");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6430
6431   mp->sw_if_index = ntohl (sw_if_index);
6432   mp->enable = is_enable;
6433   mp->is_ipv6 = is_ipv6;
6434
6435   /* send it... */
6436   S (mp);
6437
6438   /* Wait for a reply... */
6439   W (ret);
6440   return ret;
6441 }
6442
6443 static int
6444 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6445 {
6446   unformat_input_t *i = vam->input;
6447   vl_api_sw_interface_set_l2_xconnect_t *mp;
6448   u32 rx_sw_if_index;
6449   u8 rx_sw_if_index_set = 0;
6450   u32 tx_sw_if_index;
6451   u8 tx_sw_if_index_set = 0;
6452   u8 enable = 1;
6453   int ret;
6454
6455   /* Parse args required to build the message */
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6459         rx_sw_if_index_set = 1;
6460       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6461         tx_sw_if_index_set = 1;
6462       else if (unformat (i, "rx"))
6463         {
6464           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6465             {
6466               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6467                             &rx_sw_if_index))
6468                 rx_sw_if_index_set = 1;
6469             }
6470           else
6471             break;
6472         }
6473       else if (unformat (i, "tx"))
6474         {
6475           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6476             {
6477               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6478                             &tx_sw_if_index))
6479                 tx_sw_if_index_set = 1;
6480             }
6481           else
6482             break;
6483         }
6484       else if (unformat (i, "enable"))
6485         enable = 1;
6486       else if (unformat (i, "disable"))
6487         enable = 0;
6488       else
6489         break;
6490     }
6491
6492   if (rx_sw_if_index_set == 0)
6493     {
6494       errmsg ("missing rx interface name or rx_sw_if_index");
6495       return -99;
6496     }
6497
6498   if (enable && (tx_sw_if_index_set == 0))
6499     {
6500       errmsg ("missing tx interface name or tx_sw_if_index");
6501       return -99;
6502     }
6503
6504   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6505
6506   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6507   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6508   mp->enable = enable;
6509
6510   S (mp);
6511   W (ret);
6512   return ret;
6513 }
6514
6515 static int
6516 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6517 {
6518   unformat_input_t *i = vam->input;
6519   vl_api_sw_interface_set_l2_bridge_t *mp;
6520   vl_api_l2_port_type_t port_type;
6521   u32 rx_sw_if_index;
6522   u8 rx_sw_if_index_set = 0;
6523   u32 bd_id;
6524   u8 bd_id_set = 0;
6525   u32 shg = 0;
6526   u8 enable = 1;
6527   int ret;
6528
6529   port_type = L2_API_PORT_TYPE_NORMAL;
6530
6531   /* Parse args required to build the message */
6532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6533     {
6534       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6535         rx_sw_if_index_set = 1;
6536       else if (unformat (i, "bd_id %d", &bd_id))
6537         bd_id_set = 1;
6538       else
6539         if (unformat
6540             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6541         rx_sw_if_index_set = 1;
6542       else if (unformat (i, "shg %d", &shg))
6543         ;
6544       else if (unformat (i, "bvi"))
6545         port_type = L2_API_PORT_TYPE_BVI;
6546       else if (unformat (i, "uu-fwd"))
6547         port_type = L2_API_PORT_TYPE_UU_FWD;
6548       else if (unformat (i, "enable"))
6549         enable = 1;
6550       else if (unformat (i, "disable"))
6551         enable = 0;
6552       else
6553         break;
6554     }
6555
6556   if (rx_sw_if_index_set == 0)
6557     {
6558       errmsg ("missing rx interface name or sw_if_index");
6559       return -99;
6560     }
6561
6562   if (enable && (bd_id_set == 0))
6563     {
6564       errmsg ("missing bridge domain");
6565       return -99;
6566     }
6567
6568   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6569
6570   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6571   mp->bd_id = ntohl (bd_id);
6572   mp->shg = (u8) shg;
6573   mp->port_type = ntohl (port_type);
6574   mp->enable = enable;
6575
6576   S (mp);
6577   W (ret);
6578   return ret;
6579 }
6580
6581 static int
6582 api_bridge_domain_dump (vat_main_t * vam)
6583 {
6584   unformat_input_t *i = vam->input;
6585   vl_api_bridge_domain_dump_t *mp;
6586   vl_api_control_ping_t *mp_ping;
6587   u32 bd_id = ~0;
6588   int ret;
6589
6590   /* Parse args required to build the message */
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "bd_id %d", &bd_id))
6594         ;
6595       else
6596         break;
6597     }
6598
6599   M (BRIDGE_DOMAIN_DUMP, mp);
6600   mp->bd_id = ntohl (bd_id);
6601   S (mp);
6602
6603   /* Use a control ping for synchronization */
6604   MPING (CONTROL_PING, mp_ping);
6605   S (mp_ping);
6606
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_bridge_domain_add_del (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_bridge_domain_add_del_t *mp;
6616   u32 bd_id = ~0;
6617   u8 is_add = 1;
6618   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6619   u8 *bd_tag = NULL;
6620   u32 mac_age = 0;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "bd_id %d", &bd_id))
6627         ;
6628       else if (unformat (i, "flood %d", &flood))
6629         ;
6630       else if (unformat (i, "uu-flood %d", &uu_flood))
6631         ;
6632       else if (unformat (i, "forward %d", &forward))
6633         ;
6634       else if (unformat (i, "learn %d", &learn))
6635         ;
6636       else if (unformat (i, "arp-term %d", &arp_term))
6637         ;
6638       else if (unformat (i, "mac-age %d", &mac_age))
6639         ;
6640       else if (unformat (i, "bd-tag %s", &bd_tag))
6641         ;
6642       else if (unformat (i, "del"))
6643         {
6644           is_add = 0;
6645           flood = uu_flood = forward = learn = 0;
6646         }
6647       else
6648         break;
6649     }
6650
6651   if (bd_id == ~0)
6652     {
6653       errmsg ("missing bridge domain");
6654       ret = -99;
6655       goto done;
6656     }
6657
6658   if (mac_age > 255)
6659     {
6660       errmsg ("mac age must be less than 256 ");
6661       ret = -99;
6662       goto done;
6663     }
6664
6665   if ((bd_tag) && (vec_len (bd_tag) > 63))
6666     {
6667       errmsg ("bd-tag cannot be longer than 63");
6668       ret = -99;
6669       goto done;
6670     }
6671
6672   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6673
6674   mp->bd_id = ntohl (bd_id);
6675   mp->flood = flood;
6676   mp->uu_flood = uu_flood;
6677   mp->forward = forward;
6678   mp->learn = learn;
6679   mp->arp_term = arp_term;
6680   mp->is_add = is_add;
6681   mp->mac_age = (u8) mac_age;
6682   if (bd_tag)
6683     {
6684       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6685       mp->bd_tag[vec_len (bd_tag)] = 0;
6686     }
6687   S (mp);
6688   W (ret);
6689
6690 done:
6691   vec_free (bd_tag);
6692   return ret;
6693 }
6694
6695 static int
6696 api_l2fib_flush_bd (vat_main_t * vam)
6697 {
6698   unformat_input_t *i = vam->input;
6699   vl_api_l2fib_flush_bd_t *mp;
6700   u32 bd_id = ~0;
6701   int ret;
6702
6703   /* Parse args required to build the message */
6704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6705     {
6706       if (unformat (i, "bd_id %d", &bd_id));
6707       else
6708         break;
6709     }
6710
6711   if (bd_id == ~0)
6712     {
6713       errmsg ("missing bridge domain");
6714       return -99;
6715     }
6716
6717   M (L2FIB_FLUSH_BD, mp);
6718
6719   mp->bd_id = htonl (bd_id);
6720
6721   S (mp);
6722   W (ret);
6723   return ret;
6724 }
6725
6726 static int
6727 api_l2fib_flush_int (vat_main_t * vam)
6728 {
6729   unformat_input_t *i = vam->input;
6730   vl_api_l2fib_flush_int_t *mp;
6731   u32 sw_if_index = ~0;
6732   int ret;
6733
6734   /* Parse args required to build the message */
6735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736     {
6737       if (unformat (i, "sw_if_index %d", &sw_if_index));
6738       else
6739         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6740       else
6741         break;
6742     }
6743
6744   if (sw_if_index == ~0)
6745     {
6746       errmsg ("missing interface name or sw_if_index");
6747       return -99;
6748     }
6749
6750   M (L2FIB_FLUSH_INT, mp);
6751
6752   mp->sw_if_index = ntohl (sw_if_index);
6753
6754   S (mp);
6755   W (ret);
6756   return ret;
6757 }
6758
6759 static int
6760 api_l2fib_add_del (vat_main_t * vam)
6761 {
6762   unformat_input_t *i = vam->input;
6763   vl_api_l2fib_add_del_t *mp;
6764   f64 timeout;
6765   u8 mac[6] = { 0 };
6766   u8 mac_set = 0;
6767   u32 bd_id;
6768   u8 bd_id_set = 0;
6769   u32 sw_if_index = 0;
6770   u8 sw_if_index_set = 0;
6771   u8 is_add = 1;
6772   u8 static_mac = 0;
6773   u8 filter_mac = 0;
6774   u8 bvi_mac = 0;
6775   int count = 1;
6776   f64 before = 0;
6777   int j;
6778
6779   /* Parse args required to build the message */
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6783         mac_set = 1;
6784       else if (unformat (i, "bd_id %d", &bd_id))
6785         bd_id_set = 1;
6786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6787         sw_if_index_set = 1;
6788       else if (unformat (i, "sw_if"))
6789         {
6790           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6791             {
6792               if (unformat
6793                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6794                 sw_if_index_set = 1;
6795             }
6796           else
6797             break;
6798         }
6799       else if (unformat (i, "static"))
6800         static_mac = 1;
6801       else if (unformat (i, "filter"))
6802         {
6803           filter_mac = 1;
6804           static_mac = 1;
6805         }
6806       else if (unformat (i, "bvi"))
6807         {
6808           bvi_mac = 1;
6809           static_mac = 1;
6810         }
6811       else if (unformat (i, "del"))
6812         is_add = 0;
6813       else if (unformat (i, "count %d", &count))
6814         ;
6815       else
6816         break;
6817     }
6818
6819   if (mac_set == 0)
6820     {
6821       errmsg ("missing mac address");
6822       return -99;
6823     }
6824
6825   if (bd_id_set == 0)
6826     {
6827       errmsg ("missing bridge domain");
6828       return -99;
6829     }
6830
6831   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6832     {
6833       errmsg ("missing interface name or sw_if_index");
6834       return -99;
6835     }
6836
6837   if (count > 1)
6838     {
6839       /* Turn on async mode */
6840       vam->async_mode = 1;
6841       vam->async_errors = 0;
6842       before = vat_time_now (vam);
6843     }
6844
6845   for (j = 0; j < count; j++)
6846     {
6847       M (L2FIB_ADD_DEL, mp);
6848
6849       clib_memcpy (mp->mac, mac, 6);
6850       mp->bd_id = ntohl (bd_id);
6851       mp->is_add = is_add;
6852       mp->sw_if_index = ntohl (sw_if_index);
6853
6854       if (is_add)
6855         {
6856           mp->static_mac = static_mac;
6857           mp->filter_mac = filter_mac;
6858           mp->bvi_mac = bvi_mac;
6859         }
6860       increment_mac_address (mac);
6861       /* send it... */
6862       S (mp);
6863     }
6864
6865   if (count > 1)
6866     {
6867       vl_api_control_ping_t *mp_ping;
6868       f64 after;
6869
6870       /* Shut off async mode */
6871       vam->async_mode = 0;
6872
6873       MPING (CONTROL_PING, mp_ping);
6874       S (mp_ping);
6875
6876       timeout = vat_time_now (vam) + 1.0;
6877       while (vat_time_now (vam) < timeout)
6878         if (vam->result_ready == 1)
6879           goto out;
6880       vam->retval = -99;
6881
6882     out:
6883       if (vam->retval == -99)
6884         errmsg ("timeout");
6885
6886       if (vam->async_errors > 0)
6887         {
6888           errmsg ("%d asynchronous errors", vam->async_errors);
6889           vam->retval = -98;
6890         }
6891       vam->async_errors = 0;
6892       after = vat_time_now (vam);
6893
6894       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6895              count, after - before, count / (after - before));
6896     }
6897   else
6898     {
6899       int ret;
6900
6901       /* Wait for a reply... */
6902       W (ret);
6903       return ret;
6904     }
6905   /* Return the good/bad news */
6906   return (vam->retval);
6907 }
6908
6909 static int
6910 api_bridge_domain_set_mac_age (vat_main_t * vam)
6911 {
6912   unformat_input_t *i = vam->input;
6913   vl_api_bridge_domain_set_mac_age_t *mp;
6914   u32 bd_id = ~0;
6915   u32 mac_age = 0;
6916   int ret;
6917
6918   /* Parse args required to build the message */
6919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6920     {
6921       if (unformat (i, "bd_id %d", &bd_id));
6922       else if (unformat (i, "mac-age %d", &mac_age));
6923       else
6924         break;
6925     }
6926
6927   if (bd_id == ~0)
6928     {
6929       errmsg ("missing bridge domain");
6930       return -99;
6931     }
6932
6933   if (mac_age > 255)
6934     {
6935       errmsg ("mac age must be less than 256 ");
6936       return -99;
6937     }
6938
6939   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6940
6941   mp->bd_id = htonl (bd_id);
6942   mp->mac_age = (u8) mac_age;
6943
6944   S (mp);
6945   W (ret);
6946   return ret;
6947 }
6948
6949 static int
6950 api_l2_flags (vat_main_t * vam)
6951 {
6952   unformat_input_t *i = vam->input;
6953   vl_api_l2_flags_t *mp;
6954   u32 sw_if_index;
6955   u32 flags = 0;
6956   u8 sw_if_index_set = 0;
6957   u8 is_set = 0;
6958   int ret;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "sw_if_index %d", &sw_if_index))
6964         sw_if_index_set = 1;
6965       else if (unformat (i, "sw_if"))
6966         {
6967           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968             {
6969               if (unformat
6970                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6971                 sw_if_index_set = 1;
6972             }
6973           else
6974             break;
6975         }
6976       else if (unformat (i, "learn"))
6977         flags |= L2_LEARN;
6978       else if (unformat (i, "forward"))
6979         flags |= L2_FWD;
6980       else if (unformat (i, "flood"))
6981         flags |= L2_FLOOD;
6982       else if (unformat (i, "uu-flood"))
6983         flags |= L2_UU_FLOOD;
6984       else if (unformat (i, "arp-term"))
6985         flags |= L2_ARP_TERM;
6986       else if (unformat (i, "off"))
6987         is_set = 0;
6988       else if (unformat (i, "disable"))
6989         is_set = 0;
6990       else
6991         break;
6992     }
6993
6994   if (sw_if_index_set == 0)
6995     {
6996       errmsg ("missing interface name or sw_if_index");
6997       return -99;
6998     }
6999
7000   M (L2_FLAGS, mp);
7001
7002   mp->sw_if_index = ntohl (sw_if_index);
7003   mp->feature_bitmap = ntohl (flags);
7004   mp->is_set = is_set;
7005
7006   S (mp);
7007   W (ret);
7008   return ret;
7009 }
7010
7011 static int
7012 api_bridge_flags (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_bridge_flags_t *mp;
7016   u32 bd_id;
7017   u8 bd_id_set = 0;
7018   u8 is_set = 1;
7019   bd_flags_t flags = 0;
7020   int ret;
7021
7022   /* Parse args required to build the message */
7023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7024     {
7025       if (unformat (i, "bd_id %d", &bd_id))
7026         bd_id_set = 1;
7027       else if (unformat (i, "learn"))
7028         flags |= BRIDGE_API_FLAG_LEARN;
7029       else if (unformat (i, "forward"))
7030         flags |= BRIDGE_API_FLAG_FWD;
7031       else if (unformat (i, "flood"))
7032         flags |= BRIDGE_API_FLAG_FLOOD;
7033       else if (unformat (i, "uu-flood"))
7034         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7035       else if (unformat (i, "arp-term"))
7036         flags |= BRIDGE_API_FLAG_ARP_TERM;
7037       else if (unformat (i, "off"))
7038         is_set = 0;
7039       else if (unformat (i, "disable"))
7040         is_set = 0;
7041       else
7042         break;
7043     }
7044
7045   if (bd_id_set == 0)
7046     {
7047       errmsg ("missing bridge domain");
7048       return -99;
7049     }
7050
7051   M (BRIDGE_FLAGS, mp);
7052
7053   mp->bd_id = ntohl (bd_id);
7054   mp->flags = ntohl (flags);
7055   mp->is_set = is_set;
7056
7057   S (mp);
7058   W (ret);
7059   return ret;
7060 }
7061
7062 static int
7063 api_bd_ip_mac_add_del (vat_main_t * vam)
7064 {
7065   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7066   vl_api_mac_address_t mac = { 0 };
7067   unformat_input_t *i = vam->input;
7068   vl_api_bd_ip_mac_add_del_t *mp;
7069   u32 bd_id;
7070   u8 is_add = 1;
7071   u8 bd_id_set = 0;
7072   u8 ip_set = 0;
7073   u8 mac_set = 0;
7074   int ret;
7075
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         {
7082           bd_id_set++;
7083         }
7084       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7085         {
7086           ip_set++;
7087         }
7088       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7089         {
7090           mac_set++;
7091         }
7092       else if (unformat (i, "del"))
7093         is_add = 0;
7094       else
7095         break;
7096     }
7097
7098   if (bd_id_set == 0)
7099     {
7100       errmsg ("missing bridge domain");
7101       return -99;
7102     }
7103   else if (ip_set == 0)
7104     {
7105       errmsg ("missing IP address");
7106       return -99;
7107     }
7108   else if (mac_set == 0)
7109     {
7110       errmsg ("missing MAC address");
7111       return -99;
7112     }
7113
7114   M (BD_IP_MAC_ADD_DEL, mp);
7115
7116   mp->entry.bd_id = ntohl (bd_id);
7117   mp->is_add = is_add;
7118
7119   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7120   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7121
7122   S (mp);
7123   W (ret);
7124   return ret;
7125 }
7126
7127 static int
7128 api_bd_ip_mac_flush (vat_main_t * vam)
7129 {
7130   unformat_input_t *i = vam->input;
7131   vl_api_bd_ip_mac_flush_t *mp;
7132   u32 bd_id;
7133   u8 bd_id_set = 0;
7134   int ret;
7135
7136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7137     {
7138       if (unformat (i, "bd_id %d", &bd_id))
7139         {
7140           bd_id_set++;
7141         }
7142       else
7143         break;
7144     }
7145
7146   if (bd_id_set == 0)
7147     {
7148       errmsg ("missing bridge domain");
7149       return -99;
7150     }
7151
7152   M (BD_IP_MAC_FLUSH, mp);
7153
7154   mp->bd_id = ntohl (bd_id);
7155
7156   S (mp);
7157   W (ret);
7158   return ret;
7159 }
7160
7161 static void vl_api_bd_ip_mac_details_t_handler
7162   (vl_api_bd_ip_mac_details_t * mp)
7163 {
7164   vat_main_t *vam = &vat_main;
7165
7166   print (vam->ofp,
7167          "\n%-5d %U %U",
7168          ntohl (mp->entry.bd_id),
7169          format_vl_api_mac_address, mp->entry.mac,
7170          format_vl_api_address, &mp->entry.ip);
7171 }
7172
7173 static void vl_api_bd_ip_mac_details_t_handler_json
7174   (vl_api_bd_ip_mac_details_t * mp)
7175 {
7176   vat_main_t *vam = &vat_main;
7177   vat_json_node_t *node = NULL;
7178
7179   if (VAT_JSON_ARRAY != vam->json_tree.type)
7180     {
7181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7182       vat_json_init_array (&vam->json_tree);
7183     }
7184   node = vat_json_array_add (&vam->json_tree);
7185
7186   vat_json_init_object (node);
7187   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7188   vat_json_object_add_string_copy (node, "mac_address",
7189                                    format (0, "%U", format_vl_api_mac_address,
7190                                            &mp->entry.mac));
7191   u8 *ip = 0;
7192
7193   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7194   vat_json_object_add_string_copy (node, "ip_address", ip);
7195   vec_free (ip);
7196 }
7197
7198 static int
7199 api_bd_ip_mac_dump (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_bd_ip_mac_dump_t *mp;
7203   vl_api_control_ping_t *mp_ping;
7204   int ret;
7205   u32 bd_id;
7206   u8 bd_id_set = 0;
7207
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "bd_id %d", &bd_id))
7211         {
7212           bd_id_set++;
7213         }
7214       else
7215         break;
7216     }
7217
7218   print (vam->ofp,
7219          "\n%-5s %-7s %-20s %-30s",
7220          "bd_id", "is_ipv6", "mac_address", "ip_address");
7221
7222   /* Dump Bridge Domain Ip to Mac entries */
7223   M (BD_IP_MAC_DUMP, mp);
7224
7225   if (bd_id_set)
7226     mp->bd_id = htonl (bd_id);
7227   else
7228     mp->bd_id = ~0;
7229
7230   S (mp);
7231
7232   /* Use a control ping for synchronization */
7233   MPING (CONTROL_PING, mp_ping);
7234   S (mp_ping);
7235
7236   W (ret);
7237   return ret;
7238 }
7239
7240 static int
7241 api_tap_create_v2 (vat_main_t * vam)
7242 {
7243   unformat_input_t *i = vam->input;
7244   vl_api_tap_create_v2_t *mp;
7245   u8 mac_address[6];
7246   u8 random_mac = 1;
7247   u32 id = ~0;
7248   u32 num_rx_queues = 0;
7249   u8 *host_if_name = 0;
7250   u8 host_if_name_set = 0;
7251   u8 *host_ns = 0;
7252   u8 host_ns_set = 0;
7253   u8 host_mac_addr[6];
7254   u8 host_mac_addr_set = 0;
7255   u8 *host_bridge = 0;
7256   u8 host_bridge_set = 0;
7257   u8 host_ip4_prefix_set = 0;
7258   u8 host_ip6_prefix_set = 0;
7259   ip4_address_t host_ip4_addr;
7260   ip4_address_t host_ip4_gw;
7261   u8 host_ip4_gw_set = 0;
7262   u32 host_ip4_prefix_len = 0;
7263   ip6_address_t host_ip6_addr;
7264   ip6_address_t host_ip6_gw;
7265   u8 host_ip6_gw_set = 0;
7266   u32 host_ip6_prefix_len = 0;
7267   u32 host_mtu_size = 0;
7268   u8 host_mtu_set = 0;
7269   u32 tap_flags = 0;
7270   int ret;
7271   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7272
7273   clib_memset (mac_address, 0, sizeof (mac_address));
7274
7275   /* Parse args required to build the message */
7276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7277     {
7278       if (unformat (i, "id %u", &id))
7279         ;
7280       else
7281         if (unformat
7282             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7283         random_mac = 0;
7284       else if (unformat (i, "host-if-name %s", &host_if_name))
7285         host_if_name_set = 1;
7286       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7287         ;
7288       else if (unformat (i, "host-ns %s", &host_ns))
7289         host_ns_set = 1;
7290       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7291                          host_mac_addr))
7292         host_mac_addr_set = 1;
7293       else if (unformat (i, "host-bridge %s", &host_bridge))
7294         host_bridge_set = 1;
7295       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7296                          &host_ip4_addr, &host_ip4_prefix_len))
7297         host_ip4_prefix_set = 1;
7298       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7299                          &host_ip6_addr, &host_ip6_prefix_len))
7300         host_ip6_prefix_set = 1;
7301       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7302                          &host_ip4_gw))
7303         host_ip4_gw_set = 1;
7304       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7305                          &host_ip6_gw))
7306         host_ip6_gw_set = 1;
7307       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7308         ;
7309       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7310         ;
7311       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7312         host_mtu_set = 1;
7313       else if (unformat (i, "no-gso"))
7314         tap_flags &= ~TAP_API_FLAG_GSO;
7315       else if (unformat (i, "gso"))
7316         tap_flags |= TAP_API_FLAG_GSO;
7317       else if (unformat (i, "csum-offload"))
7318         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7319       else if (unformat (i, "persist"))
7320         tap_flags |= TAP_API_FLAG_PERSIST;
7321       else if (unformat (i, "attach"))
7322         tap_flags |= TAP_API_FLAG_ATTACH;
7323       else if (unformat (i, "tun"))
7324         tap_flags |= TAP_API_FLAG_TUN;
7325       else if (unformat (i, "gro-coalesce"))
7326         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7327       else if (unformat (i, "packed"))
7328         tap_flags |= TAP_API_FLAG_PACKED;
7329       else if (unformat (i, "in-order"))
7330         tap_flags |= TAP_API_FLAG_IN_ORDER;
7331       else
7332         break;
7333     }
7334
7335   if (vec_len (host_if_name) > 63)
7336     {
7337       errmsg ("tap name too long. ");
7338       return -99;
7339     }
7340   if (vec_len (host_ns) > 63)
7341     {
7342       errmsg ("host name space too long. ");
7343       return -99;
7344     }
7345   if (vec_len (host_bridge) > 63)
7346     {
7347       errmsg ("host bridge name too long. ");
7348       return -99;
7349     }
7350   if (host_ip4_prefix_len > 32)
7351     {
7352       errmsg ("host ip4 prefix length not valid. ");
7353       return -99;
7354     }
7355   if (host_ip6_prefix_len > 128)
7356     {
7357       errmsg ("host ip6 prefix length not valid. ");
7358       return -99;
7359     }
7360   if (!is_pow2 (rx_ring_sz))
7361     {
7362       errmsg ("rx ring size must be power of 2. ");
7363       return -99;
7364     }
7365   if (rx_ring_sz > 32768)
7366     {
7367       errmsg ("rx ring size must be 32768 or lower. ");
7368       return -99;
7369     }
7370   if (!is_pow2 (tx_ring_sz))
7371     {
7372       errmsg ("tx ring size must be power of 2. ");
7373       return -99;
7374     }
7375   if (tx_ring_sz > 32768)
7376     {
7377       errmsg ("tx ring size must be 32768 or lower. ");
7378       return -99;
7379     }
7380   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7381     {
7382       errmsg ("host MTU size must be in between 64 and 65355. ");
7383       return -99;
7384     }
7385
7386   /* Construct the API message */
7387   M (TAP_CREATE_V2, mp);
7388
7389   mp->id = ntohl (id);
7390   mp->use_random_mac = random_mac;
7391   mp->num_rx_queues = (u8) num_rx_queues;
7392   mp->tx_ring_sz = ntohs (tx_ring_sz);
7393   mp->rx_ring_sz = ntohs (rx_ring_sz);
7394   mp->host_mtu_set = host_mtu_set;
7395   mp->host_mtu_size = ntohl (host_mtu_size);
7396   mp->host_mac_addr_set = host_mac_addr_set;
7397   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7398   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7399   mp->host_ip4_gw_set = host_ip4_gw_set;
7400   mp->host_ip6_gw_set = host_ip6_gw_set;
7401   mp->tap_flags = ntohl (tap_flags);
7402   mp->host_namespace_set = host_ns_set;
7403   mp->host_if_name_set = host_if_name_set;
7404   mp->host_bridge_set = host_bridge_set;
7405
7406   if (random_mac == 0)
7407     clib_memcpy (mp->mac_address, mac_address, 6);
7408   if (host_mac_addr_set)
7409     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7410   if (host_if_name_set)
7411     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7412   if (host_ns_set)
7413     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7414   if (host_bridge_set)
7415     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7416   if (host_ip4_prefix_set)
7417     {
7418       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7419       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7420     }
7421   if (host_ip6_prefix_set)
7422     {
7423       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7424       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7425     }
7426   if (host_ip4_gw_set)
7427     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7428   if (host_ip6_gw_set)
7429     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7430
7431   vec_free (host_ns);
7432   vec_free (host_if_name);
7433   vec_free (host_bridge);
7434
7435   /* send it... */
7436   S (mp);
7437
7438   /* Wait for a reply... */
7439   W (ret);
7440   return ret;
7441 }
7442
7443 static int
7444 api_tap_delete_v2 (vat_main_t * vam)
7445 {
7446   unformat_input_t *i = vam->input;
7447   vl_api_tap_delete_v2_t *mp;
7448   u32 sw_if_index = ~0;
7449   u8 sw_if_index_set = 0;
7450   int ret;
7451
7452   /* Parse args required to build the message */
7453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7454     {
7455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7456         sw_if_index_set = 1;
7457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7458         sw_if_index_set = 1;
7459       else
7460         break;
7461     }
7462
7463   if (sw_if_index_set == 0)
7464     {
7465       errmsg ("missing vpp interface name. ");
7466       return -99;
7467     }
7468
7469   /* Construct the API message */
7470   M (TAP_DELETE_V2, mp);
7471
7472   mp->sw_if_index = ntohl (sw_if_index);
7473
7474   /* send it... */
7475   S (mp);
7476
7477   /* Wait for a reply... */
7478   W (ret);
7479   return ret;
7480 }
7481
7482 uword
7483 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7484 {
7485   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7486   u32 x[4];
7487
7488   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7489     return 0;
7490
7491   addr->domain = x[0];
7492   addr->bus = x[1];
7493   addr->slot = x[2];
7494   addr->function = x[3];
7495
7496   return 1;
7497 }
7498
7499 static int
7500 api_virtio_pci_create_v2 (vat_main_t * vam)
7501 {
7502   unformat_input_t *i = vam->input;
7503   vl_api_virtio_pci_create_v2_t *mp;
7504   u8 mac_address[6];
7505   u8 random_mac = 1;
7506   u32 pci_addr = 0;
7507   u64 features = (u64) ~ (0ULL);
7508   u32 virtio_flags = 0;
7509   int ret;
7510
7511   clib_memset (mac_address, 0, sizeof (mac_address));
7512
7513   /* Parse args required to build the message */
7514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7515     {
7516       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7517         {
7518           random_mac = 0;
7519         }
7520       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7521         ;
7522       else if (unformat (i, "features 0x%llx", &features))
7523         ;
7524       else if (unformat (i, "gso-enabled"))
7525         virtio_flags |= VIRTIO_API_FLAG_GSO;
7526       else if (unformat (i, "csum-offload-enabled"))
7527         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
7528       else if (unformat (i, "gro-coalesce"))
7529         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
7530       else if (unformat (i, "packed"))
7531         virtio_flags |= VIRTIO_API_FLAG_PACKED;
7532       else if (unformat (i, "in-order"))
7533         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
7534       else
7535         break;
7536     }
7537
7538   if (pci_addr == 0)
7539     {
7540       errmsg ("pci address must be non zero. ");
7541       return -99;
7542     }
7543
7544   /* Construct the API message */
7545   M (VIRTIO_PCI_CREATE_V2, mp);
7546
7547   mp->use_random_mac = random_mac;
7548
7549   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7550   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7551   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7552   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7553
7554   mp->features = clib_host_to_net_u64 (features);
7555   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
7556
7557   if (random_mac == 0)
7558     clib_memcpy (mp->mac_address, mac_address, 6);
7559
7560   /* send it... */
7561   S (mp);
7562
7563   /* Wait for a reply... */
7564   W (ret);
7565   return ret;
7566 }
7567
7568 static int
7569 api_virtio_pci_delete (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_virtio_pci_delete_t *mp;
7573   u32 sw_if_index = ~0;
7574   u8 sw_if_index_set = 0;
7575   int ret;
7576
7577   /* Parse args required to build the message */
7578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7579     {
7580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7581         sw_if_index_set = 1;
7582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7583         sw_if_index_set = 1;
7584       else
7585         break;
7586     }
7587
7588   if (sw_if_index_set == 0)
7589     {
7590       errmsg ("missing vpp interface name. ");
7591       return -99;
7592     }
7593
7594   /* Construct the API message */
7595   M (VIRTIO_PCI_DELETE, mp);
7596
7597   mp->sw_if_index = htonl (sw_if_index);
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_bond_create (vat_main_t * vam)
7609 {
7610   unformat_input_t *i = vam->input;
7611   vl_api_bond_create_t *mp;
7612   u8 mac_address[6];
7613   u8 custom_mac = 0;
7614   int ret;
7615   u8 mode;
7616   u8 lb;
7617   u8 mode_is_set = 0;
7618   u32 id = ~0;
7619   u8 numa_only = 0;
7620
7621   clib_memset (mac_address, 0, sizeof (mac_address));
7622   lb = BOND_LB_L2;
7623
7624   /* Parse args required to build the message */
7625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7626     {
7627       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7628         mode_is_set = 1;
7629       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7630                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7631         ;
7632       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7633                          mac_address))
7634         custom_mac = 1;
7635       else if (unformat (i, "numa-only"))
7636         numa_only = 1;
7637       else if (unformat (i, "id %u", &id))
7638         ;
7639       else
7640         break;
7641     }
7642
7643   if (mode_is_set == 0)
7644     {
7645       errmsg ("Missing bond mode. ");
7646       return -99;
7647     }
7648
7649   /* Construct the API message */
7650   M (BOND_CREATE, mp);
7651
7652   mp->use_custom_mac = custom_mac;
7653
7654   mp->mode = htonl (mode);
7655   mp->lb = htonl (lb);
7656   mp->id = htonl (id);
7657   mp->numa_only = numa_only;
7658
7659   if (custom_mac)
7660     clib_memcpy (mp->mac_address, mac_address, 6);
7661
7662   /* send it... */
7663   S (mp);
7664
7665   /* Wait for a reply... */
7666   W (ret);
7667   return ret;
7668 }
7669
7670 static int
7671 api_bond_create2 (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_bond_create2_t *mp;
7675   u8 mac_address[6];
7676   u8 custom_mac = 0;
7677   int ret;
7678   u8 mode;
7679   u8 lb;
7680   u8 mode_is_set = 0;
7681   u32 id = ~0;
7682   u8 numa_only = 0;
7683   u8 gso = 0;
7684
7685   clib_memset (mac_address, 0, sizeof (mac_address));
7686   lb = BOND_LB_L2;
7687
7688   /* Parse args required to build the message */
7689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7690     {
7691       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7692         mode_is_set = 1;
7693       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7694                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7695         ;
7696       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7697                          mac_address))
7698         custom_mac = 1;
7699       else if (unformat (i, "numa-only"))
7700         numa_only = 1;
7701       else if (unformat (i, "gso"))
7702         gso = 1;
7703       else if (unformat (i, "id %u", &id))
7704         ;
7705       else
7706         break;
7707     }
7708
7709   if (mode_is_set == 0)
7710     {
7711       errmsg ("Missing bond mode. ");
7712       return -99;
7713     }
7714
7715   /* Construct the API message */
7716   M (BOND_CREATE2, mp);
7717
7718   mp->use_custom_mac = custom_mac;
7719
7720   mp->mode = htonl (mode);
7721   mp->lb = htonl (lb);
7722   mp->id = htonl (id);
7723   mp->numa_only = numa_only;
7724   mp->enable_gso = gso;
7725
7726   if (custom_mac)
7727     clib_memcpy (mp->mac_address, mac_address, 6);
7728
7729   /* send it... */
7730   S (mp);
7731
7732   /* Wait for a reply... */
7733   W (ret);
7734   return ret;
7735 }
7736
7737 static int
7738 api_bond_delete (vat_main_t * vam)
7739 {
7740   unformat_input_t *i = vam->input;
7741   vl_api_bond_delete_t *mp;
7742   u32 sw_if_index = ~0;
7743   u8 sw_if_index_set = 0;
7744   int ret;
7745
7746   /* Parse args required to build the message */
7747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7748     {
7749       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7750         sw_if_index_set = 1;
7751       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7752         sw_if_index_set = 1;
7753       else
7754         break;
7755     }
7756
7757   if (sw_if_index_set == 0)
7758     {
7759       errmsg ("missing vpp interface name. ");
7760       return -99;
7761     }
7762
7763   /* Construct the API message */
7764   M (BOND_DELETE, mp);
7765
7766   mp->sw_if_index = ntohl (sw_if_index);
7767
7768   /* send it... */
7769   S (mp);
7770
7771   /* Wait for a reply... */
7772   W (ret);
7773   return ret;
7774 }
7775
7776 static int
7777 api_bond_add_member (vat_main_t * vam)
7778 {
7779   unformat_input_t *i = vam->input;
7780   vl_api_bond_add_member_t *mp;
7781   u32 bond_sw_if_index;
7782   int ret;
7783   u8 is_passive;
7784   u8 is_long_timeout;
7785   u32 bond_sw_if_index_is_set = 0;
7786   u32 sw_if_index;
7787   u8 sw_if_index_is_set = 0;
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "sw_if_index %d", &sw_if_index))
7793         sw_if_index_is_set = 1;
7794       else if (unformat (i, "bond %u", &bond_sw_if_index))
7795         bond_sw_if_index_is_set = 1;
7796       else if (unformat (i, "passive %d", &is_passive))
7797         ;
7798       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7799         ;
7800       else
7801         break;
7802     }
7803
7804   if (bond_sw_if_index_is_set == 0)
7805     {
7806       errmsg ("Missing bond sw_if_index. ");
7807       return -99;
7808     }
7809   if (sw_if_index_is_set == 0)
7810     {
7811       errmsg ("Missing member sw_if_index. ");
7812       return -99;
7813     }
7814
7815   /* Construct the API message */
7816   M (BOND_ADD_MEMBER, mp);
7817
7818   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7819   mp->sw_if_index = ntohl (sw_if_index);
7820   mp->is_long_timeout = is_long_timeout;
7821   mp->is_passive = is_passive;
7822
7823   /* send it... */
7824   S (mp);
7825
7826   /* Wait for a reply... */
7827   W (ret);
7828   return ret;
7829 }
7830
7831 static int
7832 api_bond_detach_member (vat_main_t * vam)
7833 {
7834   unformat_input_t *i = vam->input;
7835   vl_api_bond_detach_member_t *mp;
7836   u32 sw_if_index = ~0;
7837   u8 sw_if_index_set = 0;
7838   int ret;
7839
7840   /* Parse args required to build the message */
7841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7842     {
7843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7844         sw_if_index_set = 1;
7845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7846         sw_if_index_set = 1;
7847       else
7848         break;
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing vpp interface name. ");
7854       return -99;
7855     }
7856
7857   /* Construct the API message */
7858   M (BOND_DETACH_MEMBER, mp);
7859
7860   mp->sw_if_index = ntohl (sw_if_index);
7861
7862   /* send it... */
7863   S (mp);
7864
7865   /* Wait for a reply... */
7866   W (ret);
7867   return ret;
7868 }
7869
7870 static int
7871 api_ip_table_add_del (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_ip_table_add_del_t *mp;
7875   u32 table_id = ~0;
7876   u8 is_ipv6 = 0;
7877   u8 is_add = 1;
7878   int ret = 0;
7879
7880   /* Parse args required to build the message */
7881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7882     {
7883       if (unformat (i, "ipv6"))
7884         is_ipv6 = 1;
7885       else if (unformat (i, "del"))
7886         is_add = 0;
7887       else if (unformat (i, "add"))
7888         is_add = 1;
7889       else if (unformat (i, "table %d", &table_id))
7890         ;
7891       else
7892         {
7893           clib_warning ("parse error '%U'", format_unformat_error, i);
7894           return -99;
7895         }
7896     }
7897
7898   if (~0 == table_id)
7899     {
7900       errmsg ("missing table-ID");
7901       return -99;
7902     }
7903
7904   /* Construct the API message */
7905   M (IP_TABLE_ADD_DEL, mp);
7906
7907   mp->table.table_id = ntohl (table_id);
7908   mp->table.is_ip6 = is_ipv6;
7909   mp->is_add = is_add;
7910
7911   /* send it... */
7912   S (mp);
7913
7914   /* Wait for a reply... */
7915   W (ret);
7916
7917   return ret;
7918 }
7919
7920 uword
7921 unformat_fib_path (unformat_input_t * input, va_list * args)
7922 {
7923   vat_main_t *vam = va_arg (*args, vat_main_t *);
7924   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7925   u32 weight, preference;
7926   mpls_label_t out_label;
7927
7928   clib_memset (path, 0, sizeof (*path));
7929   path->weight = 1;
7930   path->sw_if_index = ~0;
7931   path->rpf_id = ~0;
7932   path->n_labels = 0;
7933
7934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (input, "%U %U",
7937                     unformat_vl_api_ip4_address,
7938                     &path->nh.address.ip4,
7939                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7940         {
7941           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7942         }
7943       else if (unformat (input, "%U %U",
7944                          unformat_vl_api_ip6_address,
7945                          &path->nh.address.ip6,
7946                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7947         {
7948           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7949         }
7950       else if (unformat (input, "weight %u", &weight))
7951         {
7952           path->weight = weight;
7953         }
7954       else if (unformat (input, "preference %u", &preference))
7955         {
7956           path->preference = preference;
7957         }
7958       else if (unformat (input, "%U next-hop-table %d",
7959                          unformat_vl_api_ip4_address,
7960                          &path->nh.address.ip4, &path->table_id))
7961         {
7962           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7963         }
7964       else if (unformat (input, "%U next-hop-table %d",
7965                          unformat_vl_api_ip6_address,
7966                          &path->nh.address.ip6, &path->table_id))
7967         {
7968           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7969         }
7970       else if (unformat (input, "%U",
7971                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7972         {
7973           /*
7974            * the recursive next-hops are by default in the default table
7975            */
7976           path->table_id = 0;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7979         }
7980       else if (unformat (input, "%U",
7981                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7982         {
7983           /*
7984            * the recursive next-hops are by default in the default table
7985            */
7986           path->table_id = 0;
7987           path->sw_if_index = ~0;
7988           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7989         }
7990       else if (unformat (input, "resolve-via-host"))
7991         {
7992           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7993         }
7994       else if (unformat (input, "resolve-via-attached"))
7995         {
7996           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7997         }
7998       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7999         {
8000           path->type = FIB_API_PATH_TYPE_LOCAL;
8001           path->sw_if_index = ~0;
8002           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8003         }
8004       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8005         {
8006           path->type = FIB_API_PATH_TYPE_LOCAL;
8007           path->sw_if_index = ~0;
8008           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8009         }
8010       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8011         ;
8012       else if (unformat (input, "via-label %d", &path->nh.via_label))
8013         {
8014           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8015           path->sw_if_index = ~0;
8016         }
8017       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8018         {
8019           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8020           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8021         }
8022       else if (unformat (input, "local"))
8023         {
8024           path->type = FIB_API_PATH_TYPE_LOCAL;
8025         }
8026       else if (unformat (input, "out-labels"))
8027         {
8028           while (unformat (input, "%d", &out_label))
8029             {
8030               path->label_stack[path->n_labels].label = out_label;
8031               path->label_stack[path->n_labels].is_uniform = 0;
8032               path->label_stack[path->n_labels].ttl = 64;
8033               path->n_labels++;
8034             }
8035         }
8036       else if (unformat (input, "via"))
8037         {
8038           /* new path, back up and return */
8039           unformat_put_input (input);
8040           unformat_put_input (input);
8041           unformat_put_input (input);
8042           unformat_put_input (input);
8043           break;
8044         }
8045       else
8046         {
8047           return (0);
8048         }
8049     }
8050
8051   path->proto = ntohl (path->proto);
8052   path->type = ntohl (path->type);
8053   path->flags = ntohl (path->flags);
8054   path->table_id = ntohl (path->table_id);
8055   path->sw_if_index = ntohl (path->sw_if_index);
8056
8057   return (1);
8058 }
8059
8060 static int
8061 api_ip_route_add_del (vat_main_t * vam)
8062 {
8063   unformat_input_t *i = vam->input;
8064   vl_api_ip_route_add_del_t *mp;
8065   u32 vrf_id = 0;
8066   u8 is_add = 1;
8067   u8 is_multipath = 0;
8068   u8 prefix_set = 0;
8069   u8 path_count = 0;
8070   vl_api_prefix_t pfx = { };
8071   vl_api_fib_path_t paths[8];
8072   int count = 1;
8073   int j;
8074   f64 before = 0;
8075   u32 random_add_del = 0;
8076   u32 *random_vector = 0;
8077   u32 random_seed = 0xdeaddabe;
8078
8079   /* Parse args required to build the message */
8080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8083         prefix_set = 1;
8084       else if (unformat (i, "del"))
8085         is_add = 0;
8086       else if (unformat (i, "add"))
8087         is_add = 1;
8088       else if (unformat (i, "vrf %d", &vrf_id))
8089         ;
8090       else if (unformat (i, "count %d", &count))
8091         ;
8092       else if (unformat (i, "random"))
8093         random_add_del = 1;
8094       else if (unformat (i, "multipath"))
8095         is_multipath = 1;
8096       else if (unformat (i, "seed %d", &random_seed))
8097         ;
8098       else
8099         if (unformat
8100             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8101         {
8102           path_count++;
8103           if (8 == path_count)
8104             {
8105               errmsg ("max 8 paths");
8106               return -99;
8107             }
8108         }
8109       else
8110         {
8111           clib_warning ("parse error '%U'", format_unformat_error, i);
8112           return -99;
8113         }
8114     }
8115
8116   if (!path_count)
8117     {
8118       errmsg ("specify a path; via ...");
8119       return -99;
8120     }
8121   if (prefix_set == 0)
8122     {
8123       errmsg ("missing prefix");
8124       return -99;
8125     }
8126
8127   /* Generate a pile of unique, random routes */
8128   if (random_add_del)
8129     {
8130       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8131       u32 this_random_address;
8132       uword *random_hash;
8133
8134       random_hash = hash_create (count, sizeof (uword));
8135
8136       hash_set (random_hash, i->as_u32, 1);
8137       for (j = 0; j <= count; j++)
8138         {
8139           do
8140             {
8141               this_random_address = random_u32 (&random_seed);
8142               this_random_address =
8143                 clib_host_to_net_u32 (this_random_address);
8144             }
8145           while (hash_get (random_hash, this_random_address));
8146           vec_add1 (random_vector, this_random_address);
8147           hash_set (random_hash, this_random_address, 1);
8148         }
8149       hash_free (random_hash);
8150       set_ip4_address (&pfx.address, random_vector[0]);
8151     }
8152
8153   if (count > 1)
8154     {
8155       /* Turn on async mode */
8156       vam->async_mode = 1;
8157       vam->async_errors = 0;
8158       before = vat_time_now (vam);
8159     }
8160
8161   for (j = 0; j < count; j++)
8162     {
8163       /* Construct the API message */
8164       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8165
8166       mp->is_add = is_add;
8167       mp->is_multipath = is_multipath;
8168
8169       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8170       mp->route.table_id = ntohl (vrf_id);
8171       mp->route.n_paths = path_count;
8172
8173       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8174
8175       if (random_add_del)
8176         set_ip4_address (&pfx.address, random_vector[j + 1]);
8177       else
8178         increment_address (&pfx.address);
8179       /* send it... */
8180       S (mp);
8181       /* If we receive SIGTERM, stop now... */
8182       if (vam->do_exit)
8183         break;
8184     }
8185
8186   /* When testing multiple add/del ops, use a control-ping to sync */
8187   if (count > 1)
8188     {
8189       vl_api_control_ping_t *mp_ping;
8190       f64 after;
8191       f64 timeout;
8192
8193       /* Shut off async mode */
8194       vam->async_mode = 0;
8195
8196       MPING (CONTROL_PING, mp_ping);
8197       S (mp_ping);
8198
8199       timeout = vat_time_now (vam) + 1.0;
8200       while (vat_time_now (vam) < timeout)
8201         if (vam->result_ready == 1)
8202           goto out;
8203       vam->retval = -99;
8204
8205     out:
8206       if (vam->retval == -99)
8207         errmsg ("timeout");
8208
8209       if (vam->async_errors > 0)
8210         {
8211           errmsg ("%d asynchronous errors", vam->async_errors);
8212           vam->retval = -98;
8213         }
8214       vam->async_errors = 0;
8215       after = vat_time_now (vam);
8216
8217       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8218       if (j > 0)
8219         count = j;
8220
8221       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8222              count, after - before, count / (after - before));
8223     }
8224   else
8225     {
8226       int ret;
8227
8228       /* Wait for a reply... */
8229       W (ret);
8230       return ret;
8231     }
8232
8233   /* Return the good/bad news */
8234   return (vam->retval);
8235 }
8236
8237 static int
8238 api_ip_mroute_add_del (vat_main_t * vam)
8239 {
8240   unformat_input_t *i = vam->input;
8241   u8 path_set = 0, prefix_set = 0, is_add = 1;
8242   vl_api_ip_mroute_add_del_t *mp;
8243   mfib_entry_flags_t eflags = 0;
8244   vl_api_mfib_path_t path;
8245   vl_api_mprefix_t pfx = { };
8246   u32 vrf_id = 0;
8247   int ret;
8248
8249   /* Parse args required to build the message */
8250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8251     {
8252       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8253         {
8254           prefix_set = 1;
8255           pfx.grp_address_length = htons (pfx.grp_address_length);
8256         }
8257       else if (unformat (i, "del"))
8258         is_add = 0;
8259       else if (unformat (i, "add"))
8260         is_add = 1;
8261       else if (unformat (i, "vrf %d", &vrf_id))
8262         ;
8263       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8264         path.itf_flags = htonl (path.itf_flags);
8265       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8266         ;
8267       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8268         path_set = 1;
8269       else
8270         {
8271           clib_warning ("parse error '%U'", format_unformat_error, i);
8272           return -99;
8273         }
8274     }
8275
8276   if (prefix_set == 0)
8277     {
8278       errmsg ("missing addresses\n");
8279       return -99;
8280     }
8281   if (path_set == 0)
8282     {
8283       errmsg ("missing path\n");
8284       return -99;
8285     }
8286
8287   /* Construct the API message */
8288   M (IP_MROUTE_ADD_DEL, mp);
8289
8290   mp->is_add = is_add;
8291   mp->is_multipath = 1;
8292
8293   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8294   mp->route.table_id = htonl (vrf_id);
8295   mp->route.n_paths = 1;
8296   mp->route.entry_flags = htonl (eflags);
8297
8298   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8299
8300   /* send it... */
8301   S (mp);
8302   /* Wait for a reply... */
8303   W (ret);
8304   return ret;
8305 }
8306
8307 static int
8308 api_mpls_table_add_del (vat_main_t * vam)
8309 {
8310   unformat_input_t *i = vam->input;
8311   vl_api_mpls_table_add_del_t *mp;
8312   u32 table_id = ~0;
8313   u8 is_add = 1;
8314   int ret = 0;
8315
8316   /* Parse args required to build the message */
8317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318     {
8319       if (unformat (i, "table %d", &table_id))
8320         ;
8321       else if (unformat (i, "del"))
8322         is_add = 0;
8323       else if (unformat (i, "add"))
8324         is_add = 1;
8325       else
8326         {
8327           clib_warning ("parse error '%U'", format_unformat_error, i);
8328           return -99;
8329         }
8330     }
8331
8332   if (~0 == table_id)
8333     {
8334       errmsg ("missing table-ID");
8335       return -99;
8336     }
8337
8338   /* Construct the API message */
8339   M (MPLS_TABLE_ADD_DEL, mp);
8340
8341   mp->mt_table.mt_table_id = ntohl (table_id);
8342   mp->mt_is_add = is_add;
8343
8344   /* send it... */
8345   S (mp);
8346
8347   /* Wait for a reply... */
8348   W (ret);
8349
8350   return ret;
8351 }
8352
8353 static int
8354 api_mpls_route_add_del (vat_main_t * vam)
8355 {
8356   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8357   mpls_label_t local_label = MPLS_LABEL_INVALID;
8358   unformat_input_t *i = vam->input;
8359   vl_api_mpls_route_add_del_t *mp;
8360   vl_api_fib_path_t paths[8];
8361   int count = 1, j;
8362   f64 before = 0;
8363
8364   /* Parse args required to build the message */
8365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8366     {
8367       if (unformat (i, "%d", &local_label))
8368         ;
8369       else if (unformat (i, "eos"))
8370         is_eos = 1;
8371       else if (unformat (i, "non-eos"))
8372         is_eos = 0;
8373       else if (unformat (i, "del"))
8374         is_add = 0;
8375       else if (unformat (i, "add"))
8376         is_add = 1;
8377       else if (unformat (i, "multipath"))
8378         is_multipath = 1;
8379       else if (unformat (i, "count %d", &count))
8380         ;
8381       else
8382         if (unformat
8383             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8384         {
8385           path_count++;
8386           if (8 == path_count)
8387             {
8388               errmsg ("max 8 paths");
8389               return -99;
8390             }
8391         }
8392       else
8393         {
8394           clib_warning ("parse error '%U'", format_unformat_error, i);
8395           return -99;
8396         }
8397     }
8398
8399   if (!path_count)
8400     {
8401       errmsg ("specify a path; via ...");
8402       return -99;
8403     }
8404
8405   if (MPLS_LABEL_INVALID == local_label)
8406     {
8407       errmsg ("missing label");
8408       return -99;
8409     }
8410
8411   if (count > 1)
8412     {
8413       /* Turn on async mode */
8414       vam->async_mode = 1;
8415       vam->async_errors = 0;
8416       before = vat_time_now (vam);
8417     }
8418
8419   for (j = 0; j < count; j++)
8420     {
8421       /* Construct the API message */
8422       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8423
8424       mp->mr_is_add = is_add;
8425       mp->mr_is_multipath = is_multipath;
8426
8427       mp->mr_route.mr_label = local_label;
8428       mp->mr_route.mr_eos = is_eos;
8429       mp->mr_route.mr_table_id = 0;
8430       mp->mr_route.mr_n_paths = path_count;
8431
8432       clib_memcpy (&mp->mr_route.mr_paths, paths,
8433                    sizeof (paths[0]) * path_count);
8434
8435       local_label++;
8436
8437       /* send it... */
8438       S (mp);
8439       /* If we receive SIGTERM, stop now... */
8440       if (vam->do_exit)
8441         break;
8442     }
8443
8444   /* When testing multiple add/del ops, use a control-ping to sync */
8445   if (count > 1)
8446     {
8447       vl_api_control_ping_t *mp_ping;
8448       f64 after;
8449       f64 timeout;
8450
8451       /* Shut off async mode */
8452       vam->async_mode = 0;
8453
8454       MPING (CONTROL_PING, mp_ping);
8455       S (mp_ping);
8456
8457       timeout = vat_time_now (vam) + 1.0;
8458       while (vat_time_now (vam) < timeout)
8459         if (vam->result_ready == 1)
8460           goto out;
8461       vam->retval = -99;
8462
8463     out:
8464       if (vam->retval == -99)
8465         errmsg ("timeout");
8466
8467       if (vam->async_errors > 0)
8468         {
8469           errmsg ("%d asynchronous errors", vam->async_errors);
8470           vam->retval = -98;
8471         }
8472       vam->async_errors = 0;
8473       after = vat_time_now (vam);
8474
8475       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8476       if (j > 0)
8477         count = j;
8478
8479       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8480              count, after - before, count / (after - before));
8481     }
8482   else
8483     {
8484       int ret;
8485
8486       /* Wait for a reply... */
8487       W (ret);
8488       return ret;
8489     }
8490
8491   /* Return the good/bad news */
8492   return (vam->retval);
8493   return (0);
8494 }
8495
8496 static int
8497 api_mpls_ip_bind_unbind (vat_main_t * vam)
8498 {
8499   unformat_input_t *i = vam->input;
8500   vl_api_mpls_ip_bind_unbind_t *mp;
8501   u32 ip_table_id = 0;
8502   u8 is_bind = 1;
8503   vl_api_prefix_t pfx;
8504   u8 prefix_set = 0;
8505   mpls_label_t local_label = MPLS_LABEL_INVALID;
8506   int ret;
8507
8508   /* Parse args required to build the message */
8509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8510     {
8511       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8512         prefix_set = 1;
8513       else if (unformat (i, "%d", &local_label))
8514         ;
8515       else if (unformat (i, "table-id %d", &ip_table_id))
8516         ;
8517       else if (unformat (i, "unbind"))
8518         is_bind = 0;
8519       else if (unformat (i, "bind"))
8520         is_bind = 1;
8521       else
8522         {
8523           clib_warning ("parse error '%U'", format_unformat_error, i);
8524           return -99;
8525         }
8526     }
8527
8528   if (!prefix_set)
8529     {
8530       errmsg ("IP prefix not set");
8531       return -99;
8532     }
8533
8534   if (MPLS_LABEL_INVALID == local_label)
8535     {
8536       errmsg ("missing label");
8537       return -99;
8538     }
8539
8540   /* Construct the API message */
8541   M (MPLS_IP_BIND_UNBIND, mp);
8542
8543   mp->mb_is_bind = is_bind;
8544   mp->mb_ip_table_id = ntohl (ip_table_id);
8545   mp->mb_mpls_table_id = 0;
8546   mp->mb_label = ntohl (local_label);
8547   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8548
8549   /* send it... */
8550   S (mp);
8551
8552   /* Wait for a reply... */
8553   W (ret);
8554   return ret;
8555   return (0);
8556 }
8557
8558 static int
8559 api_sr_mpls_policy_add (vat_main_t * vam)
8560 {
8561   unformat_input_t *i = vam->input;
8562   vl_api_sr_mpls_policy_add_t *mp;
8563   u32 bsid = 0;
8564   u32 weight = 1;
8565   u8 type = 0;
8566   u8 n_segments = 0;
8567   u32 sid;
8568   u32 *segments = NULL;
8569   int ret;
8570
8571   /* Parse args required to build the message */
8572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8573     {
8574       if (unformat (i, "bsid %d", &bsid))
8575         ;
8576       else if (unformat (i, "weight %d", &weight))
8577         ;
8578       else if (unformat (i, "spray"))
8579         type = 1;
8580       else if (unformat (i, "next %d", &sid))
8581         {
8582           n_segments += 1;
8583           vec_add1 (segments, htonl (sid));
8584         }
8585       else
8586         {
8587           clib_warning ("parse error '%U'", format_unformat_error, i);
8588           return -99;
8589         }
8590     }
8591
8592   if (bsid == 0)
8593     {
8594       errmsg ("bsid not set");
8595       return -99;
8596     }
8597
8598   if (n_segments == 0)
8599     {
8600       errmsg ("no sid in segment stack");
8601       return -99;
8602     }
8603
8604   /* Construct the API message */
8605   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8606
8607   mp->bsid = htonl (bsid);
8608   mp->weight = htonl (weight);
8609   mp->is_spray = type;
8610   mp->n_segments = n_segments;
8611   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8612   vec_free (segments);
8613
8614   /* send it... */
8615   S (mp);
8616
8617   /* Wait for a reply... */
8618   W (ret);
8619   return ret;
8620 }
8621
8622 static int
8623 api_sr_mpls_policy_del (vat_main_t * vam)
8624 {
8625   unformat_input_t *i = vam->input;
8626   vl_api_sr_mpls_policy_del_t *mp;
8627   u32 bsid = 0;
8628   int ret;
8629
8630   /* Parse args required to build the message */
8631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8632     {
8633       if (unformat (i, "bsid %d", &bsid))
8634         ;
8635       else
8636         {
8637           clib_warning ("parse error '%U'", format_unformat_error, i);
8638           return -99;
8639         }
8640     }
8641
8642   if (bsid == 0)
8643     {
8644       errmsg ("bsid not set");
8645       return -99;
8646     }
8647
8648   /* Construct the API message */
8649   M (SR_MPLS_POLICY_DEL, mp);
8650
8651   mp->bsid = htonl (bsid);
8652
8653   /* send it... */
8654   S (mp);
8655
8656   /* Wait for a reply... */
8657   W (ret);
8658   return ret;
8659 }
8660
8661 static int
8662 api_bier_table_add_del (vat_main_t * vam)
8663 {
8664   unformat_input_t *i = vam->input;
8665   vl_api_bier_table_add_del_t *mp;
8666   u8 is_add = 1;
8667   u32 set = 0, sub_domain = 0, hdr_len = 3;
8668   mpls_label_t local_label = MPLS_LABEL_INVALID;
8669   int ret;
8670
8671   /* Parse args required to build the message */
8672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8673     {
8674       if (unformat (i, "sub-domain %d", &sub_domain))
8675         ;
8676       else if (unformat (i, "set %d", &set))
8677         ;
8678       else if (unformat (i, "label %d", &local_label))
8679         ;
8680       else if (unformat (i, "hdr-len %d", &hdr_len))
8681         ;
8682       else if (unformat (i, "add"))
8683         is_add = 1;
8684       else if (unformat (i, "del"))
8685         is_add = 0;
8686       else
8687         {
8688           clib_warning ("parse error '%U'", format_unformat_error, i);
8689           return -99;
8690         }
8691     }
8692
8693   if (MPLS_LABEL_INVALID == local_label)
8694     {
8695       errmsg ("missing label\n");
8696       return -99;
8697     }
8698
8699   /* Construct the API message */
8700   M (BIER_TABLE_ADD_DEL, mp);
8701
8702   mp->bt_is_add = is_add;
8703   mp->bt_label = ntohl (local_label);
8704   mp->bt_tbl_id.bt_set = set;
8705   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8706   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8707
8708   /* send it... */
8709   S (mp);
8710
8711   /* Wait for a reply... */
8712   W (ret);
8713
8714   return (ret);
8715 }
8716
8717 static int
8718 api_bier_route_add_del (vat_main_t * vam)
8719 {
8720   unformat_input_t *i = vam->input;
8721   vl_api_bier_route_add_del_t *mp;
8722   u8 is_add = 1;
8723   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8724   ip4_address_t v4_next_hop_address;
8725   ip6_address_t v6_next_hop_address;
8726   u8 next_hop_set = 0;
8727   u8 next_hop_proto_is_ip4 = 1;
8728   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8729   int ret;
8730
8731   /* Parse args required to build the message */
8732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8733     {
8734       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8735         {
8736           next_hop_proto_is_ip4 = 1;
8737           next_hop_set = 1;
8738         }
8739       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8740         {
8741           next_hop_proto_is_ip4 = 0;
8742           next_hop_set = 1;
8743         }
8744       if (unformat (i, "sub-domain %d", &sub_domain))
8745         ;
8746       else if (unformat (i, "set %d", &set))
8747         ;
8748       else if (unformat (i, "hdr-len %d", &hdr_len))
8749         ;
8750       else if (unformat (i, "bp %d", &bp))
8751         ;
8752       else if (unformat (i, "add"))
8753         is_add = 1;
8754       else if (unformat (i, "del"))
8755         is_add = 0;
8756       else if (unformat (i, "out-label %d", &next_hop_out_label))
8757         ;
8758       else
8759         {
8760           clib_warning ("parse error '%U'", format_unformat_error, i);
8761           return -99;
8762         }
8763     }
8764
8765   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8766     {
8767       errmsg ("next hop / label set\n");
8768       return -99;
8769     }
8770   if (0 == bp)
8771     {
8772       errmsg ("bit=position not set\n");
8773       return -99;
8774     }
8775
8776   /* Construct the API message */
8777   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8778
8779   mp->br_is_add = is_add;
8780   mp->br_route.br_tbl_id.bt_set = set;
8781   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8782   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8783   mp->br_route.br_bp = ntohs (bp);
8784   mp->br_route.br_n_paths = 1;
8785   mp->br_route.br_paths[0].n_labels = 1;
8786   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8787   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8788                                     FIB_API_PATH_NH_PROTO_IP4 :
8789                                     FIB_API_PATH_NH_PROTO_IP6);
8790
8791   if (next_hop_proto_is_ip4)
8792     {
8793       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8794                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8795     }
8796   else
8797     {
8798       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8799                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8800     }
8801
8802   /* send it... */
8803   S (mp);
8804
8805   /* Wait for a reply... */
8806   W (ret);
8807
8808   return (ret);
8809 }
8810
8811 static int
8812 api_mpls_tunnel_add_del (vat_main_t * vam)
8813 {
8814   unformat_input_t *i = vam->input;
8815   vl_api_mpls_tunnel_add_del_t *mp;
8816
8817   vl_api_fib_path_t paths[8];
8818   u32 sw_if_index = ~0;
8819   u8 path_count = 0;
8820   u8 l2_only = 0;
8821   u8 is_add = 1;
8822   int ret;
8823
8824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8825     {
8826       if (unformat (i, "add"))
8827         is_add = 1;
8828       else
8829         if (unformat
8830             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8831         is_add = 0;
8832       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8833         is_add = 0;
8834       else if (unformat (i, "l2-only"))
8835         l2_only = 1;
8836       else
8837         if (unformat
8838             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8839         {
8840           path_count++;
8841           if (8 == path_count)
8842             {
8843               errmsg ("max 8 paths");
8844               return -99;
8845             }
8846         }
8847       else
8848         {
8849           clib_warning ("parse error '%U'", format_unformat_error, i);
8850           return -99;
8851         }
8852     }
8853
8854   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8855
8856   mp->mt_is_add = is_add;
8857   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8858   mp->mt_tunnel.mt_l2_only = l2_only;
8859   mp->mt_tunnel.mt_is_multicast = 0;
8860   mp->mt_tunnel.mt_n_paths = path_count;
8861
8862   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8863                sizeof (paths[0]) * path_count);
8864
8865   S (mp);
8866   W (ret);
8867   return ret;
8868 }
8869
8870 static int
8871 api_sw_interface_set_unnumbered (vat_main_t * vam)
8872 {
8873   unformat_input_t *i = vam->input;
8874   vl_api_sw_interface_set_unnumbered_t *mp;
8875   u32 sw_if_index;
8876   u32 unnum_sw_index = ~0;
8877   u8 is_add = 1;
8878   u8 sw_if_index_set = 0;
8879   int ret;
8880
8881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8882     {
8883       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8884         sw_if_index_set = 1;
8885       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8886         sw_if_index_set = 1;
8887       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8888         ;
8889       else if (unformat (i, "del"))
8890         is_add = 0;
8891       else
8892         {
8893           clib_warning ("parse error '%U'", format_unformat_error, i);
8894           return -99;
8895         }
8896     }
8897
8898   if (sw_if_index_set == 0)
8899     {
8900       errmsg ("missing interface name or sw_if_index");
8901       return -99;
8902     }
8903
8904   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8905
8906   mp->sw_if_index = ntohl (sw_if_index);
8907   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8908   mp->is_add = is_add;
8909
8910   S (mp);
8911   W (ret);
8912   return ret;
8913 }
8914
8915
8916 static int
8917 api_create_vlan_subif (vat_main_t * vam)
8918 {
8919   unformat_input_t *i = vam->input;
8920   vl_api_create_vlan_subif_t *mp;
8921   u32 sw_if_index;
8922   u8 sw_if_index_set = 0;
8923   u32 vlan_id;
8924   u8 vlan_id_set = 0;
8925   int ret;
8926
8927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8928     {
8929       if (unformat (i, "sw_if_index %d", &sw_if_index))
8930         sw_if_index_set = 1;
8931       else
8932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8933         sw_if_index_set = 1;
8934       else if (unformat (i, "vlan %d", &vlan_id))
8935         vlan_id_set = 1;
8936       else
8937         {
8938           clib_warning ("parse error '%U'", format_unformat_error, i);
8939           return -99;
8940         }
8941     }
8942
8943   if (sw_if_index_set == 0)
8944     {
8945       errmsg ("missing interface name or sw_if_index");
8946       return -99;
8947     }
8948
8949   if (vlan_id_set == 0)
8950     {
8951       errmsg ("missing vlan_id");
8952       return -99;
8953     }
8954   M (CREATE_VLAN_SUBIF, mp);
8955
8956   mp->sw_if_index = ntohl (sw_if_index);
8957   mp->vlan_id = ntohl (vlan_id);
8958
8959   S (mp);
8960   W (ret);
8961   return ret;
8962 }
8963
8964 #define foreach_create_subif_bit                \
8965 _(no_tags)                                      \
8966 _(one_tag)                                      \
8967 _(two_tags)                                     \
8968 _(dot1ad)                                       \
8969 _(exact_match)                                  \
8970 _(default_sub)                                  \
8971 _(outer_vlan_id_any)                            \
8972 _(inner_vlan_id_any)
8973
8974 #define foreach_create_subif_flag               \
8975 _(0, "no_tags")                                 \
8976 _(1, "one_tag")                                 \
8977 _(2, "two_tags")                                \
8978 _(3, "dot1ad")                                  \
8979 _(4, "exact_match")                             \
8980 _(5, "default_sub")                             \
8981 _(6, "outer_vlan_id_any")                       \
8982 _(7, "inner_vlan_id_any")
8983
8984 static int
8985 api_create_subif (vat_main_t * vam)
8986 {
8987   unformat_input_t *i = vam->input;
8988   vl_api_create_subif_t *mp;
8989   u32 sw_if_index;
8990   u8 sw_if_index_set = 0;
8991   u32 sub_id;
8992   u8 sub_id_set = 0;
8993   u32 __attribute__ ((unused)) no_tags = 0;
8994   u32 __attribute__ ((unused)) one_tag = 0;
8995   u32 __attribute__ ((unused)) two_tags = 0;
8996   u32 __attribute__ ((unused)) dot1ad = 0;
8997   u32 __attribute__ ((unused)) exact_match = 0;
8998   u32 __attribute__ ((unused)) default_sub = 0;
8999   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9000   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9001   u32 tmp;
9002   u16 outer_vlan_id = 0;
9003   u16 inner_vlan_id = 0;
9004   int ret;
9005
9006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9007     {
9008       if (unformat (i, "sw_if_index %d", &sw_if_index))
9009         sw_if_index_set = 1;
9010       else
9011         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9012         sw_if_index_set = 1;
9013       else if (unformat (i, "sub_id %d", &sub_id))
9014         sub_id_set = 1;
9015       else if (unformat (i, "outer_vlan_id %d", &tmp))
9016         outer_vlan_id = tmp;
9017       else if (unformat (i, "inner_vlan_id %d", &tmp))
9018         inner_vlan_id = tmp;
9019
9020 #define _(a) else if (unformat (i, #a)) a = 1 ;
9021       foreach_create_subif_bit
9022 #undef _
9023         else
9024         {
9025           clib_warning ("parse error '%U'", format_unformat_error, i);
9026           return -99;
9027         }
9028     }
9029
9030   if (sw_if_index_set == 0)
9031     {
9032       errmsg ("missing interface name or sw_if_index");
9033       return -99;
9034     }
9035
9036   if (sub_id_set == 0)
9037     {
9038       errmsg ("missing sub_id");
9039       return -99;
9040     }
9041   M (CREATE_SUBIF, mp);
9042
9043   mp->sw_if_index = ntohl (sw_if_index);
9044   mp->sub_id = ntohl (sub_id);
9045
9046 #define _(a,b) mp->sub_if_flags |= (1 << a);
9047   foreach_create_subif_flag;
9048 #undef _
9049
9050   mp->outer_vlan_id = ntohs (outer_vlan_id);
9051   mp->inner_vlan_id = ntohs (inner_vlan_id);
9052
9053   S (mp);
9054   W (ret);
9055   return ret;
9056 }
9057
9058 static int
9059 api_ip_table_replace_begin (vat_main_t * vam)
9060 {
9061   unformat_input_t *i = vam->input;
9062   vl_api_ip_table_replace_begin_t *mp;
9063   u32 table_id = 0;
9064   u8 is_ipv6 = 0;
9065
9066   int ret;
9067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (i, "table %d", &table_id))
9070         ;
9071       else if (unformat (i, "ipv6"))
9072         is_ipv6 = 1;
9073       else
9074         {
9075           clib_warning ("parse error '%U'", format_unformat_error, i);
9076           return -99;
9077         }
9078     }
9079
9080   M (IP_TABLE_REPLACE_BEGIN, mp);
9081
9082   mp->table.table_id = ntohl (table_id);
9083   mp->table.is_ip6 = is_ipv6;
9084
9085   S (mp);
9086   W (ret);
9087   return ret;
9088 }
9089
9090 static int
9091 api_ip_table_flush (vat_main_t * vam)
9092 {
9093   unformat_input_t *i = vam->input;
9094   vl_api_ip_table_flush_t *mp;
9095   u32 table_id = 0;
9096   u8 is_ipv6 = 0;
9097
9098   int ret;
9099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9100     {
9101       if (unformat (i, "table %d", &table_id))
9102         ;
9103       else if (unformat (i, "ipv6"))
9104         is_ipv6 = 1;
9105       else
9106         {
9107           clib_warning ("parse error '%U'", format_unformat_error, i);
9108           return -99;
9109         }
9110     }
9111
9112   M (IP_TABLE_FLUSH, mp);
9113
9114   mp->table.table_id = ntohl (table_id);
9115   mp->table.is_ip6 = is_ipv6;
9116
9117   S (mp);
9118   W (ret);
9119   return ret;
9120 }
9121
9122 static int
9123 api_ip_table_replace_end (vat_main_t * vam)
9124 {
9125   unformat_input_t *i = vam->input;
9126   vl_api_ip_table_replace_end_t *mp;
9127   u32 table_id = 0;
9128   u8 is_ipv6 = 0;
9129
9130   int ret;
9131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9132     {
9133       if (unformat (i, "table %d", &table_id))
9134         ;
9135       else if (unformat (i, "ipv6"))
9136         is_ipv6 = 1;
9137       else
9138         {
9139           clib_warning ("parse error '%U'", format_unformat_error, i);
9140           return -99;
9141         }
9142     }
9143
9144   M (IP_TABLE_REPLACE_END, mp);
9145
9146   mp->table.table_id = ntohl (table_id);
9147   mp->table.is_ip6 = is_ipv6;
9148
9149   S (mp);
9150   W (ret);
9151   return ret;
9152 }
9153
9154 static int
9155 api_set_ip_flow_hash (vat_main_t * vam)
9156 {
9157   unformat_input_t *i = vam->input;
9158   vl_api_set_ip_flow_hash_t *mp;
9159   u32 vrf_id = 0;
9160   u8 is_ipv6 = 0;
9161   u8 vrf_id_set = 0;
9162   u8 src = 0;
9163   u8 dst = 0;
9164   u8 sport = 0;
9165   u8 dport = 0;
9166   u8 proto = 0;
9167   u8 reverse = 0;
9168   int ret;
9169
9170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9171     {
9172       if (unformat (i, "vrf %d", &vrf_id))
9173         vrf_id_set = 1;
9174       else if (unformat (i, "ipv6"))
9175         is_ipv6 = 1;
9176       else if (unformat (i, "src"))
9177         src = 1;
9178       else if (unformat (i, "dst"))
9179         dst = 1;
9180       else if (unformat (i, "sport"))
9181         sport = 1;
9182       else if (unformat (i, "dport"))
9183         dport = 1;
9184       else if (unformat (i, "proto"))
9185         proto = 1;
9186       else if (unformat (i, "reverse"))
9187         reverse = 1;
9188
9189       else
9190         {
9191           clib_warning ("parse error '%U'", format_unformat_error, i);
9192           return -99;
9193         }
9194     }
9195
9196   if (vrf_id_set == 0)
9197     {
9198       errmsg ("missing vrf id");
9199       return -99;
9200     }
9201
9202   M (SET_IP_FLOW_HASH, mp);
9203   mp->src = src;
9204   mp->dst = dst;
9205   mp->sport = sport;
9206   mp->dport = dport;
9207   mp->proto = proto;
9208   mp->reverse = reverse;
9209   mp->vrf_id = ntohl (vrf_id);
9210   mp->is_ipv6 = is_ipv6;
9211
9212   S (mp);
9213   W (ret);
9214   return ret;
9215 }
9216
9217 static int
9218 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9219 {
9220   unformat_input_t *i = vam->input;
9221   vl_api_sw_interface_ip6_enable_disable_t *mp;
9222   u32 sw_if_index;
9223   u8 sw_if_index_set = 0;
9224   u8 enable = 0;
9225   int ret;
9226
9227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228     {
9229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9230         sw_if_index_set = 1;
9231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9232         sw_if_index_set = 1;
9233       else if (unformat (i, "enable"))
9234         enable = 1;
9235       else if (unformat (i, "disable"))
9236         enable = 0;
9237       else
9238         {
9239           clib_warning ("parse error '%U'", format_unformat_error, i);
9240           return -99;
9241         }
9242     }
9243
9244   if (sw_if_index_set == 0)
9245     {
9246       errmsg ("missing interface name or sw_if_index");
9247       return -99;
9248     }
9249
9250   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9251
9252   mp->sw_if_index = ntohl (sw_if_index);
9253   mp->enable = enable;
9254
9255   S (mp);
9256   W (ret);
9257   return ret;
9258 }
9259
9260
9261 static int
9262 api_l2_patch_add_del (vat_main_t * vam)
9263 {
9264   unformat_input_t *i = vam->input;
9265   vl_api_l2_patch_add_del_t *mp;
9266   u32 rx_sw_if_index;
9267   u8 rx_sw_if_index_set = 0;
9268   u32 tx_sw_if_index;
9269   u8 tx_sw_if_index_set = 0;
9270   u8 is_add = 1;
9271   int ret;
9272
9273   /* Parse args required to build the message */
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9277         rx_sw_if_index_set = 1;
9278       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9279         tx_sw_if_index_set = 1;
9280       else if (unformat (i, "rx"))
9281         {
9282           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9283             {
9284               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9285                             &rx_sw_if_index))
9286                 rx_sw_if_index_set = 1;
9287             }
9288           else
9289             break;
9290         }
9291       else if (unformat (i, "tx"))
9292         {
9293           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9294             {
9295               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9296                             &tx_sw_if_index))
9297                 tx_sw_if_index_set = 1;
9298             }
9299           else
9300             break;
9301         }
9302       else if (unformat (i, "del"))
9303         is_add = 0;
9304       else
9305         break;
9306     }
9307
9308   if (rx_sw_if_index_set == 0)
9309     {
9310       errmsg ("missing rx interface name or rx_sw_if_index");
9311       return -99;
9312     }
9313
9314   if (tx_sw_if_index_set == 0)
9315     {
9316       errmsg ("missing tx interface name or tx_sw_if_index");
9317       return -99;
9318     }
9319
9320   M (L2_PATCH_ADD_DEL, mp);
9321
9322   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9323   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9324   mp->is_add = is_add;
9325
9326   S (mp);
9327   W (ret);
9328   return ret;
9329 }
9330
9331 u8 is_del;
9332 u8 localsid_addr[16];
9333 u8 end_psp;
9334 u8 behavior;
9335 u32 sw_if_index;
9336 u32 vlan_index;
9337 u32 fib_table;
9338 u8 nh_addr[16];
9339
9340 static int
9341 api_sr_localsid_add_del (vat_main_t * vam)
9342 {
9343   unformat_input_t *i = vam->input;
9344   vl_api_sr_localsid_add_del_t *mp;
9345
9346   u8 is_del;
9347   ip6_address_t localsid;
9348   u8 end_psp = 0;
9349   u8 behavior = ~0;
9350   u32 sw_if_index;
9351   u32 fib_table = ~(u32) 0;
9352   ip46_address_t nh_addr;
9353   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9354
9355   bool nexthop_set = 0;
9356
9357   int ret;
9358
9359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (i, "del"))
9362         is_del = 1;
9363       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9364       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9365         nexthop_set = 1;
9366       else if (unformat (i, "behavior %u", &behavior));
9367       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9368       else if (unformat (i, "fib-table %u", &fib_table));
9369       else if (unformat (i, "end.psp %u", &behavior));
9370       else
9371         break;
9372     }
9373
9374   M (SR_LOCALSID_ADD_DEL, mp);
9375
9376   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9377
9378   if (nexthop_set)
9379     {
9380       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9381     }
9382   mp->behavior = behavior;
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   mp->fib_table = ntohl (fib_table);
9385   mp->end_psp = end_psp;
9386   mp->is_del = is_del;
9387
9388   S (mp);
9389   W (ret);
9390   return ret;
9391 }
9392
9393 static int
9394 api_ioam_enable (vat_main_t * vam)
9395 {
9396   unformat_input_t *input = vam->input;
9397   vl_api_ioam_enable_t *mp;
9398   u32 id = 0;
9399   int has_trace_option = 0;
9400   int has_pot_option = 0;
9401   int has_seqno_option = 0;
9402   int has_analyse_option = 0;
9403   int ret;
9404
9405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (input, "trace"))
9408         has_trace_option = 1;
9409       else if (unformat (input, "pot"))
9410         has_pot_option = 1;
9411       else if (unformat (input, "seqno"))
9412         has_seqno_option = 1;
9413       else if (unformat (input, "analyse"))
9414         has_analyse_option = 1;
9415       else
9416         break;
9417     }
9418   M (IOAM_ENABLE, mp);
9419   mp->id = htons (id);
9420   mp->seqno = has_seqno_option;
9421   mp->analyse = has_analyse_option;
9422   mp->pot_enable = has_pot_option;
9423   mp->trace_enable = has_trace_option;
9424
9425   S (mp);
9426   W (ret);
9427   return ret;
9428 }
9429
9430
9431 static int
9432 api_ioam_disable (vat_main_t * vam)
9433 {
9434   vl_api_ioam_disable_t *mp;
9435   int ret;
9436
9437   M (IOAM_DISABLE, mp);
9438   S (mp);
9439   W (ret);
9440   return ret;
9441 }
9442
9443 #define foreach_tcp_proto_field                 \
9444 _(src_port)                                     \
9445 _(dst_port)
9446
9447 #define foreach_udp_proto_field                 \
9448 _(src_port)                                     \
9449 _(dst_port)
9450
9451 #define foreach_ip4_proto_field                 \
9452 _(src_address)                                  \
9453 _(dst_address)                                  \
9454 _(tos)                                          \
9455 _(length)                                       \
9456 _(fragment_id)                                  \
9457 _(ttl)                                          \
9458 _(protocol)                                     \
9459 _(checksum)
9460
9461 typedef struct
9462 {
9463   u16 src_port, dst_port;
9464 } tcpudp_header_t;
9465
9466 #if VPP_API_TEST_BUILTIN == 0
9467 uword
9468 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9469 {
9470   u8 **maskp = va_arg (*args, u8 **);
9471   u8 *mask = 0;
9472   u8 found_something = 0;
9473   tcp_header_t *tcp;
9474
9475 #define _(a) u8 a=0;
9476   foreach_tcp_proto_field;
9477 #undef _
9478
9479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9480     {
9481       if (0);
9482 #define _(a) else if (unformat (input, #a)) a=1;
9483       foreach_tcp_proto_field
9484 #undef _
9485         else
9486         break;
9487     }
9488
9489 #define _(a) found_something += a;
9490   foreach_tcp_proto_field;
9491 #undef _
9492
9493   if (found_something == 0)
9494     return 0;
9495
9496   vec_validate (mask, sizeof (*tcp) - 1);
9497
9498   tcp = (tcp_header_t *) mask;
9499
9500 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9501   foreach_tcp_proto_field;
9502 #undef _
9503
9504   *maskp = mask;
9505   return 1;
9506 }
9507
9508 uword
9509 unformat_udp_mask (unformat_input_t * input, va_list * args)
9510 {
9511   u8 **maskp = va_arg (*args, u8 **);
9512   u8 *mask = 0;
9513   u8 found_something = 0;
9514   udp_header_t *udp;
9515
9516 #define _(a) u8 a=0;
9517   foreach_udp_proto_field;
9518 #undef _
9519
9520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9521     {
9522       if (0);
9523 #define _(a) else if (unformat (input, #a)) a=1;
9524       foreach_udp_proto_field
9525 #undef _
9526         else
9527         break;
9528     }
9529
9530 #define _(a) found_something += a;
9531   foreach_udp_proto_field;
9532 #undef _
9533
9534   if (found_something == 0)
9535     return 0;
9536
9537   vec_validate (mask, sizeof (*udp) - 1);
9538
9539   udp = (udp_header_t *) mask;
9540
9541 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9542   foreach_udp_proto_field;
9543 #undef _
9544
9545   *maskp = mask;
9546   return 1;
9547 }
9548
9549 uword
9550 unformat_l4_mask (unformat_input_t * input, va_list * args)
9551 {
9552   u8 **maskp = va_arg (*args, u8 **);
9553   u16 src_port = 0, dst_port = 0;
9554   tcpudp_header_t *tcpudp;
9555
9556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9559         return 1;
9560       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9561         return 1;
9562       else if (unformat (input, "src_port"))
9563         src_port = 0xFFFF;
9564       else if (unformat (input, "dst_port"))
9565         dst_port = 0xFFFF;
9566       else
9567         return 0;
9568     }
9569
9570   if (!src_port && !dst_port)
9571     return 0;
9572
9573   u8 *mask = 0;
9574   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9575
9576   tcpudp = (tcpudp_header_t *) mask;
9577   tcpudp->src_port = src_port;
9578   tcpudp->dst_port = dst_port;
9579
9580   *maskp = mask;
9581
9582   return 1;
9583 }
9584
9585 uword
9586 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9587 {
9588   u8 **maskp = va_arg (*args, u8 **);
9589   u8 *mask = 0;
9590   u8 found_something = 0;
9591   ip4_header_t *ip;
9592
9593 #define _(a) u8 a=0;
9594   foreach_ip4_proto_field;
9595 #undef _
9596   u8 version = 0;
9597   u8 hdr_length = 0;
9598
9599
9600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (input, "version"))
9603         version = 1;
9604       else if (unformat (input, "hdr_length"))
9605         hdr_length = 1;
9606       else if (unformat (input, "src"))
9607         src_address = 1;
9608       else if (unformat (input, "dst"))
9609         dst_address = 1;
9610       else if (unformat (input, "proto"))
9611         protocol = 1;
9612
9613 #define _(a) else if (unformat (input, #a)) a=1;
9614       foreach_ip4_proto_field
9615 #undef _
9616         else
9617         break;
9618     }
9619
9620 #define _(a) found_something += a;
9621   foreach_ip4_proto_field;
9622 #undef _
9623
9624   if (found_something == 0)
9625     return 0;
9626
9627   vec_validate (mask, sizeof (*ip) - 1);
9628
9629   ip = (ip4_header_t *) mask;
9630
9631 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9632   foreach_ip4_proto_field;
9633 #undef _
9634
9635   ip->ip_version_and_header_length = 0;
9636
9637   if (version)
9638     ip->ip_version_and_header_length |= 0xF0;
9639
9640   if (hdr_length)
9641     ip->ip_version_and_header_length |= 0x0F;
9642
9643   *maskp = mask;
9644   return 1;
9645 }
9646
9647 #define foreach_ip6_proto_field                 \
9648 _(src_address)                                  \
9649 _(dst_address)                                  \
9650 _(payload_length)                               \
9651 _(hop_limit)                                    \
9652 _(protocol)
9653
9654 uword
9655 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9656 {
9657   u8 **maskp = va_arg (*args, u8 **);
9658   u8 *mask = 0;
9659   u8 found_something = 0;
9660   ip6_header_t *ip;
9661   u32 ip_version_traffic_class_and_flow_label;
9662
9663 #define _(a) u8 a=0;
9664   foreach_ip6_proto_field;
9665 #undef _
9666   u8 version = 0;
9667   u8 traffic_class = 0;
9668   u8 flow_label = 0;
9669
9670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9671     {
9672       if (unformat (input, "version"))
9673         version = 1;
9674       else if (unformat (input, "traffic-class"))
9675         traffic_class = 1;
9676       else if (unformat (input, "flow-label"))
9677         flow_label = 1;
9678       else if (unformat (input, "src"))
9679         src_address = 1;
9680       else if (unformat (input, "dst"))
9681         dst_address = 1;
9682       else if (unformat (input, "proto"))
9683         protocol = 1;
9684
9685 #define _(a) else if (unformat (input, #a)) a=1;
9686       foreach_ip6_proto_field
9687 #undef _
9688         else
9689         break;
9690     }
9691
9692 #define _(a) found_something += a;
9693   foreach_ip6_proto_field;
9694 #undef _
9695
9696   if (found_something == 0)
9697     return 0;
9698
9699   vec_validate (mask, sizeof (*ip) - 1);
9700
9701   ip = (ip6_header_t *) mask;
9702
9703 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9704   foreach_ip6_proto_field;
9705 #undef _
9706
9707   ip_version_traffic_class_and_flow_label = 0;
9708
9709   if (version)
9710     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9711
9712   if (traffic_class)
9713     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9714
9715   if (flow_label)
9716     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9717
9718   ip->ip_version_traffic_class_and_flow_label =
9719     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9720
9721   *maskp = mask;
9722   return 1;
9723 }
9724
9725 uword
9726 unformat_l3_mask (unformat_input_t * input, va_list * args)
9727 {
9728   u8 **maskp = va_arg (*args, u8 **);
9729
9730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9731     {
9732       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9733         return 1;
9734       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9735         return 1;
9736       else
9737         break;
9738     }
9739   return 0;
9740 }
9741
9742 uword
9743 unformat_l2_mask (unformat_input_t * input, va_list * args)
9744 {
9745   u8 **maskp = va_arg (*args, u8 **);
9746   u8 *mask = 0;
9747   u8 src = 0;
9748   u8 dst = 0;
9749   u8 proto = 0;
9750   u8 tag1 = 0;
9751   u8 tag2 = 0;
9752   u8 ignore_tag1 = 0;
9753   u8 ignore_tag2 = 0;
9754   u8 cos1 = 0;
9755   u8 cos2 = 0;
9756   u8 dot1q = 0;
9757   u8 dot1ad = 0;
9758   int len = 14;
9759
9760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9761     {
9762       if (unformat (input, "src"))
9763         src = 1;
9764       else if (unformat (input, "dst"))
9765         dst = 1;
9766       else if (unformat (input, "proto"))
9767         proto = 1;
9768       else if (unformat (input, "tag1"))
9769         tag1 = 1;
9770       else if (unformat (input, "tag2"))
9771         tag2 = 1;
9772       else if (unformat (input, "ignore-tag1"))
9773         ignore_tag1 = 1;
9774       else if (unformat (input, "ignore-tag2"))
9775         ignore_tag2 = 1;
9776       else if (unformat (input, "cos1"))
9777         cos1 = 1;
9778       else if (unformat (input, "cos2"))
9779         cos2 = 1;
9780       else if (unformat (input, "dot1q"))
9781         dot1q = 1;
9782       else if (unformat (input, "dot1ad"))
9783         dot1ad = 1;
9784       else
9785         break;
9786     }
9787   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9788        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9789     return 0;
9790
9791   if (tag1 || ignore_tag1 || cos1 || dot1q)
9792     len = 18;
9793   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9794     len = 22;
9795
9796   vec_validate (mask, len - 1);
9797
9798   if (dst)
9799     clib_memset (mask, 0xff, 6);
9800
9801   if (src)
9802     clib_memset (mask + 6, 0xff, 6);
9803
9804   if (tag2 || dot1ad)
9805     {
9806       /* inner vlan tag */
9807       if (tag2)
9808         {
9809           mask[19] = 0xff;
9810           mask[18] = 0x0f;
9811         }
9812       if (cos2)
9813         mask[18] |= 0xe0;
9814       if (proto)
9815         mask[21] = mask[20] = 0xff;
9816       if (tag1)
9817         {
9818           mask[15] = 0xff;
9819           mask[14] = 0x0f;
9820         }
9821       if (cos1)
9822         mask[14] |= 0xe0;
9823       *maskp = mask;
9824       return 1;
9825     }
9826   if (tag1 | dot1q)
9827     {
9828       if (tag1)
9829         {
9830           mask[15] = 0xff;
9831           mask[14] = 0x0f;
9832         }
9833       if (cos1)
9834         mask[14] |= 0xe0;
9835       if (proto)
9836         mask[16] = mask[17] = 0xff;
9837
9838       *maskp = mask;
9839       return 1;
9840     }
9841   if (cos2)
9842     mask[18] |= 0xe0;
9843   if (cos1)
9844     mask[14] |= 0xe0;
9845   if (proto)
9846     mask[12] = mask[13] = 0xff;
9847
9848   *maskp = mask;
9849   return 1;
9850 }
9851
9852 uword
9853 unformat_classify_mask (unformat_input_t * input, va_list * args)
9854 {
9855   u8 **maskp = va_arg (*args, u8 **);
9856   u32 *skipp = va_arg (*args, u32 *);
9857   u32 *matchp = va_arg (*args, u32 *);
9858   u32 match;
9859   u8 *mask = 0;
9860   u8 *l2 = 0;
9861   u8 *l3 = 0;
9862   u8 *l4 = 0;
9863   int i;
9864
9865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9866     {
9867       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9868         ;
9869       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9870         ;
9871       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9872         ;
9873       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9874         ;
9875       else
9876         break;
9877     }
9878
9879   if (l4 && !l3)
9880     {
9881       vec_free (mask);
9882       vec_free (l2);
9883       vec_free (l4);
9884       return 0;
9885     }
9886
9887   if (mask || l2 || l3 || l4)
9888     {
9889       if (l2 || l3 || l4)
9890         {
9891           /* "With a free Ethernet header in every package" */
9892           if (l2 == 0)
9893             vec_validate (l2, 13);
9894           mask = l2;
9895           if (vec_len (l3))
9896             {
9897               vec_append (mask, l3);
9898               vec_free (l3);
9899             }
9900           if (vec_len (l4))
9901             {
9902               vec_append (mask, l4);
9903               vec_free (l4);
9904             }
9905         }
9906
9907       /* Scan forward looking for the first significant mask octet */
9908       for (i = 0; i < vec_len (mask); i++)
9909         if (mask[i])
9910           break;
9911
9912       /* compute (skip, match) params */
9913       *skipp = i / sizeof (u32x4);
9914       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9915
9916       /* Pad mask to an even multiple of the vector size */
9917       while (vec_len (mask) % sizeof (u32x4))
9918         vec_add1 (mask, 0);
9919
9920       match = vec_len (mask) / sizeof (u32x4);
9921
9922       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9923         {
9924           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9925           if (*tmp || *(tmp + 1))
9926             break;
9927           match--;
9928         }
9929       if (match == 0)
9930         clib_warning ("BUG: match 0");
9931
9932       _vec_len (mask) = match * sizeof (u32x4);
9933
9934       *matchp = match;
9935       *maskp = mask;
9936
9937       return 1;
9938     }
9939
9940   return 0;
9941 }
9942 #endif /* VPP_API_TEST_BUILTIN */
9943
9944 #define foreach_l2_next                         \
9945 _(drop, DROP)                                   \
9946 _(ethernet, ETHERNET_INPUT)                     \
9947 _(ip4, IP4_INPUT)                               \
9948 _(ip6, IP6_INPUT)
9949
9950 uword
9951 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9952 {
9953   u32 *miss_next_indexp = va_arg (*args, u32 *);
9954   u32 next_index = 0;
9955   u32 tmp;
9956
9957 #define _(n,N) \
9958   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9959   foreach_l2_next;
9960 #undef _
9961
9962   if (unformat (input, "%d", &tmp))
9963     {
9964       next_index = tmp;
9965       goto out;
9966     }
9967
9968   return 0;
9969
9970 out:
9971   *miss_next_indexp = next_index;
9972   return 1;
9973 }
9974
9975 #define foreach_ip_next                         \
9976 _(drop, DROP)                                   \
9977 _(local, LOCAL)                                 \
9978 _(rewrite, REWRITE)
9979
9980 uword
9981 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9982 {
9983   u32 *miss_next_indexp = va_arg (*args, u32 *);
9984   u32 next_index = 0;
9985   u32 tmp;
9986
9987 #define _(n,N) \
9988   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9989   foreach_ip_next;
9990 #undef _
9991
9992   if (unformat (input, "%d", &tmp))
9993     {
9994       next_index = tmp;
9995       goto out;
9996     }
9997
9998   return 0;
9999
10000 out:
10001   *miss_next_indexp = next_index;
10002   return 1;
10003 }
10004
10005 #define foreach_acl_next                        \
10006 _(deny, DENY)
10007
10008 uword
10009 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10010 {
10011   u32 *miss_next_indexp = va_arg (*args, u32 *);
10012   u32 next_index = 0;
10013   u32 tmp;
10014
10015 #define _(n,N) \
10016   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10017   foreach_acl_next;
10018 #undef _
10019
10020   if (unformat (input, "permit"))
10021     {
10022       next_index = ~0;
10023       goto out;
10024     }
10025   else if (unformat (input, "%d", &tmp))
10026     {
10027       next_index = tmp;
10028       goto out;
10029     }
10030
10031   return 0;
10032
10033 out:
10034   *miss_next_indexp = next_index;
10035   return 1;
10036 }
10037
10038 uword
10039 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10040 {
10041   u32 *r = va_arg (*args, u32 *);
10042
10043   if (unformat (input, "conform-color"))
10044     *r = POLICE_CONFORM;
10045   else if (unformat (input, "exceed-color"))
10046     *r = POLICE_EXCEED;
10047   else
10048     return 0;
10049
10050   return 1;
10051 }
10052
10053 static int
10054 api_classify_add_del_table (vat_main_t * vam)
10055 {
10056   unformat_input_t *i = vam->input;
10057   vl_api_classify_add_del_table_t *mp;
10058
10059   u32 nbuckets = 2;
10060   u32 skip = ~0;
10061   u32 match = ~0;
10062   int is_add = 1;
10063   int del_chain = 0;
10064   u32 table_index = ~0;
10065   u32 next_table_index = ~0;
10066   u32 miss_next_index = ~0;
10067   u32 memory_size = 32 << 20;
10068   u8 *mask = 0;
10069   u32 current_data_flag = 0;
10070   int current_data_offset = 0;
10071   int ret;
10072
10073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10074     {
10075       if (unformat (i, "del"))
10076         is_add = 0;
10077       else if (unformat (i, "del-chain"))
10078         {
10079           is_add = 0;
10080           del_chain = 1;
10081         }
10082       else if (unformat (i, "buckets %d", &nbuckets))
10083         ;
10084       else if (unformat (i, "memory_size %d", &memory_size))
10085         ;
10086       else if (unformat (i, "skip %d", &skip))
10087         ;
10088       else if (unformat (i, "match %d", &match))
10089         ;
10090       else if (unformat (i, "table %d", &table_index))
10091         ;
10092       else if (unformat (i, "mask %U", unformat_classify_mask,
10093                          &mask, &skip, &match))
10094         ;
10095       else if (unformat (i, "next-table %d", &next_table_index))
10096         ;
10097       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10098                          &miss_next_index))
10099         ;
10100       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10101                          &miss_next_index))
10102         ;
10103       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10104                          &miss_next_index))
10105         ;
10106       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10107         ;
10108       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10109         ;
10110       else
10111         break;
10112     }
10113
10114   if (is_add && mask == 0)
10115     {
10116       errmsg ("Mask required");
10117       return -99;
10118     }
10119
10120   if (is_add && skip == ~0)
10121     {
10122       errmsg ("skip count required");
10123       return -99;
10124     }
10125
10126   if (is_add && match == ~0)
10127     {
10128       errmsg ("match count required");
10129       return -99;
10130     }
10131
10132   if (!is_add && table_index == ~0)
10133     {
10134       errmsg ("table index required for delete");
10135       return -99;
10136     }
10137
10138   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10139
10140   mp->is_add = is_add;
10141   mp->del_chain = del_chain;
10142   mp->table_index = ntohl (table_index);
10143   mp->nbuckets = ntohl (nbuckets);
10144   mp->memory_size = ntohl (memory_size);
10145   mp->skip_n_vectors = ntohl (skip);
10146   mp->match_n_vectors = ntohl (match);
10147   mp->next_table_index = ntohl (next_table_index);
10148   mp->miss_next_index = ntohl (miss_next_index);
10149   mp->current_data_flag = ntohl (current_data_flag);
10150   mp->current_data_offset = ntohl (current_data_offset);
10151   mp->mask_len = ntohl (vec_len (mask));
10152   clib_memcpy (mp->mask, mask, vec_len (mask));
10153
10154   vec_free (mask);
10155
10156   S (mp);
10157   W (ret);
10158   return ret;
10159 }
10160
10161 #if VPP_API_TEST_BUILTIN == 0
10162 uword
10163 unformat_l4_match (unformat_input_t * input, va_list * args)
10164 {
10165   u8 **matchp = va_arg (*args, u8 **);
10166
10167   u8 *proto_header = 0;
10168   int src_port = 0;
10169   int dst_port = 0;
10170
10171   tcpudp_header_t h;
10172
10173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10174     {
10175       if (unformat (input, "src_port %d", &src_port))
10176         ;
10177       else if (unformat (input, "dst_port %d", &dst_port))
10178         ;
10179       else
10180         return 0;
10181     }
10182
10183   h.src_port = clib_host_to_net_u16 (src_port);
10184   h.dst_port = clib_host_to_net_u16 (dst_port);
10185   vec_validate (proto_header, sizeof (h) - 1);
10186   memcpy (proto_header, &h, sizeof (h));
10187
10188   *matchp = proto_header;
10189
10190   return 1;
10191 }
10192
10193 uword
10194 unformat_ip4_match (unformat_input_t * input, va_list * args)
10195 {
10196   u8 **matchp = va_arg (*args, u8 **);
10197   u8 *match = 0;
10198   ip4_header_t *ip;
10199   int version = 0;
10200   u32 version_val;
10201   int hdr_length = 0;
10202   u32 hdr_length_val;
10203   int src = 0, dst = 0;
10204   ip4_address_t src_val, dst_val;
10205   int proto = 0;
10206   u32 proto_val;
10207   int tos = 0;
10208   u32 tos_val;
10209   int length = 0;
10210   u32 length_val;
10211   int fragment_id = 0;
10212   u32 fragment_id_val;
10213   int ttl = 0;
10214   int ttl_val;
10215   int checksum = 0;
10216   u32 checksum_val;
10217
10218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (input, "version %d", &version_val))
10221         version = 1;
10222       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10223         hdr_length = 1;
10224       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10225         src = 1;
10226       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10227         dst = 1;
10228       else if (unformat (input, "proto %d", &proto_val))
10229         proto = 1;
10230       else if (unformat (input, "tos %d", &tos_val))
10231         tos = 1;
10232       else if (unformat (input, "length %d", &length_val))
10233         length = 1;
10234       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10235         fragment_id = 1;
10236       else if (unformat (input, "ttl %d", &ttl_val))
10237         ttl = 1;
10238       else if (unformat (input, "checksum %d", &checksum_val))
10239         checksum = 1;
10240       else
10241         break;
10242     }
10243
10244   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10245       + ttl + checksum == 0)
10246     return 0;
10247
10248   /*
10249    * Aligned because we use the real comparison functions
10250    */
10251   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10252
10253   ip = (ip4_header_t *) match;
10254
10255   /* These are realistically matched in practice */
10256   if (src)
10257     ip->src_address.as_u32 = src_val.as_u32;
10258
10259   if (dst)
10260     ip->dst_address.as_u32 = dst_val.as_u32;
10261
10262   if (proto)
10263     ip->protocol = proto_val;
10264
10265
10266   /* These are not, but they're included for completeness */
10267   if (version)
10268     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10269
10270   if (hdr_length)
10271     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10272
10273   if (tos)
10274     ip->tos = tos_val;
10275
10276   if (length)
10277     ip->length = clib_host_to_net_u16 (length_val);
10278
10279   if (ttl)
10280     ip->ttl = ttl_val;
10281
10282   if (checksum)
10283     ip->checksum = clib_host_to_net_u16 (checksum_val);
10284
10285   *matchp = match;
10286   return 1;
10287 }
10288
10289 uword
10290 unformat_ip6_match (unformat_input_t * input, va_list * args)
10291 {
10292   u8 **matchp = va_arg (*args, u8 **);
10293   u8 *match = 0;
10294   ip6_header_t *ip;
10295   int version = 0;
10296   u32 version_val;
10297   u8 traffic_class = 0;
10298   u32 traffic_class_val = 0;
10299   u8 flow_label = 0;
10300   u8 flow_label_val;
10301   int src = 0, dst = 0;
10302   ip6_address_t src_val, dst_val;
10303   int proto = 0;
10304   u32 proto_val;
10305   int payload_length = 0;
10306   u32 payload_length_val;
10307   int hop_limit = 0;
10308   int hop_limit_val;
10309   u32 ip_version_traffic_class_and_flow_label;
10310
10311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10312     {
10313       if (unformat (input, "version %d", &version_val))
10314         version = 1;
10315       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10316         traffic_class = 1;
10317       else if (unformat (input, "flow_label %d", &flow_label_val))
10318         flow_label = 1;
10319       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10320         src = 1;
10321       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10322         dst = 1;
10323       else if (unformat (input, "proto %d", &proto_val))
10324         proto = 1;
10325       else if (unformat (input, "payload_length %d", &payload_length_val))
10326         payload_length = 1;
10327       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10328         hop_limit = 1;
10329       else
10330         break;
10331     }
10332
10333   if (version + traffic_class + flow_label + src + dst + proto +
10334       payload_length + hop_limit == 0)
10335     return 0;
10336
10337   /*
10338    * Aligned because we use the real comparison functions
10339    */
10340   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10341
10342   ip = (ip6_header_t *) match;
10343
10344   if (src)
10345     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10346
10347   if (dst)
10348     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10349
10350   if (proto)
10351     ip->protocol = proto_val;
10352
10353   ip_version_traffic_class_and_flow_label = 0;
10354
10355   if (version)
10356     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10357
10358   if (traffic_class)
10359     ip_version_traffic_class_and_flow_label |=
10360       (traffic_class_val & 0xFF) << 20;
10361
10362   if (flow_label)
10363     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10364
10365   ip->ip_version_traffic_class_and_flow_label =
10366     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10367
10368   if (payload_length)
10369     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10370
10371   if (hop_limit)
10372     ip->hop_limit = hop_limit_val;
10373
10374   *matchp = match;
10375   return 1;
10376 }
10377
10378 uword
10379 unformat_l3_match (unformat_input_t * input, va_list * args)
10380 {
10381   u8 **matchp = va_arg (*args, u8 **);
10382
10383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10384     {
10385       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10386         return 1;
10387       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10388         return 1;
10389       else
10390         break;
10391     }
10392   return 0;
10393 }
10394
10395 uword
10396 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10397 {
10398   u8 *tagp = va_arg (*args, u8 *);
10399   u32 tag;
10400
10401   if (unformat (input, "%d", &tag))
10402     {
10403       tagp[0] = (tag >> 8) & 0x0F;
10404       tagp[1] = tag & 0xFF;
10405       return 1;
10406     }
10407
10408   return 0;
10409 }
10410
10411 uword
10412 unformat_l2_match (unformat_input_t * input, va_list * args)
10413 {
10414   u8 **matchp = va_arg (*args, u8 **);
10415   u8 *match = 0;
10416   u8 src = 0;
10417   u8 src_val[6];
10418   u8 dst = 0;
10419   u8 dst_val[6];
10420   u8 proto = 0;
10421   u16 proto_val;
10422   u8 tag1 = 0;
10423   u8 tag1_val[2];
10424   u8 tag2 = 0;
10425   u8 tag2_val[2];
10426   int len = 14;
10427   u8 ignore_tag1 = 0;
10428   u8 ignore_tag2 = 0;
10429   u8 cos1 = 0;
10430   u8 cos2 = 0;
10431   u32 cos1_val = 0;
10432   u32 cos2_val = 0;
10433
10434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10435     {
10436       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10437         src = 1;
10438       else
10439         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10440         dst = 1;
10441       else if (unformat (input, "proto %U",
10442                          unformat_ethernet_type_host_byte_order, &proto_val))
10443         proto = 1;
10444       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10445         tag1 = 1;
10446       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10447         tag2 = 1;
10448       else if (unformat (input, "ignore-tag1"))
10449         ignore_tag1 = 1;
10450       else if (unformat (input, "ignore-tag2"))
10451         ignore_tag2 = 1;
10452       else if (unformat (input, "cos1 %d", &cos1_val))
10453         cos1 = 1;
10454       else if (unformat (input, "cos2 %d", &cos2_val))
10455         cos2 = 1;
10456       else
10457         break;
10458     }
10459   if ((src + dst + proto + tag1 + tag2 +
10460        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10461     return 0;
10462
10463   if (tag1 || ignore_tag1 || cos1)
10464     len = 18;
10465   if (tag2 || ignore_tag2 || cos2)
10466     len = 22;
10467
10468   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10469
10470   if (dst)
10471     clib_memcpy (match, dst_val, 6);
10472
10473   if (src)
10474     clib_memcpy (match + 6, src_val, 6);
10475
10476   if (tag2)
10477     {
10478       /* inner vlan tag */
10479       match[19] = tag2_val[1];
10480       match[18] = tag2_val[0];
10481       if (cos2)
10482         match[18] |= (cos2_val & 0x7) << 5;
10483       if (proto)
10484         {
10485           match[21] = proto_val & 0xff;
10486           match[20] = proto_val >> 8;
10487         }
10488       if (tag1)
10489         {
10490           match[15] = tag1_val[1];
10491           match[14] = tag1_val[0];
10492         }
10493       if (cos1)
10494         match[14] |= (cos1_val & 0x7) << 5;
10495       *matchp = match;
10496       return 1;
10497     }
10498   if (tag1)
10499     {
10500       match[15] = tag1_val[1];
10501       match[14] = tag1_val[0];
10502       if (proto)
10503         {
10504           match[17] = proto_val & 0xff;
10505           match[16] = proto_val >> 8;
10506         }
10507       if (cos1)
10508         match[14] |= (cos1_val & 0x7) << 5;
10509
10510       *matchp = match;
10511       return 1;
10512     }
10513   if (cos2)
10514     match[18] |= (cos2_val & 0x7) << 5;
10515   if (cos1)
10516     match[14] |= (cos1_val & 0x7) << 5;
10517   if (proto)
10518     {
10519       match[13] = proto_val & 0xff;
10520       match[12] = proto_val >> 8;
10521     }
10522
10523   *matchp = match;
10524   return 1;
10525 }
10526
10527 uword
10528 unformat_qos_source (unformat_input_t * input, va_list * args)
10529 {
10530   int *qs = va_arg (*args, int *);
10531
10532   if (unformat (input, "ip"))
10533     *qs = QOS_SOURCE_IP;
10534   else if (unformat (input, "mpls"))
10535     *qs = QOS_SOURCE_MPLS;
10536   else if (unformat (input, "ext"))
10537     *qs = QOS_SOURCE_EXT;
10538   else if (unformat (input, "vlan"))
10539     *qs = QOS_SOURCE_VLAN;
10540   else
10541     return 0;
10542
10543   return 1;
10544 }
10545 #endif
10546
10547 uword
10548 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10549 {
10550   u8 **matchp = va_arg (*args, u8 **);
10551   u32 skip_n_vectors = va_arg (*args, u32);
10552   u32 match_n_vectors = va_arg (*args, u32);
10553
10554   u8 *match = 0;
10555   u8 *l2 = 0;
10556   u8 *l3 = 0;
10557   u8 *l4 = 0;
10558
10559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10560     {
10561       if (unformat (input, "hex %U", unformat_hex_string, &match))
10562         ;
10563       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10564         ;
10565       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10566         ;
10567       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10568         ;
10569       else
10570         break;
10571     }
10572
10573   if (l4 && !l3)
10574     {
10575       vec_free (match);
10576       vec_free (l2);
10577       vec_free (l4);
10578       return 0;
10579     }
10580
10581   if (match || l2 || l3 || l4)
10582     {
10583       if (l2 || l3 || l4)
10584         {
10585           /* "Win a free Ethernet header in every packet" */
10586           if (l2 == 0)
10587             vec_validate_aligned (l2, 13, sizeof (u32x4));
10588           match = l2;
10589           if (vec_len (l3))
10590             {
10591               vec_append_aligned (match, l3, sizeof (u32x4));
10592               vec_free (l3);
10593             }
10594           if (vec_len (l4))
10595             {
10596               vec_append_aligned (match, l4, sizeof (u32x4));
10597               vec_free (l4);
10598             }
10599         }
10600
10601       /* Make sure the vector is big enough even if key is all 0's */
10602       vec_validate_aligned
10603         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10604          sizeof (u32x4));
10605
10606       /* Set size, include skipped vectors */
10607       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10608
10609       *matchp = match;
10610
10611       return 1;
10612     }
10613
10614   return 0;
10615 }
10616
10617 static int
10618 api_classify_add_del_session (vat_main_t * vam)
10619 {
10620   unformat_input_t *i = vam->input;
10621   vl_api_classify_add_del_session_t *mp;
10622   int is_add = 1;
10623   u32 table_index = ~0;
10624   u32 hit_next_index = ~0;
10625   u32 opaque_index = ~0;
10626   u8 *match = 0;
10627   i32 advance = 0;
10628   u32 skip_n_vectors = 0;
10629   u32 match_n_vectors = 0;
10630   u32 action = 0;
10631   u32 metadata = 0;
10632   int ret;
10633
10634   /*
10635    * Warning: you have to supply skip_n and match_n
10636    * because the API client cant simply look at the classify
10637    * table object.
10638    */
10639
10640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10641     {
10642       if (unformat (i, "del"))
10643         is_add = 0;
10644       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10645                          &hit_next_index))
10646         ;
10647       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10648                          &hit_next_index))
10649         ;
10650       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10651                          &hit_next_index))
10652         ;
10653       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10654         ;
10655       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10656         ;
10657       else if (unformat (i, "opaque-index %d", &opaque_index))
10658         ;
10659       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10660         ;
10661       else if (unformat (i, "match_n %d", &match_n_vectors))
10662         ;
10663       else if (unformat (i, "match %U", api_unformat_classify_match,
10664                          &match, skip_n_vectors, match_n_vectors))
10665         ;
10666       else if (unformat (i, "advance %d", &advance))
10667         ;
10668       else if (unformat (i, "table-index %d", &table_index))
10669         ;
10670       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10671         action = 1;
10672       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10673         action = 2;
10674       else if (unformat (i, "action %d", &action))
10675         ;
10676       else if (unformat (i, "metadata %d", &metadata))
10677         ;
10678       else
10679         break;
10680     }
10681
10682   if (table_index == ~0)
10683     {
10684       errmsg ("Table index required");
10685       return -99;
10686     }
10687
10688   if (is_add && match == 0)
10689     {
10690       errmsg ("Match value required");
10691       return -99;
10692     }
10693
10694   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10695
10696   mp->is_add = is_add;
10697   mp->table_index = ntohl (table_index);
10698   mp->hit_next_index = ntohl (hit_next_index);
10699   mp->opaque_index = ntohl (opaque_index);
10700   mp->advance = ntohl (advance);
10701   mp->action = action;
10702   mp->metadata = ntohl (metadata);
10703   mp->match_len = ntohl (vec_len (match));
10704   clib_memcpy (mp->match, match, vec_len (match));
10705   vec_free (match);
10706
10707   S (mp);
10708   W (ret);
10709   return ret;
10710 }
10711
10712 static int
10713 api_classify_set_interface_ip_table (vat_main_t * vam)
10714 {
10715   unformat_input_t *i = vam->input;
10716   vl_api_classify_set_interface_ip_table_t *mp;
10717   u32 sw_if_index;
10718   int sw_if_index_set;
10719   u32 table_index = ~0;
10720   u8 is_ipv6 = 0;
10721   int ret;
10722
10723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10724     {
10725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10726         sw_if_index_set = 1;
10727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10728         sw_if_index_set = 1;
10729       else if (unformat (i, "table %d", &table_index))
10730         ;
10731       else
10732         {
10733           clib_warning ("parse error '%U'", format_unformat_error, i);
10734           return -99;
10735         }
10736     }
10737
10738   if (sw_if_index_set == 0)
10739     {
10740       errmsg ("missing interface name or sw_if_index");
10741       return -99;
10742     }
10743
10744
10745   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10746
10747   mp->sw_if_index = ntohl (sw_if_index);
10748   mp->table_index = ntohl (table_index);
10749   mp->is_ipv6 = is_ipv6;
10750
10751   S (mp);
10752   W (ret);
10753   return ret;
10754 }
10755
10756 static int
10757 api_classify_set_interface_l2_tables (vat_main_t * vam)
10758 {
10759   unformat_input_t *i = vam->input;
10760   vl_api_classify_set_interface_l2_tables_t *mp;
10761   u32 sw_if_index;
10762   int sw_if_index_set;
10763   u32 ip4_table_index = ~0;
10764   u32 ip6_table_index = ~0;
10765   u32 other_table_index = ~0;
10766   u32 is_input = 1;
10767   int ret;
10768
10769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10772         sw_if_index_set = 1;
10773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10774         sw_if_index_set = 1;
10775       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10776         ;
10777       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10778         ;
10779       else if (unformat (i, "other-table %d", &other_table_index))
10780         ;
10781       else if (unformat (i, "is-input %d", &is_input))
10782         ;
10783       else
10784         {
10785           clib_warning ("parse error '%U'", format_unformat_error, i);
10786           return -99;
10787         }
10788     }
10789
10790   if (sw_if_index_set == 0)
10791     {
10792       errmsg ("missing interface name or sw_if_index");
10793       return -99;
10794     }
10795
10796
10797   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10798
10799   mp->sw_if_index = ntohl (sw_if_index);
10800   mp->ip4_table_index = ntohl (ip4_table_index);
10801   mp->ip6_table_index = ntohl (ip6_table_index);
10802   mp->other_table_index = ntohl (other_table_index);
10803   mp->is_input = (u8) is_input;
10804
10805   S (mp);
10806   W (ret);
10807   return ret;
10808 }
10809
10810 static int
10811 api_set_ipfix_exporter (vat_main_t * vam)
10812 {
10813   unformat_input_t *i = vam->input;
10814   vl_api_set_ipfix_exporter_t *mp;
10815   ip4_address_t collector_address;
10816   u8 collector_address_set = 0;
10817   u32 collector_port = ~0;
10818   ip4_address_t src_address;
10819   u8 src_address_set = 0;
10820   u32 vrf_id = ~0;
10821   u32 path_mtu = ~0;
10822   u32 template_interval = ~0;
10823   u8 udp_checksum = 0;
10824   int ret;
10825
10826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10827     {
10828       if (unformat (i, "collector_address %U", unformat_ip4_address,
10829                     &collector_address))
10830         collector_address_set = 1;
10831       else if (unformat (i, "collector_port %d", &collector_port))
10832         ;
10833       else if (unformat (i, "src_address %U", unformat_ip4_address,
10834                          &src_address))
10835         src_address_set = 1;
10836       else if (unformat (i, "vrf_id %d", &vrf_id))
10837         ;
10838       else if (unformat (i, "path_mtu %d", &path_mtu))
10839         ;
10840       else if (unformat (i, "template_interval %d", &template_interval))
10841         ;
10842       else if (unformat (i, "udp_checksum"))
10843         udp_checksum = 1;
10844       else
10845         break;
10846     }
10847
10848   if (collector_address_set == 0)
10849     {
10850       errmsg ("collector_address required");
10851       return -99;
10852     }
10853
10854   if (src_address_set == 0)
10855     {
10856       errmsg ("src_address required");
10857       return -99;
10858     }
10859
10860   M (SET_IPFIX_EXPORTER, mp);
10861
10862   memcpy (mp->collector_address.un.ip4, collector_address.data,
10863           sizeof (collector_address.data));
10864   mp->collector_port = htons ((u16) collector_port);
10865   memcpy (mp->src_address.un.ip4, src_address.data,
10866           sizeof (src_address.data));
10867   mp->vrf_id = htonl (vrf_id);
10868   mp->path_mtu = htonl (path_mtu);
10869   mp->template_interval = htonl (template_interval);
10870   mp->udp_checksum = udp_checksum;
10871
10872   S (mp);
10873   W (ret);
10874   return ret;
10875 }
10876
10877 static int
10878 api_set_ipfix_classify_stream (vat_main_t * vam)
10879 {
10880   unformat_input_t *i = vam->input;
10881   vl_api_set_ipfix_classify_stream_t *mp;
10882   u32 domain_id = 0;
10883   u32 src_port = UDP_DST_PORT_ipfix;
10884   int ret;
10885
10886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (i, "domain %d", &domain_id))
10889         ;
10890       else if (unformat (i, "src_port %d", &src_port))
10891         ;
10892       else
10893         {
10894           errmsg ("unknown input `%U'", format_unformat_error, i);
10895           return -99;
10896         }
10897     }
10898
10899   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10900
10901   mp->domain_id = htonl (domain_id);
10902   mp->src_port = htons ((u16) src_port);
10903
10904   S (mp);
10905   W (ret);
10906   return ret;
10907 }
10908
10909 static int
10910 api_ipfix_classify_table_add_del (vat_main_t * vam)
10911 {
10912   unformat_input_t *i = vam->input;
10913   vl_api_ipfix_classify_table_add_del_t *mp;
10914   int is_add = -1;
10915   u32 classify_table_index = ~0;
10916   u8 ip_version = 0;
10917   u8 transport_protocol = 255;
10918   int ret;
10919
10920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (i, "add"))
10923         is_add = 1;
10924       else if (unformat (i, "del"))
10925         is_add = 0;
10926       else if (unformat (i, "table %d", &classify_table_index))
10927         ;
10928       else if (unformat (i, "ip4"))
10929         ip_version = 4;
10930       else if (unformat (i, "ip6"))
10931         ip_version = 6;
10932       else if (unformat (i, "tcp"))
10933         transport_protocol = 6;
10934       else if (unformat (i, "udp"))
10935         transport_protocol = 17;
10936       else
10937         {
10938           errmsg ("unknown input `%U'", format_unformat_error, i);
10939           return -99;
10940         }
10941     }
10942
10943   if (is_add == -1)
10944     {
10945       errmsg ("expecting: add|del");
10946       return -99;
10947     }
10948   if (classify_table_index == ~0)
10949     {
10950       errmsg ("classifier table not specified");
10951       return -99;
10952     }
10953   if (ip_version == 0)
10954     {
10955       errmsg ("IP version not specified");
10956       return -99;
10957     }
10958
10959   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10960
10961   mp->is_add = is_add;
10962   mp->table_id = htonl (classify_table_index);
10963   mp->ip_version = ip_version;
10964   mp->transport_protocol = transport_protocol;
10965
10966   S (mp);
10967   W (ret);
10968   return ret;
10969 }
10970
10971 static int
10972 api_get_node_index (vat_main_t * vam)
10973 {
10974   unformat_input_t *i = vam->input;
10975   vl_api_get_node_index_t *mp;
10976   u8 *name = 0;
10977   int ret;
10978
10979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10980     {
10981       if (unformat (i, "node %s", &name))
10982         ;
10983       else
10984         break;
10985     }
10986   if (name == 0)
10987     {
10988       errmsg ("node name required");
10989       return -99;
10990     }
10991   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10992     {
10993       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10994       return -99;
10995     }
10996
10997   M (GET_NODE_INDEX, mp);
10998   clib_memcpy (mp->node_name, name, vec_len (name));
10999   vec_free (name);
11000
11001   S (mp);
11002   W (ret);
11003   return ret;
11004 }
11005
11006 static int
11007 api_get_next_index (vat_main_t * vam)
11008 {
11009   unformat_input_t *i = vam->input;
11010   vl_api_get_next_index_t *mp;
11011   u8 *node_name = 0, *next_node_name = 0;
11012   int ret;
11013
11014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11015     {
11016       if (unformat (i, "node-name %s", &node_name))
11017         ;
11018       else if (unformat (i, "next-node-name %s", &next_node_name))
11019         break;
11020     }
11021
11022   if (node_name == 0)
11023     {
11024       errmsg ("node name required");
11025       return -99;
11026     }
11027   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11028     {
11029       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11030       return -99;
11031     }
11032
11033   if (next_node_name == 0)
11034     {
11035       errmsg ("next node name required");
11036       return -99;
11037     }
11038   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11039     {
11040       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11041       return -99;
11042     }
11043
11044   M (GET_NEXT_INDEX, mp);
11045   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11046   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11047   vec_free (node_name);
11048   vec_free (next_node_name);
11049
11050   S (mp);
11051   W (ret);
11052   return ret;
11053 }
11054
11055 static int
11056 api_add_node_next (vat_main_t * vam)
11057 {
11058   unformat_input_t *i = vam->input;
11059   vl_api_add_node_next_t *mp;
11060   u8 *name = 0;
11061   u8 *next = 0;
11062   int ret;
11063
11064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11065     {
11066       if (unformat (i, "node %s", &name))
11067         ;
11068       else if (unformat (i, "next %s", &next))
11069         ;
11070       else
11071         break;
11072     }
11073   if (name == 0)
11074     {
11075       errmsg ("node name required");
11076       return -99;
11077     }
11078   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11079     {
11080       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11081       return -99;
11082     }
11083   if (next == 0)
11084     {
11085       errmsg ("next node required");
11086       return -99;
11087     }
11088   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11089     {
11090       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11091       return -99;
11092     }
11093
11094   M (ADD_NODE_NEXT, mp);
11095   clib_memcpy (mp->node_name, name, vec_len (name));
11096   clib_memcpy (mp->next_name, next, vec_len (next));
11097   vec_free (name);
11098   vec_free (next);
11099
11100   S (mp);
11101   W (ret);
11102   return ret;
11103 }
11104
11105 static void vl_api_sw_interface_tap_v2_details_t_handler
11106   (vl_api_sw_interface_tap_v2_details_t * mp)
11107 {
11108   vat_main_t *vam = &vat_main;
11109
11110   u8 *ip4 =
11111     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11112             mp->host_ip4_prefix.len);
11113   u8 *ip6 =
11114     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11115             mp->host_ip6_prefix.len);
11116
11117   print (vam->ofp,
11118          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11119          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11120          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11121          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11122          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11123
11124   vec_free (ip4);
11125   vec_free (ip6);
11126 }
11127
11128 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11129   (vl_api_sw_interface_tap_v2_details_t * mp)
11130 {
11131   vat_main_t *vam = &vat_main;
11132   vat_json_node_t *node = NULL;
11133
11134   if (VAT_JSON_ARRAY != vam->json_tree.type)
11135     {
11136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11137       vat_json_init_array (&vam->json_tree);
11138     }
11139   node = vat_json_array_add (&vam->json_tree);
11140
11141   vat_json_init_object (node);
11142   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11144   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11145   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11146   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11147   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11148   vat_json_object_add_string_copy (node, "host_mac_addr",
11149                                    format (0, "%U", format_ethernet_address,
11150                                            &mp->host_mac_addr));
11151   vat_json_object_add_string_copy (node, "host_namespace",
11152                                    mp->host_namespace);
11153   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11154   vat_json_object_add_string_copy (node, "host_ip4_addr",
11155                                    format (0, "%U/%d", format_ip4_address,
11156                                            mp->host_ip4_prefix.address,
11157                                            mp->host_ip4_prefix.len));
11158   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11159                                    format (0, "%U/%d", format_ip6_address,
11160                                            mp->host_ip6_prefix.address,
11161                                            mp->host_ip6_prefix.len));
11162
11163 }
11164
11165 static int
11166 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11167 {
11168   vl_api_sw_interface_tap_v2_dump_t *mp;
11169   vl_api_control_ping_t *mp_ping;
11170   int ret;
11171
11172   print (vam->ofp,
11173          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11174          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11175          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11176          "host_ip6_addr");
11177
11178   /* Get list of tap interfaces */
11179   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11180   S (mp);
11181
11182   /* Use a control ping for synchronization */
11183   MPING (CONTROL_PING, mp_ping);
11184   S (mp_ping);
11185
11186   W (ret);
11187   return ret;
11188 }
11189
11190 static void vl_api_sw_interface_virtio_pci_details_t_handler
11191   (vl_api_sw_interface_virtio_pci_details_t * mp)
11192 {
11193   vat_main_t *vam = &vat_main;
11194
11195   typedef union
11196   {
11197     struct
11198     {
11199       u16 domain;
11200       u8 bus;
11201       u8 slot:5;
11202       u8 function:3;
11203     };
11204     u32 as_u32;
11205   } pci_addr_t;
11206   pci_addr_t addr;
11207
11208   addr.domain = ntohs (mp->pci_addr.domain);
11209   addr.bus = mp->pci_addr.bus;
11210   addr.slot = mp->pci_addr.slot;
11211   addr.function = mp->pci_addr.function;
11212
11213   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11214                          addr.slot, addr.function);
11215
11216   print (vam->ofp,
11217          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11218          pci_addr, ntohl (mp->sw_if_index),
11219          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11220          format_ethernet_address, mp->mac_addr,
11221          clib_net_to_host_u64 (mp->features));
11222   vec_free (pci_addr);
11223 }
11224
11225 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11226   (vl_api_sw_interface_virtio_pci_details_t * mp)
11227 {
11228   vat_main_t *vam = &vat_main;
11229   vat_json_node_t *node = NULL;
11230   vlib_pci_addr_t pci_addr;
11231
11232   if (VAT_JSON_ARRAY != vam->json_tree.type)
11233     {
11234       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11235       vat_json_init_array (&vam->json_tree);
11236     }
11237   node = vat_json_array_add (&vam->json_tree);
11238
11239   pci_addr.domain = ntohs (mp->pci_addr.domain);
11240   pci_addr.bus = mp->pci_addr.bus;
11241   pci_addr.slot = mp->pci_addr.slot;
11242   pci_addr.function = mp->pci_addr.function;
11243
11244   vat_json_init_object (node);
11245   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11246   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11247   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11248   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11249   vat_json_object_add_uint (node, "features",
11250                             clib_net_to_host_u64 (mp->features));
11251   vat_json_object_add_string_copy (node, "mac_addr",
11252                                    format (0, "%U", format_ethernet_address,
11253                                            &mp->mac_addr));
11254 }
11255
11256 static int
11257 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11258 {
11259   vl_api_sw_interface_virtio_pci_dump_t *mp;
11260   vl_api_control_ping_t *mp_ping;
11261   int ret;
11262
11263   print (vam->ofp,
11264          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11265          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11266          "mac_addr", "features");
11267
11268   /* Get list of tap interfaces */
11269   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11270   S (mp);
11271
11272   /* Use a control ping for synchronization */
11273   MPING (CONTROL_PING, mp_ping);
11274   S (mp_ping);
11275
11276   W (ret);
11277   return ret;
11278 }
11279
11280 static int
11281 api_vxlan_offload_rx (vat_main_t * vam)
11282 {
11283   unformat_input_t *line_input = vam->input;
11284   vl_api_vxlan_offload_rx_t *mp;
11285   u32 hw_if_index = ~0, rx_if_index = ~0;
11286   u8 is_add = 1;
11287   int ret;
11288
11289   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11290     {
11291       if (unformat (line_input, "del"))
11292         is_add = 0;
11293       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11294                          &hw_if_index))
11295         ;
11296       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11297         ;
11298       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11299                          &rx_if_index))
11300         ;
11301       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11302         ;
11303       else
11304         {
11305           errmsg ("parse error '%U'", format_unformat_error, line_input);
11306           return -99;
11307         }
11308     }
11309
11310   if (hw_if_index == ~0)
11311     {
11312       errmsg ("no hw interface");
11313       return -99;
11314     }
11315
11316   if (rx_if_index == ~0)
11317     {
11318       errmsg ("no rx tunnel");
11319       return -99;
11320     }
11321
11322   M (VXLAN_OFFLOAD_RX, mp);
11323
11324   mp->hw_if_index = ntohl (hw_if_index);
11325   mp->sw_if_index = ntohl (rx_if_index);
11326   mp->enable = is_add;
11327
11328   S (mp);
11329   W (ret);
11330   return ret;
11331 }
11332
11333 static uword unformat_vxlan_decap_next
11334   (unformat_input_t * input, va_list * args)
11335 {
11336   u32 *result = va_arg (*args, u32 *);
11337   u32 tmp;
11338
11339   if (unformat (input, "l2"))
11340     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11341   else if (unformat (input, "%d", &tmp))
11342     *result = tmp;
11343   else
11344     return 0;
11345   return 1;
11346 }
11347
11348 static int
11349 api_vxlan_add_del_tunnel (vat_main_t * vam)
11350 {
11351   unformat_input_t *line_input = vam->input;
11352   vl_api_vxlan_add_del_tunnel_t *mp;
11353   ip46_address_t src, dst;
11354   u8 is_add = 1;
11355   u8 ipv4_set = 0, ipv6_set = 0;
11356   u8 src_set = 0;
11357   u8 dst_set = 0;
11358   u8 grp_set = 0;
11359   u32 instance = ~0;
11360   u32 mcast_sw_if_index = ~0;
11361   u32 encap_vrf_id = 0;
11362   u32 decap_next_index = ~0;
11363   u32 vni = 0;
11364   int ret;
11365
11366   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11367   clib_memset (&src, 0, sizeof src);
11368   clib_memset (&dst, 0, sizeof dst);
11369
11370   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (line_input, "del"))
11373         is_add = 0;
11374       else if (unformat (line_input, "instance %d", &instance))
11375         ;
11376       else
11377         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11378         {
11379           ipv4_set = 1;
11380           src_set = 1;
11381         }
11382       else
11383         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11384         {
11385           ipv4_set = 1;
11386           dst_set = 1;
11387         }
11388       else
11389         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11390         {
11391           ipv6_set = 1;
11392           src_set = 1;
11393         }
11394       else
11395         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11396         {
11397           ipv6_set = 1;
11398           dst_set = 1;
11399         }
11400       else if (unformat (line_input, "group %U %U",
11401                          unformat_ip4_address, &dst.ip4,
11402                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11403         {
11404           grp_set = dst_set = 1;
11405           ipv4_set = 1;
11406         }
11407       else if (unformat (line_input, "group %U",
11408                          unformat_ip4_address, &dst.ip4))
11409         {
11410           grp_set = dst_set = 1;
11411           ipv4_set = 1;
11412         }
11413       else if (unformat (line_input, "group %U %U",
11414                          unformat_ip6_address, &dst.ip6,
11415                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11416         {
11417           grp_set = dst_set = 1;
11418           ipv6_set = 1;
11419         }
11420       else if (unformat (line_input, "group %U",
11421                          unformat_ip6_address, &dst.ip6))
11422         {
11423           grp_set = dst_set = 1;
11424           ipv6_set = 1;
11425         }
11426       else
11427         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11428         ;
11429       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11430         ;
11431       else if (unformat (line_input, "decap-next %U",
11432                          unformat_vxlan_decap_next, &decap_next_index))
11433         ;
11434       else if (unformat (line_input, "vni %d", &vni))
11435         ;
11436       else
11437         {
11438           errmsg ("parse error '%U'", format_unformat_error, line_input);
11439           return -99;
11440         }
11441     }
11442
11443   if (src_set == 0)
11444     {
11445       errmsg ("tunnel src address not specified");
11446       return -99;
11447     }
11448   if (dst_set == 0)
11449     {
11450       errmsg ("tunnel dst address not specified");
11451       return -99;
11452     }
11453
11454   if (grp_set && !ip46_address_is_multicast (&dst))
11455     {
11456       errmsg ("tunnel group address not multicast");
11457       return -99;
11458     }
11459   if (grp_set && mcast_sw_if_index == ~0)
11460     {
11461       errmsg ("tunnel nonexistent multicast device");
11462       return -99;
11463     }
11464   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11465     {
11466       errmsg ("tunnel dst address must be unicast");
11467       return -99;
11468     }
11469
11470
11471   if (ipv4_set && ipv6_set)
11472     {
11473       errmsg ("both IPv4 and IPv6 addresses specified");
11474       return -99;
11475     }
11476
11477   if ((vni == 0) || (vni >> 24))
11478     {
11479       errmsg ("vni not specified or out of range");
11480       return -99;
11481     }
11482
11483   M (VXLAN_ADD_DEL_TUNNEL, mp);
11484
11485   if (ipv6_set)
11486     {
11487       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11488       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11489     }
11490   else
11491     {
11492       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11493       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11494     }
11495   mp->src_address.af = ipv6_set;
11496   mp->dst_address.af = ipv6_set;
11497
11498   mp->instance = htonl (instance);
11499   mp->encap_vrf_id = ntohl (encap_vrf_id);
11500   mp->decap_next_index = ntohl (decap_next_index);
11501   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11502   mp->vni = ntohl (vni);
11503   mp->is_add = is_add;
11504
11505   S (mp);
11506   W (ret);
11507   return ret;
11508 }
11509
11510 static void vl_api_vxlan_tunnel_details_t_handler
11511   (vl_api_vxlan_tunnel_details_t * mp)
11512 {
11513   vat_main_t *vam = &vat_main;
11514   ip46_address_t src =
11515     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11516   ip46_address_t dst =
11517     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11518
11519   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11520          ntohl (mp->sw_if_index),
11521          ntohl (mp->instance),
11522          format_ip46_address, &src, IP46_TYPE_ANY,
11523          format_ip46_address, &dst, IP46_TYPE_ANY,
11524          ntohl (mp->encap_vrf_id),
11525          ntohl (mp->decap_next_index), ntohl (mp->vni),
11526          ntohl (mp->mcast_sw_if_index));
11527 }
11528
11529 static void vl_api_vxlan_tunnel_details_t_handler_json
11530   (vl_api_vxlan_tunnel_details_t * mp)
11531 {
11532   vat_main_t *vam = &vat_main;
11533   vat_json_node_t *node = NULL;
11534
11535   if (VAT_JSON_ARRAY != vam->json_tree.type)
11536     {
11537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11538       vat_json_init_array (&vam->json_tree);
11539     }
11540   node = vat_json_array_add (&vam->json_tree);
11541
11542   vat_json_init_object (node);
11543   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11544
11545   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11546
11547   if (mp->src_address.af)
11548     {
11549       struct in6_addr ip6;
11550
11551       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11552       vat_json_object_add_ip6 (node, "src_address", ip6);
11553       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11554       vat_json_object_add_ip6 (node, "dst_address", ip6);
11555     }
11556   else
11557     {
11558       struct in_addr ip4;
11559
11560       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11561       vat_json_object_add_ip4 (node, "src_address", ip4);
11562       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11563       vat_json_object_add_ip4 (node, "dst_address", ip4);
11564     }
11565   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11566   vat_json_object_add_uint (node, "decap_next_index",
11567                             ntohl (mp->decap_next_index));
11568   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11569   vat_json_object_add_uint (node, "mcast_sw_if_index",
11570                             ntohl (mp->mcast_sw_if_index));
11571 }
11572
11573 static int
11574 api_vxlan_tunnel_dump (vat_main_t * vam)
11575 {
11576   unformat_input_t *i = vam->input;
11577   vl_api_vxlan_tunnel_dump_t *mp;
11578   vl_api_control_ping_t *mp_ping;
11579   u32 sw_if_index;
11580   u8 sw_if_index_set = 0;
11581   int ret;
11582
11583   /* Parse args required to build the message */
11584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11585     {
11586       if (unformat (i, "sw_if_index %d", &sw_if_index))
11587         sw_if_index_set = 1;
11588       else
11589         break;
11590     }
11591
11592   if (sw_if_index_set == 0)
11593     {
11594       sw_if_index = ~0;
11595     }
11596
11597   if (!vam->json_output)
11598     {
11599       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11600              "sw_if_index", "instance", "src_address", "dst_address",
11601              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11602     }
11603
11604   /* Get list of vxlan-tunnel interfaces */
11605   M (VXLAN_TUNNEL_DUMP, mp);
11606
11607   mp->sw_if_index = htonl (sw_if_index);
11608
11609   S (mp);
11610
11611   /* Use a control ping for synchronization */
11612   MPING (CONTROL_PING, mp_ping);
11613   S (mp_ping);
11614
11615   W (ret);
11616   return ret;
11617 }
11618
11619 static int
11620 api_gre_tunnel_add_del (vat_main_t * vam)
11621 {
11622   unformat_input_t *line_input = vam->input;
11623   vl_api_address_t src = { }, dst =
11624   {
11625   };
11626   vl_api_gre_tunnel_add_del_t *mp;
11627   vl_api_gre_tunnel_type_t t_type;
11628   u8 is_add = 1;
11629   u8 src_set = 0;
11630   u8 dst_set = 0;
11631   u32 outer_table_id = 0;
11632   u32 session_id = 0;
11633   u32 instance = ~0;
11634   int ret;
11635
11636   t_type = GRE_API_TUNNEL_TYPE_L3;
11637
11638   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (line_input, "del"))
11641         is_add = 0;
11642       else if (unformat (line_input, "instance %d", &instance))
11643         ;
11644       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
11645         {
11646           src_set = 1;
11647         }
11648       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
11649         {
11650           dst_set = 1;
11651         }
11652       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
11653         ;
11654       else if (unformat (line_input, "teb"))
11655         t_type = GRE_API_TUNNEL_TYPE_TEB;
11656       else if (unformat (line_input, "erspan %d", &session_id))
11657         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
11658       else
11659         {
11660           errmsg ("parse error '%U'", format_unformat_error, line_input);
11661           return -99;
11662         }
11663     }
11664
11665   if (src_set == 0)
11666     {
11667       errmsg ("tunnel src address not specified");
11668       return -99;
11669     }
11670   if (dst_set == 0)
11671     {
11672       errmsg ("tunnel dst address not specified");
11673       return -99;
11674     }
11675
11676   M (GRE_TUNNEL_ADD_DEL, mp);
11677
11678   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
11679   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
11680
11681   mp->tunnel.instance = htonl (instance);
11682   mp->tunnel.outer_table_id = htonl (outer_table_id);
11683   mp->is_add = is_add;
11684   mp->tunnel.session_id = htons ((u16) session_id);
11685   mp->tunnel.type = htonl (t_type);
11686
11687   S (mp);
11688   W (ret);
11689   return ret;
11690 }
11691
11692 static void vl_api_gre_tunnel_details_t_handler
11693   (vl_api_gre_tunnel_details_t * mp)
11694 {
11695   vat_main_t *vam = &vat_main;
11696
11697   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
11698          ntohl (mp->tunnel.sw_if_index),
11699          ntohl (mp->tunnel.instance),
11700          format_vl_api_address, &mp->tunnel.src,
11701          format_vl_api_address, &mp->tunnel.dst,
11702          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
11703          ntohl (mp->tunnel.session_id));
11704 }
11705
11706 static void vl_api_gre_tunnel_details_t_handler_json
11707   (vl_api_gre_tunnel_details_t * mp)
11708 {
11709   vat_main_t *vam = &vat_main;
11710   vat_json_node_t *node = NULL;
11711
11712   if (VAT_JSON_ARRAY != vam->json_tree.type)
11713     {
11714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11715       vat_json_init_array (&vam->json_tree);
11716     }
11717   node = vat_json_array_add (&vam->json_tree);
11718
11719   vat_json_init_object (node);
11720   vat_json_object_add_uint (node, "sw_if_index",
11721                             ntohl (mp->tunnel.sw_if_index));
11722   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
11723
11724   vat_json_object_add_address (node, "src", &mp->tunnel.src);
11725   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
11726   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
11727   vat_json_object_add_uint (node, "outer_table_id",
11728                             ntohl (mp->tunnel.outer_table_id));
11729   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
11730 }
11731
11732 static int
11733 api_gre_tunnel_dump (vat_main_t * vam)
11734 {
11735   unformat_input_t *i = vam->input;
11736   vl_api_gre_tunnel_dump_t *mp;
11737   vl_api_control_ping_t *mp_ping;
11738   u32 sw_if_index;
11739   u8 sw_if_index_set = 0;
11740   int ret;
11741
11742   /* Parse args required to build the message */
11743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11744     {
11745       if (unformat (i, "sw_if_index %d", &sw_if_index))
11746         sw_if_index_set = 1;
11747       else
11748         break;
11749     }
11750
11751   if (sw_if_index_set == 0)
11752     {
11753       sw_if_index = ~0;
11754     }
11755
11756   if (!vam->json_output)
11757     {
11758       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
11759              "sw_if_index", "instance", "src_address", "dst_address",
11760              "tunnel_type", "outer_fib_id", "session_id");
11761     }
11762
11763   /* Get list of gre-tunnel interfaces */
11764   M (GRE_TUNNEL_DUMP, mp);
11765
11766   mp->sw_if_index = htonl (sw_if_index);
11767
11768   S (mp);
11769
11770   /* Use a control ping for synchronization */
11771   MPING (CONTROL_PING, mp_ping);
11772   S (mp_ping);
11773
11774   W (ret);
11775   return ret;
11776 }
11777
11778 static int
11779 api_l2_fib_clear_table (vat_main_t * vam)
11780 {
11781 //  unformat_input_t * i = vam->input;
11782   vl_api_l2_fib_clear_table_t *mp;
11783   int ret;
11784
11785   M (L2_FIB_CLEAR_TABLE, mp);
11786
11787   S (mp);
11788   W (ret);
11789   return ret;
11790 }
11791
11792 static int
11793 api_l2_interface_efp_filter (vat_main_t * vam)
11794 {
11795   unformat_input_t *i = vam->input;
11796   vl_api_l2_interface_efp_filter_t *mp;
11797   u32 sw_if_index;
11798   u8 enable = 1;
11799   u8 sw_if_index_set = 0;
11800   int ret;
11801
11802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11803     {
11804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11807         sw_if_index_set = 1;
11808       else if (unformat (i, "enable"))
11809         enable = 1;
11810       else if (unformat (i, "disable"))
11811         enable = 0;
11812       else
11813         {
11814           clib_warning ("parse error '%U'", format_unformat_error, i);
11815           return -99;
11816         }
11817     }
11818
11819   if (sw_if_index_set == 0)
11820     {
11821       errmsg ("missing sw_if_index");
11822       return -99;
11823     }
11824
11825   M (L2_INTERFACE_EFP_FILTER, mp);
11826
11827   mp->sw_if_index = ntohl (sw_if_index);
11828   mp->enable_disable = enable;
11829
11830   S (mp);
11831   W (ret);
11832   return ret;
11833 }
11834
11835 #define foreach_vtr_op                          \
11836 _("disable",  L2_VTR_DISABLED)                  \
11837 _("push-1",  L2_VTR_PUSH_1)                     \
11838 _("push-2",  L2_VTR_PUSH_2)                     \
11839 _("pop-1",  L2_VTR_POP_1)                       \
11840 _("pop-2",  L2_VTR_POP_2)                       \
11841 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11842 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11843 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11844 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11845
11846 static int
11847 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11848 {
11849   unformat_input_t *i = vam->input;
11850   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11851   u32 sw_if_index;
11852   u8 sw_if_index_set = 0;
11853   u8 vtr_op_set = 0;
11854   u32 vtr_op = 0;
11855   u32 push_dot1q = 1;
11856   u32 tag1 = ~0;
11857   u32 tag2 = ~0;
11858   int ret;
11859
11860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11861     {
11862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11863         sw_if_index_set = 1;
11864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11865         sw_if_index_set = 1;
11866       else if (unformat (i, "vtr_op %d", &vtr_op))
11867         vtr_op_set = 1;
11868 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11869       foreach_vtr_op
11870 #undef _
11871         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11872         ;
11873       else if (unformat (i, "tag1 %d", &tag1))
11874         ;
11875       else if (unformat (i, "tag2 %d", &tag2))
11876         ;
11877       else
11878         {
11879           clib_warning ("parse error '%U'", format_unformat_error, i);
11880           return -99;
11881         }
11882     }
11883
11884   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11885     {
11886       errmsg ("missing vtr operation or sw_if_index");
11887       return -99;
11888     }
11889
11890   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11891   mp->sw_if_index = ntohl (sw_if_index);
11892   mp->vtr_op = ntohl (vtr_op);
11893   mp->push_dot1q = ntohl (push_dot1q);
11894   mp->tag1 = ntohl (tag1);
11895   mp->tag2 = ntohl (tag2);
11896
11897   S (mp);
11898   W (ret);
11899   return ret;
11900 }
11901
11902 static int
11903 api_create_vhost_user_if (vat_main_t * vam)
11904 {
11905   unformat_input_t *i = vam->input;
11906   vl_api_create_vhost_user_if_t *mp;
11907   u8 *file_name;
11908   u8 is_server = 0;
11909   u8 file_name_set = 0;
11910   u32 custom_dev_instance = ~0;
11911   u8 hwaddr[6];
11912   u8 use_custom_mac = 0;
11913   u8 disable_mrg_rxbuf = 0;
11914   u8 disable_indirect_desc = 0;
11915   u8 *tag = 0;
11916   u8 enable_gso = 0;
11917   u8 enable_packed = 0;
11918   int ret;
11919
11920   /* Shut up coverity */
11921   clib_memset (hwaddr, 0, sizeof (hwaddr));
11922
11923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (i, "socket %s", &file_name))
11926         {
11927           file_name_set = 1;
11928         }
11929       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11930         ;
11931       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11932         use_custom_mac = 1;
11933       else if (unformat (i, "server"))
11934         is_server = 1;
11935       else if (unformat (i, "disable_mrg_rxbuf"))
11936         disable_mrg_rxbuf = 1;
11937       else if (unformat (i, "disable_indirect_desc"))
11938         disable_indirect_desc = 1;
11939       else if (unformat (i, "gso"))
11940         enable_gso = 1;
11941       else if (unformat (i, "packed"))
11942         enable_packed = 1;
11943       else if (unformat (i, "tag %s", &tag))
11944         ;
11945       else
11946         break;
11947     }
11948
11949   if (file_name_set == 0)
11950     {
11951       errmsg ("missing socket file name");
11952       return -99;
11953     }
11954
11955   if (vec_len (file_name) > 255)
11956     {
11957       errmsg ("socket file name too long");
11958       return -99;
11959     }
11960   vec_add1 (file_name, 0);
11961
11962   M (CREATE_VHOST_USER_IF, mp);
11963
11964   mp->is_server = is_server;
11965   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
11966   mp->disable_indirect_desc = disable_indirect_desc;
11967   mp->enable_gso = enable_gso;
11968   mp->enable_packed = enable_packed;
11969   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11970   vec_free (file_name);
11971   if (custom_dev_instance != ~0)
11972     {
11973       mp->renumber = 1;
11974       mp->custom_dev_instance = ntohl (custom_dev_instance);
11975     }
11976
11977   mp->use_custom_mac = use_custom_mac;
11978   clib_memcpy (mp->mac_address, hwaddr, 6);
11979   if (tag)
11980     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11981   vec_free (tag);
11982
11983   S (mp);
11984   W (ret);
11985   return ret;
11986 }
11987
11988 static int
11989 api_modify_vhost_user_if (vat_main_t * vam)
11990 {
11991   unformat_input_t *i = vam->input;
11992   vl_api_modify_vhost_user_if_t *mp;
11993   u8 *file_name;
11994   u8 is_server = 0;
11995   u8 file_name_set = 0;
11996   u32 custom_dev_instance = ~0;
11997   u8 sw_if_index_set = 0;
11998   u32 sw_if_index = (u32) ~ 0;
11999   u8 enable_gso = 0;
12000   u8 enable_packed = 0;
12001   int ret;
12002
12003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12004     {
12005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12006         sw_if_index_set = 1;
12007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12008         sw_if_index_set = 1;
12009       else if (unformat (i, "socket %s", &file_name))
12010         {
12011           file_name_set = 1;
12012         }
12013       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12014         ;
12015       else if (unformat (i, "server"))
12016         is_server = 1;
12017       else if (unformat (i, "gso"))
12018         enable_gso = 1;
12019       else if (unformat (i, "packed"))
12020         enable_packed = 1;
12021       else
12022         break;
12023     }
12024
12025   if (sw_if_index_set == 0)
12026     {
12027       errmsg ("missing sw_if_index or interface name");
12028       return -99;
12029     }
12030
12031   if (file_name_set == 0)
12032     {
12033       errmsg ("missing socket file name");
12034       return -99;
12035     }
12036
12037   if (vec_len (file_name) > 255)
12038     {
12039       errmsg ("socket file name too long");
12040       return -99;
12041     }
12042   vec_add1 (file_name, 0);
12043
12044   M (MODIFY_VHOST_USER_IF, mp);
12045
12046   mp->sw_if_index = ntohl (sw_if_index);
12047   mp->is_server = is_server;
12048   mp->enable_gso = enable_gso;
12049   mp->enable_packed = enable_packed;
12050   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12051   vec_free (file_name);
12052   if (custom_dev_instance != ~0)
12053     {
12054       mp->renumber = 1;
12055       mp->custom_dev_instance = ntohl (custom_dev_instance);
12056     }
12057
12058   S (mp);
12059   W (ret);
12060   return ret;
12061 }
12062
12063 static int
12064 api_delete_vhost_user_if (vat_main_t * vam)
12065 {
12066   unformat_input_t *i = vam->input;
12067   vl_api_delete_vhost_user_if_t *mp;
12068   u32 sw_if_index = ~0;
12069   u8 sw_if_index_set = 0;
12070   int ret;
12071
12072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12073     {
12074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12075         sw_if_index_set = 1;
12076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12077         sw_if_index_set = 1;
12078       else
12079         break;
12080     }
12081
12082   if (sw_if_index_set == 0)
12083     {
12084       errmsg ("missing sw_if_index or interface name");
12085       return -99;
12086     }
12087
12088
12089   M (DELETE_VHOST_USER_IF, mp);
12090
12091   mp->sw_if_index = ntohl (sw_if_index);
12092
12093   S (mp);
12094   W (ret);
12095   return ret;
12096 }
12097
12098 static void vl_api_sw_interface_vhost_user_details_t_handler
12099   (vl_api_sw_interface_vhost_user_details_t * mp)
12100 {
12101   vat_main_t *vam = &vat_main;
12102   u64 features;
12103
12104   features =
12105     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12106                                                     clib_net_to_host_u32
12107                                                     (mp->features_last_32) <<
12108                                                     32);
12109
12110   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12111          (char *) mp->interface_name,
12112          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12113          features, mp->is_server,
12114          ntohl (mp->num_regions), (char *) mp->sock_filename);
12115   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12116 }
12117
12118 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12119   (vl_api_sw_interface_vhost_user_details_t * mp)
12120 {
12121   vat_main_t *vam = &vat_main;
12122   vat_json_node_t *node = NULL;
12123
12124   if (VAT_JSON_ARRAY != vam->json_tree.type)
12125     {
12126       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12127       vat_json_init_array (&vam->json_tree);
12128     }
12129   node = vat_json_array_add (&vam->json_tree);
12130
12131   vat_json_init_object (node);
12132   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12133   vat_json_object_add_string_copy (node, "interface_name",
12134                                    mp->interface_name);
12135   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12136                             ntohl (mp->virtio_net_hdr_sz));
12137   vat_json_object_add_uint (node, "features_first_32",
12138                             clib_net_to_host_u32 (mp->features_first_32));
12139   vat_json_object_add_uint (node, "features_last_32",
12140                             clib_net_to_host_u32 (mp->features_last_32));
12141   vat_json_object_add_uint (node, "is_server", mp->is_server);
12142   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12143   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12144   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12145 }
12146
12147 static int
12148 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12149 {
12150   unformat_input_t *i = vam->input;
12151   vl_api_sw_interface_vhost_user_dump_t *mp;
12152   vl_api_control_ping_t *mp_ping;
12153   int ret;
12154   u32 sw_if_index = ~0;
12155
12156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12157     {
12158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12159         ;
12160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12161         ;
12162       else
12163         break;
12164     }
12165
12166   print (vam->ofp,
12167          "Interface name            idx hdr_sz features server regions filename");
12168
12169   /* Get list of vhost-user interfaces */
12170   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12171   mp->sw_if_index = ntohl (sw_if_index);
12172   S (mp);
12173
12174   /* Use a control ping for synchronization */
12175   MPING (CONTROL_PING, mp_ping);
12176   S (mp_ping);
12177
12178   W (ret);
12179   return ret;
12180 }
12181
12182 static int
12183 api_show_version (vat_main_t * vam)
12184 {
12185   vl_api_show_version_t *mp;
12186   int ret;
12187
12188   M (SHOW_VERSION, mp);
12189
12190   S (mp);
12191   W (ret);
12192   return ret;
12193 }
12194
12195
12196 static int
12197 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12198 {
12199   unformat_input_t *line_input = vam->input;
12200   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12201   ip46_address_t local, remote;
12202   u8 is_add = 1;
12203   u8 local_set = 0;
12204   u8 remote_set = 0;
12205   u8 grp_set = 0;
12206   u32 mcast_sw_if_index = ~0;
12207   u32 encap_vrf_id = 0;
12208   u32 decap_vrf_id = 0;
12209   u8 protocol = ~0;
12210   u32 vni;
12211   u8 vni_set = 0;
12212   int ret;
12213
12214   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12215     {
12216       if (unformat (line_input, "del"))
12217         is_add = 0;
12218       else if (unformat (line_input, "local %U",
12219                          unformat_ip46_address, &local))
12220         {
12221           local_set = 1;
12222         }
12223       else if (unformat (line_input, "remote %U",
12224                          unformat_ip46_address, &remote))
12225         {
12226           remote_set = 1;
12227         }
12228       else if (unformat (line_input, "group %U %U",
12229                          unformat_ip46_address, &remote,
12230                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12231         {
12232           grp_set = remote_set = 1;
12233         }
12234       else if (unformat (line_input, "group %U",
12235                          unformat_ip46_address, &remote))
12236         {
12237           grp_set = remote_set = 1;
12238         }
12239       else
12240         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12241         ;
12242       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12243         ;
12244       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12245         ;
12246       else if (unformat (line_input, "vni %d", &vni))
12247         vni_set = 1;
12248       else if (unformat (line_input, "next-ip4"))
12249         protocol = 1;
12250       else if (unformat (line_input, "next-ip6"))
12251         protocol = 2;
12252       else if (unformat (line_input, "next-ethernet"))
12253         protocol = 3;
12254       else if (unformat (line_input, "next-nsh"))
12255         protocol = 4;
12256       else
12257         {
12258           errmsg ("parse error '%U'", format_unformat_error, line_input);
12259           return -99;
12260         }
12261     }
12262
12263   if (local_set == 0)
12264     {
12265       errmsg ("tunnel local address not specified");
12266       return -99;
12267     }
12268   if (remote_set == 0)
12269     {
12270       errmsg ("tunnel remote address not specified");
12271       return -99;
12272     }
12273   if (grp_set && mcast_sw_if_index == ~0)
12274     {
12275       errmsg ("tunnel nonexistent multicast device");
12276       return -99;
12277     }
12278   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12279     {
12280       errmsg ("both IPv4 and IPv6 addresses specified");
12281       return -99;
12282     }
12283
12284   if (vni_set == 0)
12285     {
12286       errmsg ("vni not specified");
12287       return -99;
12288     }
12289
12290   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12291
12292   ip_address_encode (&local,
12293                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12294                      IP46_TYPE_IP6, &mp->local);
12295   ip_address_encode (&remote,
12296                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12297                      IP46_TYPE_IP6, &mp->remote);
12298
12299   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12300   mp->encap_vrf_id = ntohl (encap_vrf_id);
12301   mp->decap_vrf_id = ntohl (decap_vrf_id);
12302   mp->protocol = protocol;
12303   mp->vni = ntohl (vni);
12304   mp->is_add = is_add;
12305
12306   S (mp);
12307   W (ret);
12308   return ret;
12309 }
12310
12311 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12312   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12313 {
12314   vat_main_t *vam = &vat_main;
12315   ip46_address_t local, remote;
12316
12317   ip_address_decode (&mp->local, &local);
12318   ip_address_decode (&mp->remote, &remote);
12319
12320   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12321          ntohl (mp->sw_if_index),
12322          format_ip46_address, &local, IP46_TYPE_ANY,
12323          format_ip46_address, &remote, IP46_TYPE_ANY,
12324          ntohl (mp->vni), mp->protocol,
12325          ntohl (mp->mcast_sw_if_index),
12326          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12327 }
12328
12329
12330 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12331   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12332 {
12333   vat_main_t *vam = &vat_main;
12334   vat_json_node_t *node = NULL;
12335   struct in_addr ip4;
12336   struct in6_addr ip6;
12337   ip46_address_t local, remote;
12338
12339   ip_address_decode (&mp->local, &local);
12340   ip_address_decode (&mp->remote, &remote);
12341
12342   if (VAT_JSON_ARRAY != vam->json_tree.type)
12343     {
12344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12345       vat_json_init_array (&vam->json_tree);
12346     }
12347   node = vat_json_array_add (&vam->json_tree);
12348
12349   vat_json_init_object (node);
12350   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12351   if (ip46_address_is_ip4 (&local))
12352     {
12353       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12354       vat_json_object_add_ip4 (node, "local", ip4);
12355       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12356       vat_json_object_add_ip4 (node, "remote", ip4);
12357     }
12358   else
12359     {
12360       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12361       vat_json_object_add_ip6 (node, "local", ip6);
12362       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12363       vat_json_object_add_ip6 (node, "remote", ip6);
12364     }
12365   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12366   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12367   vat_json_object_add_uint (node, "mcast_sw_if_index",
12368                             ntohl (mp->mcast_sw_if_index));
12369   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12370   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12371   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12372 }
12373
12374 static int
12375 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12379   vl_api_control_ping_t *mp_ping;
12380   u32 sw_if_index;
12381   u8 sw_if_index_set = 0;
12382   int ret;
12383
12384   /* Parse args required to build the message */
12385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12386     {
12387       if (unformat (i, "sw_if_index %d", &sw_if_index))
12388         sw_if_index_set = 1;
12389       else
12390         break;
12391     }
12392
12393   if (sw_if_index_set == 0)
12394     {
12395       sw_if_index = ~0;
12396     }
12397
12398   if (!vam->json_output)
12399     {
12400       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12401              "sw_if_index", "local", "remote", "vni",
12402              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12403     }
12404
12405   /* Get list of vxlan-tunnel interfaces */
12406   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12407
12408   mp->sw_if_index = htonl (sw_if_index);
12409
12410   S (mp);
12411
12412   /* Use a control ping for synchronization */
12413   MPING (CONTROL_PING, mp_ping);
12414   S (mp_ping);
12415
12416   W (ret);
12417   return ret;
12418 }
12419
12420 static void vl_api_l2_fib_table_details_t_handler
12421   (vl_api_l2_fib_table_details_t * mp)
12422 {
12423   vat_main_t *vam = &vat_main;
12424
12425   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12426          "       %d       %d     %d",
12427          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12428          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12429          mp->bvi_mac);
12430 }
12431
12432 static void vl_api_l2_fib_table_details_t_handler_json
12433   (vl_api_l2_fib_table_details_t * mp)
12434 {
12435   vat_main_t *vam = &vat_main;
12436   vat_json_node_t *node = NULL;
12437
12438   if (VAT_JSON_ARRAY != vam->json_tree.type)
12439     {
12440       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12441       vat_json_init_array (&vam->json_tree);
12442     }
12443   node = vat_json_array_add (&vam->json_tree);
12444
12445   vat_json_init_object (node);
12446   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12447   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12449   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12450   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12451   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12452 }
12453
12454 static int
12455 api_l2_fib_table_dump (vat_main_t * vam)
12456 {
12457   unformat_input_t *i = vam->input;
12458   vl_api_l2_fib_table_dump_t *mp;
12459   vl_api_control_ping_t *mp_ping;
12460   u32 bd_id;
12461   u8 bd_id_set = 0;
12462   int ret;
12463
12464   /* Parse args required to build the message */
12465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12466     {
12467       if (unformat (i, "bd_id %d", &bd_id))
12468         bd_id_set = 1;
12469       else
12470         break;
12471     }
12472
12473   if (bd_id_set == 0)
12474     {
12475       errmsg ("missing bridge domain");
12476       return -99;
12477     }
12478
12479   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12480
12481   /* Get list of l2 fib entries */
12482   M (L2_FIB_TABLE_DUMP, mp);
12483
12484   mp->bd_id = ntohl (bd_id);
12485   S (mp);
12486
12487   /* Use a control ping for synchronization */
12488   MPING (CONTROL_PING, mp_ping);
12489   S (mp_ping);
12490
12491   W (ret);
12492   return ret;
12493 }
12494
12495
12496 static int
12497 api_interface_name_renumber (vat_main_t * vam)
12498 {
12499   unformat_input_t *line_input = vam->input;
12500   vl_api_interface_name_renumber_t *mp;
12501   u32 sw_if_index = ~0;
12502   u32 new_show_dev_instance = ~0;
12503   int ret;
12504
12505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12506     {
12507       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12508                     &sw_if_index))
12509         ;
12510       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12511         ;
12512       else if (unformat (line_input, "new_show_dev_instance %d",
12513                          &new_show_dev_instance))
12514         ;
12515       else
12516         break;
12517     }
12518
12519   if (sw_if_index == ~0)
12520     {
12521       errmsg ("missing interface name or sw_if_index");
12522       return -99;
12523     }
12524
12525   if (new_show_dev_instance == ~0)
12526     {
12527       errmsg ("missing new_show_dev_instance");
12528       return -99;
12529     }
12530
12531   M (INTERFACE_NAME_RENUMBER, mp);
12532
12533   mp->sw_if_index = ntohl (sw_if_index);
12534   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12535
12536   S (mp);
12537   W (ret);
12538   return ret;
12539 }
12540
12541 static int
12542 api_want_l2_macs_events (vat_main_t * vam)
12543 {
12544   unformat_input_t *line_input = vam->input;
12545   vl_api_want_l2_macs_events_t *mp;
12546   u8 enable_disable = 1;
12547   u32 scan_delay = 0;
12548   u32 max_macs_in_event = 0;
12549   u32 learn_limit = 0;
12550   int ret;
12551
12552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (line_input, "learn-limit %d", &learn_limit))
12555         ;
12556       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12557         ;
12558       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12559         ;
12560       else if (unformat (line_input, "disable"))
12561         enable_disable = 0;
12562       else
12563         break;
12564     }
12565
12566   M (WANT_L2_MACS_EVENTS, mp);
12567   mp->enable_disable = enable_disable;
12568   mp->pid = htonl (getpid ());
12569   mp->learn_limit = htonl (learn_limit);
12570   mp->scan_delay = (u8) scan_delay;
12571   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12572   S (mp);
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static int
12578 api_input_acl_set_interface (vat_main_t * vam)
12579 {
12580   unformat_input_t *i = vam->input;
12581   vl_api_input_acl_set_interface_t *mp;
12582   u32 sw_if_index;
12583   int sw_if_index_set;
12584   u32 ip4_table_index = ~0;
12585   u32 ip6_table_index = ~0;
12586   u32 l2_table_index = ~0;
12587   u8 is_add = 1;
12588   int ret;
12589
12590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12591     {
12592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12593         sw_if_index_set = 1;
12594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12595         sw_if_index_set = 1;
12596       else if (unformat (i, "del"))
12597         is_add = 0;
12598       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12599         ;
12600       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12601         ;
12602       else if (unformat (i, "l2-table %d", &l2_table_index))
12603         ;
12604       else
12605         {
12606           clib_warning ("parse error '%U'", format_unformat_error, i);
12607           return -99;
12608         }
12609     }
12610
12611   if (sw_if_index_set == 0)
12612     {
12613       errmsg ("missing interface name or sw_if_index");
12614       return -99;
12615     }
12616
12617   M (INPUT_ACL_SET_INTERFACE, mp);
12618
12619   mp->sw_if_index = ntohl (sw_if_index);
12620   mp->ip4_table_index = ntohl (ip4_table_index);
12621   mp->ip6_table_index = ntohl (ip6_table_index);
12622   mp->l2_table_index = ntohl (l2_table_index);
12623   mp->is_add = is_add;
12624
12625   S (mp);
12626   W (ret);
12627   return ret;
12628 }
12629
12630 static int
12631 api_output_acl_set_interface (vat_main_t * vam)
12632 {
12633   unformat_input_t *i = vam->input;
12634   vl_api_output_acl_set_interface_t *mp;
12635   u32 sw_if_index;
12636   int sw_if_index_set;
12637   u32 ip4_table_index = ~0;
12638   u32 ip6_table_index = ~0;
12639   u32 l2_table_index = ~0;
12640   u8 is_add = 1;
12641   int ret;
12642
12643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12644     {
12645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12646         sw_if_index_set = 1;
12647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12648         sw_if_index_set = 1;
12649       else if (unformat (i, "del"))
12650         is_add = 0;
12651       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12652         ;
12653       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12654         ;
12655       else if (unformat (i, "l2-table %d", &l2_table_index))
12656         ;
12657       else
12658         {
12659           clib_warning ("parse error '%U'", format_unformat_error, i);
12660           return -99;
12661         }
12662     }
12663
12664   if (sw_if_index_set == 0)
12665     {
12666       errmsg ("missing interface name or sw_if_index");
12667       return -99;
12668     }
12669
12670   M (OUTPUT_ACL_SET_INTERFACE, mp);
12671
12672   mp->sw_if_index = ntohl (sw_if_index);
12673   mp->ip4_table_index = ntohl (ip4_table_index);
12674   mp->ip6_table_index = ntohl (ip6_table_index);
12675   mp->l2_table_index = ntohl (l2_table_index);
12676   mp->is_add = is_add;
12677
12678   S (mp);
12679   W (ret);
12680   return ret;
12681 }
12682
12683 static int
12684 api_ip_address_dump (vat_main_t * vam)
12685 {
12686   unformat_input_t *i = vam->input;
12687   vl_api_ip_address_dump_t *mp;
12688   vl_api_control_ping_t *mp_ping;
12689   u32 sw_if_index = ~0;
12690   u8 sw_if_index_set = 0;
12691   u8 ipv4_set = 0;
12692   u8 ipv6_set = 0;
12693   int ret;
12694
12695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12696     {
12697       if (unformat (i, "sw_if_index %d", &sw_if_index))
12698         sw_if_index_set = 1;
12699       else
12700         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12701         sw_if_index_set = 1;
12702       else if (unformat (i, "ipv4"))
12703         ipv4_set = 1;
12704       else if (unformat (i, "ipv6"))
12705         ipv6_set = 1;
12706       else
12707         break;
12708     }
12709
12710   if (ipv4_set && ipv6_set)
12711     {
12712       errmsg ("ipv4 and ipv6 flags cannot be both set");
12713       return -99;
12714     }
12715
12716   if ((!ipv4_set) && (!ipv6_set))
12717     {
12718       errmsg ("no ipv4 nor ipv6 flag set");
12719       return -99;
12720     }
12721
12722   if (sw_if_index_set == 0)
12723     {
12724       errmsg ("missing interface name or sw_if_index");
12725       return -99;
12726     }
12727
12728   vam->current_sw_if_index = sw_if_index;
12729   vam->is_ipv6 = ipv6_set;
12730
12731   M (IP_ADDRESS_DUMP, mp);
12732   mp->sw_if_index = ntohl (sw_if_index);
12733   mp->is_ipv6 = ipv6_set;
12734   S (mp);
12735
12736   /* Use a control ping for synchronization */
12737   MPING (CONTROL_PING, mp_ping);
12738   S (mp_ping);
12739
12740   W (ret);
12741   return ret;
12742 }
12743
12744 static int
12745 api_ip_dump (vat_main_t * vam)
12746 {
12747   vl_api_ip_dump_t *mp;
12748   vl_api_control_ping_t *mp_ping;
12749   unformat_input_t *in = vam->input;
12750   int ipv4_set = 0;
12751   int ipv6_set = 0;
12752   int is_ipv6;
12753   int i;
12754   int ret;
12755
12756   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12757     {
12758       if (unformat (in, "ipv4"))
12759         ipv4_set = 1;
12760       else if (unformat (in, "ipv6"))
12761         ipv6_set = 1;
12762       else
12763         break;
12764     }
12765
12766   if (ipv4_set && ipv6_set)
12767     {
12768       errmsg ("ipv4 and ipv6 flags cannot be both set");
12769       return -99;
12770     }
12771
12772   if ((!ipv4_set) && (!ipv6_set))
12773     {
12774       errmsg ("no ipv4 nor ipv6 flag set");
12775       return -99;
12776     }
12777
12778   is_ipv6 = ipv6_set;
12779   vam->is_ipv6 = is_ipv6;
12780
12781   /* free old data */
12782   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12783     {
12784       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12785     }
12786   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12787
12788   M (IP_DUMP, mp);
12789   mp->is_ipv6 = ipv6_set;
12790   S (mp);
12791
12792   /* Use a control ping for synchronization */
12793   MPING (CONTROL_PING, mp_ping);
12794   S (mp_ping);
12795
12796   W (ret);
12797   return ret;
12798 }
12799
12800 static int
12801 api_ipsec_spd_add_del (vat_main_t * vam)
12802 {
12803   unformat_input_t *i = vam->input;
12804   vl_api_ipsec_spd_add_del_t *mp;
12805   u32 spd_id = ~0;
12806   u8 is_add = 1;
12807   int ret;
12808
12809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (i, "spd_id %d", &spd_id))
12812         ;
12813       else if (unformat (i, "del"))
12814         is_add = 0;
12815       else
12816         {
12817           clib_warning ("parse error '%U'", format_unformat_error, i);
12818           return -99;
12819         }
12820     }
12821   if (spd_id == ~0)
12822     {
12823       errmsg ("spd_id must be set");
12824       return -99;
12825     }
12826
12827   M (IPSEC_SPD_ADD_DEL, mp);
12828
12829   mp->spd_id = ntohl (spd_id);
12830   mp->is_add = is_add;
12831
12832   S (mp);
12833   W (ret);
12834   return ret;
12835 }
12836
12837 static int
12838 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12839 {
12840   unformat_input_t *i = vam->input;
12841   vl_api_ipsec_interface_add_del_spd_t *mp;
12842   u32 sw_if_index;
12843   u8 sw_if_index_set = 0;
12844   u32 spd_id = (u32) ~ 0;
12845   u8 is_add = 1;
12846   int ret;
12847
12848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (i, "del"))
12851         is_add = 0;
12852       else if (unformat (i, "spd_id %d", &spd_id))
12853         ;
12854       else
12855         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12856         sw_if_index_set = 1;
12857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12858         sw_if_index_set = 1;
12859       else
12860         {
12861           clib_warning ("parse error '%U'", format_unformat_error, i);
12862           return -99;
12863         }
12864
12865     }
12866
12867   if (spd_id == (u32) ~ 0)
12868     {
12869       errmsg ("spd_id must be set");
12870       return -99;
12871     }
12872
12873   if (sw_if_index_set == 0)
12874     {
12875       errmsg ("missing interface name or sw_if_index");
12876       return -99;
12877     }
12878
12879   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12880
12881   mp->spd_id = ntohl (spd_id);
12882   mp->sw_if_index = ntohl (sw_if_index);
12883   mp->is_add = is_add;
12884
12885   S (mp);
12886   W (ret);
12887   return ret;
12888 }
12889
12890 static int
12891 api_ipsec_spd_entry_add_del (vat_main_t * vam)
12892 {
12893   unformat_input_t *i = vam->input;
12894   vl_api_ipsec_spd_entry_add_del_t *mp;
12895   u8 is_add = 1, is_outbound = 0;
12896   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12897   i32 priority = 0;
12898   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12899   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12900   vl_api_address_t laddr_start = { }, laddr_stop =
12901   {
12902   }, raddr_start =
12903   {
12904   }, raddr_stop =
12905   {
12906   };
12907   int ret;
12908
12909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12910     {
12911       if (unformat (i, "del"))
12912         is_add = 0;
12913       if (unformat (i, "outbound"))
12914         is_outbound = 1;
12915       if (unformat (i, "inbound"))
12916         is_outbound = 0;
12917       else if (unformat (i, "spd_id %d", &spd_id))
12918         ;
12919       else if (unformat (i, "sa_id %d", &sa_id))
12920         ;
12921       else if (unformat (i, "priority %d", &priority))
12922         ;
12923       else if (unformat (i, "protocol %d", &protocol))
12924         ;
12925       else if (unformat (i, "lport_start %d", &lport_start))
12926         ;
12927       else if (unformat (i, "lport_stop %d", &lport_stop))
12928         ;
12929       else if (unformat (i, "rport_start %d", &rport_start))
12930         ;
12931       else if (unformat (i, "rport_stop %d", &rport_stop))
12932         ;
12933       else if (unformat (i, "laddr_start %U",
12934                          unformat_vl_api_address, &laddr_start))
12935         ;
12936       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
12937                          &laddr_stop))
12938         ;
12939       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
12940                          &raddr_start))
12941         ;
12942       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
12943                          &raddr_stop))
12944         ;
12945       else
12946         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12947         {
12948           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12949             {
12950               clib_warning ("unsupported action: 'resolve'");
12951               return -99;
12952             }
12953         }
12954       else
12955         {
12956           clib_warning ("parse error '%U'", format_unformat_error, i);
12957           return -99;
12958         }
12959
12960     }
12961
12962   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
12963
12964   mp->is_add = is_add;
12965
12966   mp->entry.spd_id = ntohl (spd_id);
12967   mp->entry.priority = ntohl (priority);
12968   mp->entry.is_outbound = is_outbound;
12969
12970   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
12971                sizeof (vl_api_address_t));
12972   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
12973                sizeof (vl_api_address_t));
12974   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
12975                sizeof (vl_api_address_t));
12976   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
12977                sizeof (vl_api_address_t));
12978
12979   mp->entry.protocol = (u8) protocol;
12980   mp->entry.local_port_start = ntohs ((u16) lport_start);
12981   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
12982   mp->entry.remote_port_start = ntohs ((u16) rport_start);
12983   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
12984   mp->entry.policy = (u8) policy;
12985   mp->entry.sa_id = ntohl (sa_id);
12986
12987   S (mp);
12988   W (ret);
12989   return ret;
12990 }
12991
12992 static int
12993 api_ipsec_sad_entry_add_del (vat_main_t * vam)
12994 {
12995   unformat_input_t *i = vam->input;
12996   vl_api_ipsec_sad_entry_add_del_t *mp;
12997   u32 sad_id = 0, spi = 0;
12998   u8 *ck = 0, *ik = 0;
12999   u8 is_add = 1;
13000
13001   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13002   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13003   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13004   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13005   vl_api_address_t tun_src, tun_dst;
13006   int ret;
13007
13008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13009     {
13010       if (unformat (i, "del"))
13011         is_add = 0;
13012       else if (unformat (i, "sad_id %d", &sad_id))
13013         ;
13014       else if (unformat (i, "spi %d", &spi))
13015         ;
13016       else if (unformat (i, "esp"))
13017         protocol = IPSEC_API_PROTO_ESP;
13018       else
13019         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13020         {
13021           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13022           if (ADDRESS_IP6 == tun_src.af)
13023             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13024         }
13025       else
13026         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13027         {
13028           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13029           if (ADDRESS_IP6 == tun_src.af)
13030             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13031         }
13032       else
13033         if (unformat (i, "crypto_alg %U",
13034                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13035         ;
13036       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13037         ;
13038       else if (unformat (i, "integ_alg %U",
13039                          unformat_ipsec_api_integ_alg, &integ_alg))
13040         ;
13041       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13042         ;
13043       else
13044         {
13045           clib_warning ("parse error '%U'", format_unformat_error, i);
13046           return -99;
13047         }
13048
13049     }
13050
13051   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13052
13053   mp->is_add = is_add;
13054   mp->entry.sad_id = ntohl (sad_id);
13055   mp->entry.protocol = protocol;
13056   mp->entry.spi = ntohl (spi);
13057   mp->entry.flags = flags;
13058
13059   mp->entry.crypto_algorithm = crypto_alg;
13060   mp->entry.integrity_algorithm = integ_alg;
13061   mp->entry.crypto_key.length = vec_len (ck);
13062   mp->entry.integrity_key.length = vec_len (ik);
13063
13064   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13065     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13066
13067   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13068     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13069
13070   if (ck)
13071     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13072   if (ik)
13073     clib_memcpy (mp->entry.integrity_key.data, ik,
13074                  mp->entry.integrity_key.length);
13075
13076   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13077     {
13078       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13079                    sizeof (mp->entry.tunnel_src));
13080       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13081                    sizeof (mp->entry.tunnel_dst));
13082     }
13083
13084   S (mp);
13085   W (ret);
13086   return ret;
13087 }
13088
13089 static int
13090 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13091 {
13092   unformat_input_t *i = vam->input;
13093   vl_api_ipsec_tunnel_if_add_del_t *mp;
13094   u32 local_spi = 0, remote_spi = 0;
13095   u32 crypto_alg = 0, integ_alg = 0;
13096   u8 *lck = NULL, *rck = NULL;
13097   u8 *lik = NULL, *rik = NULL;
13098   vl_api_address_t local_ip = { 0 };
13099   vl_api_address_t remote_ip = { 0 };
13100   f64 before = 0;
13101   u8 is_add = 1;
13102   u8 esn = 0;
13103   u8 anti_replay = 0;
13104   u8 renumber = 0;
13105   u32 instance = ~0;
13106   u32 count = 1, jj;
13107   int ret = -1;
13108
13109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13110     {
13111       if (unformat (i, "del"))
13112         is_add = 0;
13113       else if (unformat (i, "esn"))
13114         esn = 1;
13115       else if (unformat (i, "anti-replay"))
13116         anti_replay = 1;
13117       else if (unformat (i, "count %d", &count))
13118         ;
13119       else if (unformat (i, "local_spi %d", &local_spi))
13120         ;
13121       else if (unformat (i, "remote_spi %d", &remote_spi))
13122         ;
13123       else
13124         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13125         ;
13126       else
13127         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13128         ;
13129       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13130         ;
13131       else
13132         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13133         ;
13134       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13135         ;
13136       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13137         ;
13138       else
13139         if (unformat
13140             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13141         {
13142           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13143             {
13144               errmsg ("unsupported crypto-alg: '%U'\n",
13145                       format_ipsec_crypto_alg, crypto_alg);
13146               return -99;
13147             }
13148         }
13149       else
13150         if (unformat
13151             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13152         {
13153           if (integ_alg >= IPSEC_INTEG_N_ALG)
13154             {
13155               errmsg ("unsupported integ-alg: '%U'\n",
13156                       format_ipsec_integ_alg, integ_alg);
13157               return -99;
13158             }
13159         }
13160       else if (unformat (i, "instance %u", &instance))
13161         renumber = 1;
13162       else
13163         {
13164           errmsg ("parse error '%U'\n", format_unformat_error, i);
13165           return -99;
13166         }
13167     }
13168
13169   if (count > 1)
13170     {
13171       /* Turn on async mode */
13172       vam->async_mode = 1;
13173       vam->async_errors = 0;
13174       before = vat_time_now (vam);
13175     }
13176
13177   for (jj = 0; jj < count; jj++)
13178     {
13179       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13180
13181       mp->is_add = is_add;
13182       mp->esn = esn;
13183       mp->anti_replay = anti_replay;
13184
13185       if (jj > 0)
13186         increment_address (&remote_ip);
13187
13188       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13189       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13190
13191       mp->local_spi = htonl (local_spi + jj);
13192       mp->remote_spi = htonl (remote_spi + jj);
13193       mp->crypto_alg = (u8) crypto_alg;
13194
13195       mp->local_crypto_key_len = 0;
13196       if (lck)
13197         {
13198           mp->local_crypto_key_len = vec_len (lck);
13199           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13200             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13201           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13202         }
13203
13204       mp->remote_crypto_key_len = 0;
13205       if (rck)
13206         {
13207           mp->remote_crypto_key_len = vec_len (rck);
13208           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13209             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13210           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13211         }
13212
13213       mp->integ_alg = (u8) integ_alg;
13214
13215       mp->local_integ_key_len = 0;
13216       if (lik)
13217         {
13218           mp->local_integ_key_len = vec_len (lik);
13219           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13220             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13221           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13222         }
13223
13224       mp->remote_integ_key_len = 0;
13225       if (rik)
13226         {
13227           mp->remote_integ_key_len = vec_len (rik);
13228           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13229             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13230           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13231         }
13232
13233       if (renumber)
13234         {
13235           mp->renumber = renumber;
13236           mp->show_instance = ntohl (instance);
13237         }
13238       S (mp);
13239     }
13240
13241   /* When testing multiple add/del ops, use a control-ping to sync */
13242   if (count > 1)
13243     {
13244       vl_api_control_ping_t *mp_ping;
13245       f64 after;
13246       f64 timeout;
13247
13248       /* Shut off async mode */
13249       vam->async_mode = 0;
13250
13251       MPING (CONTROL_PING, mp_ping);
13252       S (mp_ping);
13253
13254       timeout = vat_time_now (vam) + 1.0;
13255       while (vat_time_now (vam) < timeout)
13256         if (vam->result_ready == 1)
13257           goto out;
13258       vam->retval = -99;
13259
13260     out:
13261       if (vam->retval == -99)
13262         errmsg ("timeout");
13263
13264       if (vam->async_errors > 0)
13265         {
13266           errmsg ("%d asynchronous errors", vam->async_errors);
13267           vam->retval = -98;
13268         }
13269       vam->async_errors = 0;
13270       after = vat_time_now (vam);
13271
13272       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13273       if (jj > 0)
13274         count = jj;
13275
13276       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13277              count, after - before, count / (after - before));
13278     }
13279   else
13280     {
13281       /* Wait for a reply... */
13282       W (ret);
13283       return ret;
13284     }
13285
13286   return ret;
13287 }
13288
13289 static void
13290 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13291 {
13292   vat_main_t *vam = &vat_main;
13293
13294   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13295          "crypto_key %U integ_alg %u integ_key %U flags %x "
13296          "tunnel_src_addr %U tunnel_dst_addr %U "
13297          "salt %u seq_outbound %lu last_seq_inbound %lu "
13298          "replay_window %lu stat_index %u\n",
13299          ntohl (mp->entry.sad_id),
13300          ntohl (mp->sw_if_index),
13301          ntohl (mp->entry.spi),
13302          ntohl (mp->entry.protocol),
13303          ntohl (mp->entry.crypto_algorithm),
13304          format_hex_bytes, mp->entry.crypto_key.data,
13305          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13306          format_hex_bytes, mp->entry.integrity_key.data,
13307          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13308          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13309          &mp->entry.tunnel_dst, ntohl (mp->salt),
13310          clib_net_to_host_u64 (mp->seq_outbound),
13311          clib_net_to_host_u64 (mp->last_seq_inbound),
13312          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13313 }
13314
13315 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13316 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13317
13318 static void vl_api_ipsec_sa_details_t_handler_json
13319   (vl_api_ipsec_sa_details_t * mp)
13320 {
13321   vat_main_t *vam = &vat_main;
13322   vat_json_node_t *node = NULL;
13323   vl_api_ipsec_sad_flags_t flags;
13324
13325   if (VAT_JSON_ARRAY != vam->json_tree.type)
13326     {
13327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13328       vat_json_init_array (&vam->json_tree);
13329     }
13330   node = vat_json_array_add (&vam->json_tree);
13331
13332   vat_json_init_object (node);
13333   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13334   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13335   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13336   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13337   vat_json_object_add_uint (node, "crypto_alg",
13338                             ntohl (mp->entry.crypto_algorithm));
13339   vat_json_object_add_uint (node, "integ_alg",
13340                             ntohl (mp->entry.integrity_algorithm));
13341   flags = ntohl (mp->entry.flags);
13342   vat_json_object_add_uint (node, "use_esn",
13343                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13344   vat_json_object_add_uint (node, "use_anti_replay",
13345                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13346   vat_json_object_add_uint (node, "is_tunnel",
13347                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13348   vat_json_object_add_uint (node, "is_tunnel_ip6",
13349                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13350   vat_json_object_add_uint (node, "udp_encap",
13351                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13352   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13353                              mp->entry.crypto_key.length);
13354   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13355                              mp->entry.integrity_key.length);
13356   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13357   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13358   vat_json_object_add_uint (node, "replay_window",
13359                             clib_net_to_host_u64 (mp->replay_window));
13360   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13361 }
13362
13363 static int
13364 api_ipsec_sa_dump (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_ipsec_sa_dump_t *mp;
13368   vl_api_control_ping_t *mp_ping;
13369   u32 sa_id = ~0;
13370   int ret;
13371
13372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13373     {
13374       if (unformat (i, "sa_id %d", &sa_id))
13375         ;
13376       else
13377         {
13378           clib_warning ("parse error '%U'", format_unformat_error, i);
13379           return -99;
13380         }
13381     }
13382
13383   M (IPSEC_SA_DUMP, mp);
13384
13385   mp->sa_id = ntohl (sa_id);
13386
13387   S (mp);
13388
13389   /* Use a control ping for synchronization */
13390   M (CONTROL_PING, mp_ping);
13391   S (mp_ping);
13392
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13402   u32 sw_if_index = ~0;
13403   u32 sa_id = ~0;
13404   u8 is_outbound = (u8) ~ 0;
13405   int ret;
13406
13407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13408     {
13409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13410         ;
13411       else if (unformat (i, "sa_id %d", &sa_id))
13412         ;
13413       else if (unformat (i, "outbound"))
13414         is_outbound = 1;
13415       else if (unformat (i, "inbound"))
13416         is_outbound = 0;
13417       else
13418         {
13419           clib_warning ("parse error '%U'", format_unformat_error, i);
13420           return -99;
13421         }
13422     }
13423
13424   if (sw_if_index == ~0)
13425     {
13426       errmsg ("interface must be specified");
13427       return -99;
13428     }
13429
13430   if (sa_id == ~0)
13431     {
13432       errmsg ("SA ID must be specified");
13433       return -99;
13434     }
13435
13436   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13437
13438   mp->sw_if_index = htonl (sw_if_index);
13439   mp->sa_id = htonl (sa_id);
13440   mp->is_outbound = is_outbound;
13441
13442   S (mp);
13443   W (ret);
13444
13445   return ret;
13446 }
13447
13448 static int
13449 api_get_first_msg_id (vat_main_t * vam)
13450 {
13451   vl_api_get_first_msg_id_t *mp;
13452   unformat_input_t *i = vam->input;
13453   u8 *name;
13454   u8 name_set = 0;
13455   int ret;
13456
13457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13458     {
13459       if (unformat (i, "client %s", &name))
13460         name_set = 1;
13461       else
13462         break;
13463     }
13464
13465   if (name_set == 0)
13466     {
13467       errmsg ("missing client name");
13468       return -99;
13469     }
13470   vec_add1 (name, 0);
13471
13472   if (vec_len (name) > 63)
13473     {
13474       errmsg ("client name too long");
13475       return -99;
13476     }
13477
13478   M (GET_FIRST_MSG_ID, mp);
13479   clib_memcpy (mp->name, name, vec_len (name));
13480   S (mp);
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_cop_interface_enable_disable (vat_main_t * vam)
13487 {
13488   unformat_input_t *line_input = vam->input;
13489   vl_api_cop_interface_enable_disable_t *mp;
13490   u32 sw_if_index = ~0;
13491   u8 enable_disable = 1;
13492   int ret;
13493
13494   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13495     {
13496       if (unformat (line_input, "disable"))
13497         enable_disable = 0;
13498       if (unformat (line_input, "enable"))
13499         enable_disable = 1;
13500       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13501                          vam, &sw_if_index))
13502         ;
13503       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13504         ;
13505       else
13506         break;
13507     }
13508
13509   if (sw_if_index == ~0)
13510     {
13511       errmsg ("missing interface name or sw_if_index");
13512       return -99;
13513     }
13514
13515   /* Construct the API message */
13516   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13517   mp->sw_if_index = ntohl (sw_if_index);
13518   mp->enable_disable = enable_disable;
13519
13520   /* send it... */
13521   S (mp);
13522   /* Wait for the reply */
13523   W (ret);
13524   return ret;
13525 }
13526
13527 static int
13528 api_cop_whitelist_enable_disable (vat_main_t * vam)
13529 {
13530   unformat_input_t *line_input = vam->input;
13531   vl_api_cop_whitelist_enable_disable_t *mp;
13532   u32 sw_if_index = ~0;
13533   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13534   u32 fib_id = 0;
13535   int ret;
13536
13537   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13538     {
13539       if (unformat (line_input, "ip4"))
13540         ip4 = 1;
13541       else if (unformat (line_input, "ip6"))
13542         ip6 = 1;
13543       else if (unformat (line_input, "default"))
13544         default_cop = 1;
13545       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13546                          vam, &sw_if_index))
13547         ;
13548       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13549         ;
13550       else if (unformat (line_input, "fib-id %d", &fib_id))
13551         ;
13552       else
13553         break;
13554     }
13555
13556   if (sw_if_index == ~0)
13557     {
13558       errmsg ("missing interface name or sw_if_index");
13559       return -99;
13560     }
13561
13562   /* Construct the API message */
13563   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13564   mp->sw_if_index = ntohl (sw_if_index);
13565   mp->fib_id = ntohl (fib_id);
13566   mp->ip4 = ip4;
13567   mp->ip6 = ip6;
13568   mp->default_cop = default_cop;
13569
13570   /* send it... */
13571   S (mp);
13572   /* Wait for the reply */
13573   W (ret);
13574   return ret;
13575 }
13576
13577 static int
13578 api_get_node_graph (vat_main_t * vam)
13579 {
13580   vl_api_get_node_graph_t *mp;
13581   int ret;
13582
13583   M (GET_NODE_GRAPH, mp);
13584
13585   /* send it... */
13586   S (mp);
13587   /* Wait for the reply */
13588   W (ret);
13589   return ret;
13590 }
13591
13592 /* *INDENT-OFF* */
13593 /** Used for parsing LISP eids */
13594 typedef CLIB_PACKED(struct{
13595   union {
13596           ip46_address_t ip;
13597           mac_address_t mac;
13598           lisp_nsh_api_t nsh;
13599   } addr;
13600   u32 len;       /**< prefix length if IP */
13601   u8 type;      /**< type of eid */
13602 }) lisp_eid_vat_t;
13603 /* *INDENT-ON* */
13604
13605 static uword
13606 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13607 {
13608   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13609
13610   clib_memset (a, 0, sizeof (a[0]));
13611
13612   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
13613     {
13614       a->type = 0;              /* ip prefix type */
13615     }
13616   else if (unformat (input, "%U", unformat_ethernet_address, &a->addr.mac))
13617     {
13618       a->type = 1;              /* mac type */
13619     }
13620   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
13621     {
13622       a->type = 2;              /* NSH type */
13623       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
13624     }
13625   else
13626     {
13627       return 0;
13628     }
13629
13630   if (a->type == 0)
13631     {
13632       if (ip46_address_is_ip4 (&a->addr.ip))
13633         return a->len > 32 ? 1 : 0;
13634       else
13635         return a->len > 128 ? 1 : 0;
13636     }
13637
13638   return 1;
13639 }
13640
13641 static void
13642 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
13643 {
13644   eid->type = vat_eid->type;
13645   switch (eid->type)
13646     {
13647     case EID_TYPE_API_PREFIX:
13648       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
13649         {
13650           clib_memcpy (&eid->address.prefix.address.un.ip4,
13651                        &vat_eid->addr.ip.ip4, 4);
13652           eid->address.prefix.address.af = ADDRESS_IP4;
13653           eid->address.prefix.len = vat_eid->len;
13654         }
13655       else
13656         {
13657           clib_memcpy (&eid->address.prefix.address.un.ip6,
13658                        &vat_eid->addr.ip.ip6, 16);
13659           eid->address.prefix.address.af = ADDRESS_IP6;
13660           eid->address.prefix.len = vat_eid->len;
13661         }
13662       return;
13663     case EID_TYPE_API_MAC:
13664       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
13665                    sizeof (eid->address.mac));
13666       return;
13667     case EID_TYPE_API_NSH:
13668       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
13669                    sizeof (eid->address.nsh));
13670       return;
13671     default:
13672       ASSERT (0);
13673       return;
13674     }
13675 }
13676
13677 static int
13678 api_one_add_del_locator_set (vat_main_t * vam)
13679 {
13680   unformat_input_t *input = vam->input;
13681   vl_api_one_add_del_locator_set_t *mp;
13682   u8 is_add = 1;
13683   u8 *locator_set_name = NULL;
13684   u8 locator_set_name_set = 0;
13685   vl_api_local_locator_t locator, *locators = 0;
13686   u32 sw_if_index, priority, weight;
13687   u32 data_len = 0;
13688
13689   int ret;
13690   /* Parse args required to build the message */
13691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13692     {
13693       if (unformat (input, "del"))
13694         {
13695           is_add = 0;
13696         }
13697       else if (unformat (input, "locator-set %s", &locator_set_name))
13698         {
13699           locator_set_name_set = 1;
13700         }
13701       else if (unformat (input, "sw_if_index %u p %u w %u",
13702                          &sw_if_index, &priority, &weight))
13703         {
13704           locator.sw_if_index = htonl (sw_if_index);
13705           locator.priority = priority;
13706           locator.weight = weight;
13707           vec_add1 (locators, locator);
13708         }
13709       else
13710         if (unformat
13711             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13712              &sw_if_index, &priority, &weight))
13713         {
13714           locator.sw_if_index = htonl (sw_if_index);
13715           locator.priority = priority;
13716           locator.weight = weight;
13717           vec_add1 (locators, locator);
13718         }
13719       else
13720         break;
13721     }
13722
13723   if (locator_set_name_set == 0)
13724     {
13725       errmsg ("missing locator-set name");
13726       vec_free (locators);
13727       return -99;
13728     }
13729
13730   if (vec_len (locator_set_name) > 64)
13731     {
13732       errmsg ("locator-set name too long");
13733       vec_free (locator_set_name);
13734       vec_free (locators);
13735       return -99;
13736     }
13737   vec_add1 (locator_set_name, 0);
13738
13739   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13740
13741   /* Construct the API message */
13742   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13743
13744   mp->is_add = is_add;
13745   clib_memcpy (mp->locator_set_name, locator_set_name,
13746                vec_len (locator_set_name));
13747   vec_free (locator_set_name);
13748
13749   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13750   if (locators)
13751     clib_memcpy (mp->locators, locators, data_len);
13752   vec_free (locators);
13753
13754   /* send it... */
13755   S (mp);
13756
13757   /* Wait for a reply... */
13758   W (ret);
13759   return ret;
13760 }
13761
13762 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13763
13764 static int
13765 api_one_add_del_locator (vat_main_t * vam)
13766 {
13767   unformat_input_t *input = vam->input;
13768   vl_api_one_add_del_locator_t *mp;
13769   u32 tmp_if_index = ~0;
13770   u32 sw_if_index = ~0;
13771   u8 sw_if_index_set = 0;
13772   u8 sw_if_index_if_name_set = 0;
13773   u32 priority = ~0;
13774   u8 priority_set = 0;
13775   u32 weight = ~0;
13776   u8 weight_set = 0;
13777   u8 is_add = 1;
13778   u8 *locator_set_name = NULL;
13779   u8 locator_set_name_set = 0;
13780   int ret;
13781
13782   /* Parse args required to build the message */
13783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13784     {
13785       if (unformat (input, "del"))
13786         {
13787           is_add = 0;
13788         }
13789       else if (unformat (input, "locator-set %s", &locator_set_name))
13790         {
13791           locator_set_name_set = 1;
13792         }
13793       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13794                          &tmp_if_index))
13795         {
13796           sw_if_index_if_name_set = 1;
13797           sw_if_index = tmp_if_index;
13798         }
13799       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13800         {
13801           sw_if_index_set = 1;
13802           sw_if_index = tmp_if_index;
13803         }
13804       else if (unformat (input, "p %d", &priority))
13805         {
13806           priority_set = 1;
13807         }
13808       else if (unformat (input, "w %d", &weight))
13809         {
13810           weight_set = 1;
13811         }
13812       else
13813         break;
13814     }
13815
13816   if (locator_set_name_set == 0)
13817     {
13818       errmsg ("missing locator-set name");
13819       return -99;
13820     }
13821
13822   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13823     {
13824       errmsg ("missing sw_if_index");
13825       vec_free (locator_set_name);
13826       return -99;
13827     }
13828
13829   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13830     {
13831       errmsg ("cannot use both params interface name and sw_if_index");
13832       vec_free (locator_set_name);
13833       return -99;
13834     }
13835
13836   if (priority_set == 0)
13837     {
13838       errmsg ("missing locator-set priority");
13839       vec_free (locator_set_name);
13840       return -99;
13841     }
13842
13843   if (weight_set == 0)
13844     {
13845       errmsg ("missing locator-set weight");
13846       vec_free (locator_set_name);
13847       return -99;
13848     }
13849
13850   if (vec_len (locator_set_name) > 64)
13851     {
13852       errmsg ("locator-set name too long");
13853       vec_free (locator_set_name);
13854       return -99;
13855     }
13856   vec_add1 (locator_set_name, 0);
13857
13858   /* Construct the API message */
13859   M (ONE_ADD_DEL_LOCATOR, mp);
13860
13861   mp->is_add = is_add;
13862   mp->sw_if_index = ntohl (sw_if_index);
13863   mp->priority = priority;
13864   mp->weight = weight;
13865   clib_memcpy (mp->locator_set_name, locator_set_name,
13866                vec_len (locator_set_name));
13867   vec_free (locator_set_name);
13868
13869   /* send it... */
13870   S (mp);
13871
13872   /* Wait for a reply... */
13873   W (ret);
13874   return ret;
13875 }
13876
13877 #define api_lisp_add_del_locator api_one_add_del_locator
13878
13879 uword
13880 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13881 {
13882   u32 *key_id = va_arg (*args, u32 *);
13883   u8 *s = 0;
13884
13885   if (unformat (input, "%s", &s))
13886     {
13887       if (!strcmp ((char *) s, "sha1"))
13888         key_id[0] = HMAC_SHA_1_96;
13889       else if (!strcmp ((char *) s, "sha256"))
13890         key_id[0] = HMAC_SHA_256_128;
13891       else
13892         {
13893           clib_warning ("invalid key_id: '%s'", s);
13894           key_id[0] = HMAC_NO_KEY;
13895         }
13896     }
13897   else
13898     return 0;
13899
13900   vec_free (s);
13901   return 1;
13902 }
13903
13904 static int
13905 api_one_add_del_local_eid (vat_main_t * vam)
13906 {
13907   unformat_input_t *input = vam->input;
13908   vl_api_one_add_del_local_eid_t *mp;
13909   u8 is_add = 1;
13910   u8 eid_set = 0;
13911   lisp_eid_vat_t _eid, *eid = &_eid;
13912   u8 *locator_set_name = 0;
13913   u8 locator_set_name_set = 0;
13914   u32 vni = 0;
13915   u16 key_id = 0;
13916   u8 *key = 0;
13917   int ret;
13918
13919   /* Parse args required to build the message */
13920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13921     {
13922       if (unformat (input, "del"))
13923         {
13924           is_add = 0;
13925         }
13926       else if (unformat (input, "vni %d", &vni))
13927         {
13928           ;
13929         }
13930       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13931         {
13932           eid_set = 1;
13933         }
13934       else if (unformat (input, "locator-set %s", &locator_set_name))
13935         {
13936           locator_set_name_set = 1;
13937         }
13938       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13939         ;
13940       else if (unformat (input, "secret-key %_%v%_", &key))
13941         ;
13942       else
13943         break;
13944     }
13945
13946   if (locator_set_name_set == 0)
13947     {
13948       errmsg ("missing locator-set name");
13949       return -99;
13950     }
13951
13952   if (0 == eid_set)
13953     {
13954       errmsg ("EID address not set!");
13955       vec_free (locator_set_name);
13956       return -99;
13957     }
13958
13959   if (key && (0 == key_id))
13960     {
13961       errmsg ("invalid key_id!");
13962       return -99;
13963     }
13964
13965   if (vec_len (key) > 64)
13966     {
13967       errmsg ("key too long");
13968       vec_free (key);
13969       return -99;
13970     }
13971
13972   if (vec_len (locator_set_name) > 64)
13973     {
13974       errmsg ("locator-set name too long");
13975       vec_free (locator_set_name);
13976       return -99;
13977     }
13978   vec_add1 (locator_set_name, 0);
13979
13980   /* Construct the API message */
13981   M (ONE_ADD_DEL_LOCAL_EID, mp);
13982
13983   mp->is_add = is_add;
13984   lisp_eid_put_vat (&mp->eid, eid);
13985   mp->vni = clib_host_to_net_u32 (vni);
13986   mp->key.id = key_id;
13987   clib_memcpy (mp->locator_set_name, locator_set_name,
13988                vec_len (locator_set_name));
13989   clib_memcpy (mp->key.key, key, vec_len (key));
13990
13991   vec_free (locator_set_name);
13992   vec_free (key);
13993
13994   /* send it... */
13995   S (mp);
13996
13997   /* Wait for a reply... */
13998   W (ret);
13999   return ret;
14000 }
14001
14002 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14003
14004 static int
14005 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14006 {
14007   u32 dp_table = 0, vni = 0;;
14008   unformat_input_t *input = vam->input;
14009   vl_api_gpe_add_del_fwd_entry_t *mp;
14010   u8 is_add = 1;
14011   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14012   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14013   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14014   u32 action = ~0, w;
14015   ip4_address_t rmt_rloc4, lcl_rloc4;
14016   ip6_address_t rmt_rloc6, lcl_rloc6;
14017   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14018   int ret;
14019
14020   clib_memset (&rloc, 0, sizeof (rloc));
14021
14022   /* Parse args required to build the message */
14023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14024     {
14025       if (unformat (input, "del"))
14026         is_add = 0;
14027       else if (unformat (input, "add"))
14028         is_add = 1;
14029       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14030         {
14031           rmt_eid_set = 1;
14032         }
14033       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14034         {
14035           lcl_eid_set = 1;
14036         }
14037       else if (unformat (input, "vrf %d", &dp_table))
14038         ;
14039       else if (unformat (input, "bd %d", &dp_table))
14040         ;
14041       else if (unformat (input, "vni %d", &vni))
14042         ;
14043       else if (unformat (input, "w %d", &w))
14044         {
14045           if (!curr_rloc)
14046             {
14047               errmsg ("No RLOC configured for setting priority/weight!");
14048               return -99;
14049             }
14050           curr_rloc->weight = w;
14051         }
14052       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14053                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14054         {
14055           rloc.addr.af = 0;
14056           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14057           rloc.weight = 0;
14058           vec_add1 (lcl_locs, rloc);
14059
14060           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14061           vec_add1 (rmt_locs, rloc);
14062           /* weight saved in rmt loc */
14063           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14064         }
14065       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14066                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14067         {
14068           rloc.addr.af = 1;
14069           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14070           rloc.weight = 0;
14071           vec_add1 (lcl_locs, rloc);
14072
14073           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14074           vec_add1 (rmt_locs, rloc);
14075           /* weight saved in rmt loc */
14076           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14077         }
14078       else if (unformat (input, "action %d", &action))
14079         {
14080           ;
14081         }
14082       else
14083         {
14084           clib_warning ("parse error '%U'", format_unformat_error, input);
14085           return -99;
14086         }
14087     }
14088
14089   if (!rmt_eid_set)
14090     {
14091       errmsg ("remote eid addresses not set");
14092       return -99;
14093     }
14094
14095   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14096     {
14097       errmsg ("eid types don't match");
14098       return -99;
14099     }
14100
14101   if (0 == rmt_locs && (u32) ~ 0 == action)
14102     {
14103       errmsg ("action not set for negative mapping");
14104       return -99;
14105     }
14106
14107   /* Construct the API message */
14108   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14109       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14110
14111   mp->is_add = is_add;
14112   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14113   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14114   mp->dp_table = clib_host_to_net_u32 (dp_table);
14115   mp->vni = clib_host_to_net_u32 (vni);
14116   mp->action = action;
14117
14118   if (0 != rmt_locs && 0 != lcl_locs)
14119     {
14120       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14121       clib_memcpy (mp->locs, lcl_locs,
14122                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14123
14124       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14125       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14126                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14127     }
14128   vec_free (lcl_locs);
14129   vec_free (rmt_locs);
14130
14131   /* send it... */
14132   S (mp);
14133
14134   /* Wait for a reply... */
14135   W (ret);
14136   return ret;
14137 }
14138
14139 static int
14140 api_one_add_del_map_server (vat_main_t * vam)
14141 {
14142   unformat_input_t *input = vam->input;
14143   vl_api_one_add_del_map_server_t *mp;
14144   u8 is_add = 1;
14145   u8 ipv4_set = 0;
14146   u8 ipv6_set = 0;
14147   ip4_address_t ipv4;
14148   ip6_address_t ipv6;
14149   int ret;
14150
14151   /* Parse args required to build the message */
14152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14153     {
14154       if (unformat (input, "del"))
14155         {
14156           is_add = 0;
14157         }
14158       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14159         {
14160           ipv4_set = 1;
14161         }
14162       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14163         {
14164           ipv6_set = 1;
14165         }
14166       else
14167         break;
14168     }
14169
14170   if (ipv4_set && ipv6_set)
14171     {
14172       errmsg ("both eid v4 and v6 addresses set");
14173       return -99;
14174     }
14175
14176   if (!ipv4_set && !ipv6_set)
14177     {
14178       errmsg ("eid addresses not set");
14179       return -99;
14180     }
14181
14182   /* Construct the API message */
14183   M (ONE_ADD_DEL_MAP_SERVER, mp);
14184
14185   mp->is_add = is_add;
14186   if (ipv6_set)
14187     {
14188       mp->ip_address.af = 1;
14189       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14190     }
14191   else
14192     {
14193       mp->ip_address.af = 0;
14194       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14195     }
14196
14197   /* send it... */
14198   S (mp);
14199
14200   /* Wait for a reply... */
14201   W (ret);
14202   return ret;
14203 }
14204
14205 #define api_lisp_add_del_map_server api_one_add_del_map_server
14206
14207 static int
14208 api_one_add_del_map_resolver (vat_main_t * vam)
14209 {
14210   unformat_input_t *input = vam->input;
14211   vl_api_one_add_del_map_resolver_t *mp;
14212   u8 is_add = 1;
14213   u8 ipv4_set = 0;
14214   u8 ipv6_set = 0;
14215   ip4_address_t ipv4;
14216   ip6_address_t ipv6;
14217   int ret;
14218
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, "%U", unformat_ip4_address, &ipv4))
14227         {
14228           ipv4_set = 1;
14229         }
14230       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14231         {
14232           ipv6_set = 1;
14233         }
14234       else
14235         break;
14236     }
14237
14238   if (ipv4_set && ipv6_set)
14239     {
14240       errmsg ("both eid v4 and v6 addresses set");
14241       return -99;
14242     }
14243
14244   if (!ipv4_set && !ipv6_set)
14245     {
14246       errmsg ("eid addresses not set");
14247       return -99;
14248     }
14249
14250   /* Construct the API message */
14251   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14252
14253   mp->is_add = is_add;
14254   if (ipv6_set)
14255     {
14256       mp->ip_address.af = 1;
14257       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14258     }
14259   else
14260     {
14261       mp->ip_address.af = 0;
14262       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14263     }
14264
14265   /* send it... */
14266   S (mp);
14267
14268   /* Wait for a reply... */
14269   W (ret);
14270   return ret;
14271 }
14272
14273 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14274
14275 static int
14276 api_lisp_gpe_enable_disable (vat_main_t * vam)
14277 {
14278   unformat_input_t *input = vam->input;
14279   vl_api_gpe_enable_disable_t *mp;
14280   u8 is_set = 0;
14281   u8 is_enable = 1;
14282   int ret;
14283
14284   /* Parse args required to build the message */
14285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14286     {
14287       if (unformat (input, "enable"))
14288         {
14289           is_set = 1;
14290           is_enable = 1;
14291         }
14292       else if (unformat (input, "disable"))
14293         {
14294           is_set = 1;
14295           is_enable = 0;
14296         }
14297       else
14298         break;
14299     }
14300
14301   if (is_set == 0)
14302     {
14303       errmsg ("Value not set");
14304       return -99;
14305     }
14306
14307   /* Construct the API message */
14308   M (GPE_ENABLE_DISABLE, mp);
14309
14310   mp->is_enable = is_enable;
14311
14312   /* send it... */
14313   S (mp);
14314
14315   /* Wait for a reply... */
14316   W (ret);
14317   return ret;
14318 }
14319
14320 static int
14321 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14322 {
14323   unformat_input_t *input = vam->input;
14324   vl_api_one_rloc_probe_enable_disable_t *mp;
14325   u8 is_set = 0;
14326   u8 is_enable = 0;
14327   int ret;
14328
14329   /* Parse args required to build the message */
14330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14331     {
14332       if (unformat (input, "enable"))
14333         {
14334           is_set = 1;
14335           is_enable = 1;
14336         }
14337       else if (unformat (input, "disable"))
14338         is_set = 1;
14339       else
14340         break;
14341     }
14342
14343   if (!is_set)
14344     {
14345       errmsg ("Value not set");
14346       return -99;
14347     }
14348
14349   /* Construct the API message */
14350   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14351
14352   mp->is_enable = is_enable;
14353
14354   /* send it... */
14355   S (mp);
14356
14357   /* Wait for a reply... */
14358   W (ret);
14359   return ret;
14360 }
14361
14362 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14363
14364 static int
14365 api_one_map_register_enable_disable (vat_main_t * vam)
14366 {
14367   unformat_input_t *input = vam->input;
14368   vl_api_one_map_register_enable_disable_t *mp;
14369   u8 is_set = 0;
14370   u8 is_enable = 0;
14371   int ret;
14372
14373   /* Parse args required to build the message */
14374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14375     {
14376       if (unformat (input, "enable"))
14377         {
14378           is_set = 1;
14379           is_enable = 1;
14380         }
14381       else if (unformat (input, "disable"))
14382         is_set = 1;
14383       else
14384         break;
14385     }
14386
14387   if (!is_set)
14388     {
14389       errmsg ("Value not set");
14390       return -99;
14391     }
14392
14393   /* Construct the API message */
14394   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14395
14396   mp->is_enable = is_enable;
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_map_register_enable_disable api_one_map_register_enable_disable
14407
14408 static int
14409 api_one_enable_disable (vat_main_t * vam)
14410 {
14411   unformat_input_t *input = vam->input;
14412   vl_api_one_enable_disable_t *mp;
14413   u8 is_set = 0;
14414   u8 is_enable = 0;
14415   int ret;
14416
14417   /* Parse args required to build the message */
14418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14419     {
14420       if (unformat (input, "enable"))
14421         {
14422           is_set = 1;
14423           is_enable = 1;
14424         }
14425       else if (unformat (input, "disable"))
14426         {
14427           is_set = 1;
14428         }
14429       else
14430         break;
14431     }
14432
14433   if (!is_set)
14434     {
14435       errmsg ("Value not set");
14436       return -99;
14437     }
14438
14439   /* Construct the API message */
14440   M (ONE_ENABLE_DISABLE, mp);
14441
14442   mp->is_enable = is_enable;
14443
14444   /* send it... */
14445   S (mp);
14446
14447   /* Wait for a reply... */
14448   W (ret);
14449   return ret;
14450 }
14451
14452 #define api_lisp_enable_disable api_one_enable_disable
14453
14454 static int
14455 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14456 {
14457   unformat_input_t *input = vam->input;
14458   vl_api_one_enable_disable_xtr_mode_t *mp;
14459   u8 is_set = 0;
14460   u8 is_enable = 0;
14461   int ret;
14462
14463   /* Parse args required to build the message */
14464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14465     {
14466       if (unformat (input, "enable"))
14467         {
14468           is_set = 1;
14469           is_enable = 1;
14470         }
14471       else if (unformat (input, "disable"))
14472         {
14473           is_set = 1;
14474         }
14475       else
14476         break;
14477     }
14478
14479   if (!is_set)
14480     {
14481       errmsg ("Value not set");
14482       return -99;
14483     }
14484
14485   /* Construct the API message */
14486   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14487
14488   mp->is_enable = is_enable;
14489
14490   /* send it... */
14491   S (mp);
14492
14493   /* Wait for a reply... */
14494   W (ret);
14495   return ret;
14496 }
14497
14498 static int
14499 api_one_show_xtr_mode (vat_main_t * vam)
14500 {
14501   vl_api_one_show_xtr_mode_t *mp;
14502   int ret;
14503
14504   /* Construct the API message */
14505   M (ONE_SHOW_XTR_MODE, mp);
14506
14507   /* send it... */
14508   S (mp);
14509
14510   /* Wait for a reply... */
14511   W (ret);
14512   return ret;
14513 }
14514
14515 static int
14516 api_one_enable_disable_pitr_mode (vat_main_t * vam)
14517 {
14518   unformat_input_t *input = vam->input;
14519   vl_api_one_enable_disable_pitr_mode_t *mp;
14520   u8 is_set = 0;
14521   u8 is_enable = 0;
14522   int ret;
14523
14524   /* Parse args required to build the message */
14525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14526     {
14527       if (unformat (input, "enable"))
14528         {
14529           is_set = 1;
14530           is_enable = 1;
14531         }
14532       else if (unformat (input, "disable"))
14533         {
14534           is_set = 1;
14535         }
14536       else
14537         break;
14538     }
14539
14540   if (!is_set)
14541     {
14542       errmsg ("Value not set");
14543       return -99;
14544     }
14545
14546   /* Construct the API message */
14547   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
14548
14549   mp->is_enable = is_enable;
14550
14551   /* send it... */
14552   S (mp);
14553
14554   /* Wait for a reply... */
14555   W (ret);
14556   return ret;
14557 }
14558
14559 static int
14560 api_one_show_pitr_mode (vat_main_t * vam)
14561 {
14562   vl_api_one_show_pitr_mode_t *mp;
14563   int ret;
14564
14565   /* Construct the API message */
14566   M (ONE_SHOW_PITR_MODE, mp);
14567
14568   /* send it... */
14569   S (mp);
14570
14571   /* Wait for a reply... */
14572   W (ret);
14573   return ret;
14574 }
14575
14576 static int
14577 api_one_enable_disable_petr_mode (vat_main_t * vam)
14578 {
14579   unformat_input_t *input = vam->input;
14580   vl_api_one_enable_disable_petr_mode_t *mp;
14581   u8 is_set = 0;
14582   u8 is_enable = 0;
14583   int ret;
14584
14585   /* Parse args required to build the message */
14586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14587     {
14588       if (unformat (input, "enable"))
14589         {
14590           is_set = 1;
14591           is_enable = 1;
14592         }
14593       else if (unformat (input, "disable"))
14594         {
14595           is_set = 1;
14596         }
14597       else
14598         break;
14599     }
14600
14601   if (!is_set)
14602     {
14603       errmsg ("Value not set");
14604       return -99;
14605     }
14606
14607   /* Construct the API message */
14608   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
14609
14610   mp->is_enable = is_enable;
14611
14612   /* send it... */
14613   S (mp);
14614
14615   /* Wait for a reply... */
14616   W (ret);
14617   return ret;
14618 }
14619
14620 static int
14621 api_one_show_petr_mode (vat_main_t * vam)
14622 {
14623   vl_api_one_show_petr_mode_t *mp;
14624   int ret;
14625
14626   /* Construct the API message */
14627   M (ONE_SHOW_PETR_MODE, mp);
14628
14629   /* send it... */
14630   S (mp);
14631
14632   /* Wait for a reply... */
14633   W (ret);
14634   return ret;
14635 }
14636
14637 static int
14638 api_show_one_map_register_state (vat_main_t * vam)
14639 {
14640   vl_api_show_one_map_register_state_t *mp;
14641   int ret;
14642
14643   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14644
14645   /* send */
14646   S (mp);
14647
14648   /* wait for reply */
14649   W (ret);
14650   return ret;
14651 }
14652
14653 #define api_show_lisp_map_register_state api_show_one_map_register_state
14654
14655 static int
14656 api_show_one_rloc_probe_state (vat_main_t * vam)
14657 {
14658   vl_api_show_one_rloc_probe_state_t *mp;
14659   int ret;
14660
14661   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14662
14663   /* send */
14664   S (mp);
14665
14666   /* wait for reply */
14667   W (ret);
14668   return ret;
14669 }
14670
14671 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14672
14673 static int
14674 api_one_add_del_ndp_entry (vat_main_t * vam)
14675 {
14676   vl_api_one_add_del_ndp_entry_t *mp;
14677   unformat_input_t *input = vam->input;
14678   u8 is_add = 1;
14679   u8 mac_set = 0;
14680   u8 bd_set = 0;
14681   u8 ip_set = 0;
14682   u8 mac[6] = { 0, };
14683   u8 ip6[16] = { 0, };
14684   u32 bd = ~0;
14685   int ret;
14686
14687   /* Parse args required to build the message */
14688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14689     {
14690       if (unformat (input, "del"))
14691         is_add = 0;
14692       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
14693         mac_set = 1;
14694       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
14695         ip_set = 1;
14696       else if (unformat (input, "bd %d", &bd))
14697         bd_set = 1;
14698       else
14699         {
14700           errmsg ("parse error '%U'", format_unformat_error, input);
14701           return -99;
14702         }
14703     }
14704
14705   if (!bd_set || !ip_set || (!mac_set && is_add))
14706     {
14707       errmsg ("Missing BD, IP or MAC!");
14708       return -99;
14709     }
14710
14711   M (ONE_ADD_DEL_NDP_ENTRY, mp);
14712   mp->is_add = is_add;
14713   clib_memcpy (&mp->entry.mac, mac, 6);
14714   mp->bd = clib_host_to_net_u32 (bd);
14715   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
14716
14717   /* send */
14718   S (mp);
14719
14720   /* wait for reply */
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_one_add_del_l2_arp_entry (vat_main_t * vam)
14727 {
14728   vl_api_one_add_del_l2_arp_entry_t *mp;
14729   unformat_input_t *input = vam->input;
14730   u8 is_add = 1;
14731   u8 mac_set = 0;
14732   u8 bd_set = 0;
14733   u8 ip_set = 0;
14734   u8 mac[6] = { 0, };
14735   u32 ip4 = 0, bd = ~0;
14736   int ret;
14737
14738   /* Parse args required to build the message */
14739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14740     {
14741       if (unformat (input, "del"))
14742         is_add = 0;
14743       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
14744         mac_set = 1;
14745       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
14746         ip_set = 1;
14747       else if (unformat (input, "bd %d", &bd))
14748         bd_set = 1;
14749       else
14750         {
14751           errmsg ("parse error '%U'", format_unformat_error, input);
14752           return -99;
14753         }
14754     }
14755
14756   if (!bd_set || !ip_set || (!mac_set && is_add))
14757     {
14758       errmsg ("Missing BD, IP or MAC!");
14759       return -99;
14760     }
14761
14762   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
14763   mp->is_add = is_add;
14764   clib_memcpy (&mp->entry.mac, mac, 6);
14765   mp->bd = clib_host_to_net_u32 (bd);
14766   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
14767
14768   /* send */
14769   S (mp);
14770
14771   /* wait for reply */
14772   W (ret);
14773   return ret;
14774 }
14775
14776 static int
14777 api_one_ndp_bd_get (vat_main_t * vam)
14778 {
14779   vl_api_one_ndp_bd_get_t *mp;
14780   int ret;
14781
14782   M (ONE_NDP_BD_GET, mp);
14783
14784   /* send */
14785   S (mp);
14786
14787   /* wait for reply */
14788   W (ret);
14789   return ret;
14790 }
14791
14792 static int
14793 api_one_ndp_entries_get (vat_main_t * vam)
14794 {
14795   vl_api_one_ndp_entries_get_t *mp;
14796   unformat_input_t *input = vam->input;
14797   u8 bd_set = 0;
14798   u32 bd = ~0;
14799   int ret;
14800
14801   /* Parse args required to build the message */
14802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14803     {
14804       if (unformat (input, "bd %d", &bd))
14805         bd_set = 1;
14806       else
14807         {
14808           errmsg ("parse error '%U'", format_unformat_error, input);
14809           return -99;
14810         }
14811     }
14812
14813   if (!bd_set)
14814     {
14815       errmsg ("Expected bridge domain!");
14816       return -99;
14817     }
14818
14819   M (ONE_NDP_ENTRIES_GET, mp);
14820   mp->bd = clib_host_to_net_u32 (bd);
14821
14822   /* send */
14823   S (mp);
14824
14825   /* wait for reply */
14826   W (ret);
14827   return ret;
14828 }
14829
14830 static int
14831 api_one_l2_arp_bd_get (vat_main_t * vam)
14832 {
14833   vl_api_one_l2_arp_bd_get_t *mp;
14834   int ret;
14835
14836   M (ONE_L2_ARP_BD_GET, mp);
14837
14838   /* send */
14839   S (mp);
14840
14841   /* wait for reply */
14842   W (ret);
14843   return ret;
14844 }
14845
14846 static int
14847 api_one_l2_arp_entries_get (vat_main_t * vam)
14848 {
14849   vl_api_one_l2_arp_entries_get_t *mp;
14850   unformat_input_t *input = vam->input;
14851   u8 bd_set = 0;
14852   u32 bd = ~0;
14853   int ret;
14854
14855   /* Parse args required to build the message */
14856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14857     {
14858       if (unformat (input, "bd %d", &bd))
14859         bd_set = 1;
14860       else
14861         {
14862           errmsg ("parse error '%U'", format_unformat_error, input);
14863           return -99;
14864         }
14865     }
14866
14867   if (!bd_set)
14868     {
14869       errmsg ("Expected bridge domain!");
14870       return -99;
14871     }
14872
14873   M (ONE_L2_ARP_ENTRIES_GET, mp);
14874   mp->bd = clib_host_to_net_u32 (bd);
14875
14876   /* send */
14877   S (mp);
14878
14879   /* wait for reply */
14880   W (ret);
14881   return ret;
14882 }
14883
14884 static int
14885 api_one_stats_enable_disable (vat_main_t * vam)
14886 {
14887   vl_api_one_stats_enable_disable_t *mp;
14888   unformat_input_t *input = vam->input;
14889   u8 is_set = 0;
14890   u8 is_enable = 0;
14891   int ret;
14892
14893   /* Parse args required to build the message */
14894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14895     {
14896       if (unformat (input, "enable"))
14897         {
14898           is_set = 1;
14899           is_enable = 1;
14900         }
14901       else if (unformat (input, "disable"))
14902         {
14903           is_set = 1;
14904         }
14905       else
14906         break;
14907     }
14908
14909   if (!is_set)
14910     {
14911       errmsg ("Value not set");
14912       return -99;
14913     }
14914
14915   M (ONE_STATS_ENABLE_DISABLE, mp);
14916   mp->is_enable = is_enable;
14917
14918   /* send */
14919   S (mp);
14920
14921   /* wait for reply */
14922   W (ret);
14923   return ret;
14924 }
14925
14926 static int
14927 api_show_one_stats_enable_disable (vat_main_t * vam)
14928 {
14929   vl_api_show_one_stats_enable_disable_t *mp;
14930   int ret;
14931
14932   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14933
14934   /* send */
14935   S (mp);
14936
14937   /* wait for reply */
14938   W (ret);
14939   return ret;
14940 }
14941
14942 static int
14943 api_show_one_map_request_mode (vat_main_t * vam)
14944 {
14945   vl_api_show_one_map_request_mode_t *mp;
14946   int ret;
14947
14948   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14949
14950   /* send */
14951   S (mp);
14952
14953   /* wait for reply */
14954   W (ret);
14955   return ret;
14956 }
14957
14958 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14959
14960 static int
14961 api_one_map_request_mode (vat_main_t * vam)
14962 {
14963   unformat_input_t *input = vam->input;
14964   vl_api_one_map_request_mode_t *mp;
14965   u8 mode = 0;
14966   int ret;
14967
14968   /* Parse args required to build the message */
14969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14970     {
14971       if (unformat (input, "dst-only"))
14972         mode = 0;
14973       else if (unformat (input, "src-dst"))
14974         mode = 1;
14975       else
14976         {
14977           errmsg ("parse error '%U'", format_unformat_error, input);
14978           return -99;
14979         }
14980     }
14981
14982   M (ONE_MAP_REQUEST_MODE, mp);
14983
14984   mp->mode = mode;
14985
14986   /* send */
14987   S (mp);
14988
14989   /* wait for reply */
14990   W (ret);
14991   return ret;
14992 }
14993
14994 #define api_lisp_map_request_mode api_one_map_request_mode
14995
14996 /**
14997  * Enable/disable ONE proxy ITR.
14998  *
14999  * @param vam vpp API test context
15000  * @return return code
15001  */
15002 static int
15003 api_one_pitr_set_locator_set (vat_main_t * vam)
15004 {
15005   u8 ls_name_set = 0;
15006   unformat_input_t *input = vam->input;
15007   vl_api_one_pitr_set_locator_set_t *mp;
15008   u8 is_add = 1;
15009   u8 *ls_name = 0;
15010   int ret;
15011
15012   /* Parse args required to build the message */
15013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15014     {
15015       if (unformat (input, "del"))
15016         is_add = 0;
15017       else if (unformat (input, "locator-set %s", &ls_name))
15018         ls_name_set = 1;
15019       else
15020         {
15021           errmsg ("parse error '%U'", format_unformat_error, input);
15022           return -99;
15023         }
15024     }
15025
15026   if (!ls_name_set)
15027     {
15028       errmsg ("locator-set name not set!");
15029       return -99;
15030     }
15031
15032   M (ONE_PITR_SET_LOCATOR_SET, mp);
15033
15034   mp->is_add = is_add;
15035   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15036   vec_free (ls_name);
15037
15038   /* send */
15039   S (mp);
15040
15041   /* wait for reply */
15042   W (ret);
15043   return ret;
15044 }
15045
15046 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15047
15048 static int
15049 api_one_nsh_set_locator_set (vat_main_t * vam)
15050 {
15051   u8 ls_name_set = 0;
15052   unformat_input_t *input = vam->input;
15053   vl_api_one_nsh_set_locator_set_t *mp;
15054   u8 is_add = 1;
15055   u8 *ls_name = 0;
15056   int ret;
15057
15058   /* Parse args required to build the message */
15059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15060     {
15061       if (unformat (input, "del"))
15062         is_add = 0;
15063       else if (unformat (input, "ls %s", &ls_name))
15064         ls_name_set = 1;
15065       else
15066         {
15067           errmsg ("parse error '%U'", format_unformat_error, input);
15068           return -99;
15069         }
15070     }
15071
15072   if (!ls_name_set && is_add)
15073     {
15074       errmsg ("locator-set name not set!");
15075       return -99;
15076     }
15077
15078   M (ONE_NSH_SET_LOCATOR_SET, mp);
15079
15080   mp->is_add = is_add;
15081   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15082   vec_free (ls_name);
15083
15084   /* send */
15085   S (mp);
15086
15087   /* wait for reply */
15088   W (ret);
15089   return ret;
15090 }
15091
15092 static int
15093 api_show_one_pitr (vat_main_t * vam)
15094 {
15095   vl_api_show_one_pitr_t *mp;
15096   int ret;
15097
15098   if (!vam->json_output)
15099     {
15100       print (vam->ofp, "%=20s", "lisp status:");
15101     }
15102
15103   M (SHOW_ONE_PITR, mp);
15104   /* send it... */
15105   S (mp);
15106
15107   /* Wait for a reply... */
15108   W (ret);
15109   return ret;
15110 }
15111
15112 #define api_show_lisp_pitr api_show_one_pitr
15113
15114 static int
15115 api_one_use_petr (vat_main_t * vam)
15116 {
15117   unformat_input_t *input = vam->input;
15118   vl_api_one_use_petr_t *mp;
15119   u8 is_add = 0;
15120   ip_address_t ip;
15121   int ret;
15122
15123   clib_memset (&ip, 0, sizeof (ip));
15124
15125   /* Parse args required to build the message */
15126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (input, "disable"))
15129         is_add = 0;
15130       else
15131         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15132         {
15133           is_add = 1;
15134           ip_addr_version (&ip) = AF_IP4;
15135         }
15136       else
15137         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15138         {
15139           is_add = 1;
15140           ip_addr_version (&ip) = AF_IP6;
15141         }
15142       else
15143         {
15144           errmsg ("parse error '%U'", format_unformat_error, input);
15145           return -99;
15146         }
15147     }
15148
15149   M (ONE_USE_PETR, mp);
15150
15151   mp->is_add = is_add;
15152   if (is_add)
15153     {
15154       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15155       if (mp->ip_address.af)
15156         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15157       else
15158         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15159     }
15160
15161   /* send */
15162   S (mp);
15163
15164   /* wait for reply */
15165   W (ret);
15166   return ret;
15167 }
15168
15169 #define api_lisp_use_petr api_one_use_petr
15170
15171 static int
15172 api_show_one_nsh_mapping (vat_main_t * vam)
15173 {
15174   vl_api_show_one_use_petr_t *mp;
15175   int ret;
15176
15177   if (!vam->json_output)
15178     {
15179       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15180     }
15181
15182   M (SHOW_ONE_NSH_MAPPING, mp);
15183   /* send it... */
15184   S (mp);
15185
15186   /* Wait for a reply... */
15187   W (ret);
15188   return ret;
15189 }
15190
15191 static int
15192 api_show_one_use_petr (vat_main_t * vam)
15193 {
15194   vl_api_show_one_use_petr_t *mp;
15195   int ret;
15196
15197   if (!vam->json_output)
15198     {
15199       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15200     }
15201
15202   M (SHOW_ONE_USE_PETR, mp);
15203   /* send it... */
15204   S (mp);
15205
15206   /* Wait for a reply... */
15207   W (ret);
15208   return ret;
15209 }
15210
15211 #define api_show_lisp_use_petr api_show_one_use_petr
15212
15213 /**
15214  * Add/delete mapping between vni and vrf
15215  */
15216 static int
15217 api_one_eid_table_add_del_map (vat_main_t * vam)
15218 {
15219   unformat_input_t *input = vam->input;
15220   vl_api_one_eid_table_add_del_map_t *mp;
15221   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15222   u32 vni, vrf, bd_index;
15223   int ret;
15224
15225   /* Parse args required to build the message */
15226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (input, "del"))
15229         is_add = 0;
15230       else if (unformat (input, "vrf %d", &vrf))
15231         vrf_set = 1;
15232       else if (unformat (input, "bd_index %d", &bd_index))
15233         bd_index_set = 1;
15234       else if (unformat (input, "vni %d", &vni))
15235         vni_set = 1;
15236       else
15237         break;
15238     }
15239
15240   if (!vni_set || (!vrf_set && !bd_index_set))
15241     {
15242       errmsg ("missing arguments!");
15243       return -99;
15244     }
15245
15246   if (vrf_set && bd_index_set)
15247     {
15248       errmsg ("error: both vrf and bd entered!");
15249       return -99;
15250     }
15251
15252   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15253
15254   mp->is_add = is_add;
15255   mp->vni = htonl (vni);
15256   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15257   mp->is_l2 = bd_index_set;
15258
15259   /* send */
15260   S (mp);
15261
15262   /* wait for reply */
15263   W (ret);
15264   return ret;
15265 }
15266
15267 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15268
15269 uword
15270 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15271 {
15272   u32 *action = va_arg (*args, u32 *);
15273   u8 *s = 0;
15274
15275   if (unformat (input, "%s", &s))
15276     {
15277       if (!strcmp ((char *) s, "no-action"))
15278         action[0] = 0;
15279       else if (!strcmp ((char *) s, "natively-forward"))
15280         action[0] = 1;
15281       else if (!strcmp ((char *) s, "send-map-request"))
15282         action[0] = 2;
15283       else if (!strcmp ((char *) s, "drop"))
15284         action[0] = 3;
15285       else
15286         {
15287           clib_warning ("invalid action: '%s'", s);
15288           action[0] = 3;
15289         }
15290     }
15291   else
15292     return 0;
15293
15294   vec_free (s);
15295   return 1;
15296 }
15297
15298 /**
15299  * Add/del remote mapping to/from ONE control plane
15300  *
15301  * @param vam vpp API test context
15302  * @return return code
15303  */
15304 static int
15305 api_one_add_del_remote_mapping (vat_main_t * vam)
15306 {
15307   unformat_input_t *input = vam->input;
15308   vl_api_one_add_del_remote_mapping_t *mp;
15309   u32 vni = 0;
15310   lisp_eid_vat_t _eid, *eid = &_eid;
15311   lisp_eid_vat_t _seid, *seid = &_seid;
15312   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15313   u32 action = ~0, p, w, data_len;
15314   ip4_address_t rloc4;
15315   ip6_address_t rloc6;
15316   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15317   int ret;
15318
15319   clib_memset (&rloc, 0, sizeof (rloc));
15320
15321   /* Parse args required to build the message */
15322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15323     {
15324       if (unformat (input, "del-all"))
15325         {
15326           del_all = 1;
15327         }
15328       else if (unformat (input, "del"))
15329         {
15330           is_add = 0;
15331         }
15332       else if (unformat (input, "add"))
15333         {
15334           is_add = 1;
15335         }
15336       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15337         {
15338           eid_set = 1;
15339         }
15340       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15341         {
15342           seid_set = 1;
15343         }
15344       else if (unformat (input, "vni %d", &vni))
15345         {
15346           ;
15347         }
15348       else if (unformat (input, "p %d w %d", &p, &w))
15349         {
15350           if (!curr_rloc)
15351             {
15352               errmsg ("No RLOC configured for setting priority/weight!");
15353               return -99;
15354             }
15355           curr_rloc->priority = p;
15356           curr_rloc->weight = w;
15357         }
15358       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15359         {
15360           rloc.ip_address.af = 0;
15361           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15362           vec_add1 (rlocs, rloc);
15363           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15364         }
15365       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15366         {
15367           rloc.ip_address.af = 1;
15368           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15369           vec_add1 (rlocs, rloc);
15370           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15371         }
15372       else if (unformat (input, "action %U",
15373                          unformat_negative_mapping_action, &action))
15374         {
15375           ;
15376         }
15377       else
15378         {
15379           clib_warning ("parse error '%U'", format_unformat_error, input);
15380           return -99;
15381         }
15382     }
15383
15384   if (0 == eid_set)
15385     {
15386       errmsg ("missing params!");
15387       return -99;
15388     }
15389
15390   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15391     {
15392       errmsg ("no action set for negative map-reply!");
15393       return -99;
15394     }
15395
15396   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15397
15398   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15399   mp->is_add = is_add;
15400   mp->vni = htonl (vni);
15401   mp->action = (u8) action;
15402   mp->is_src_dst = seid_set;
15403   mp->del_all = del_all;
15404   lisp_eid_put_vat (&mp->deid, eid);
15405   lisp_eid_put_vat (&mp->seid, seid);
15406
15407   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15408   clib_memcpy (mp->rlocs, rlocs, data_len);
15409   vec_free (rlocs);
15410
15411   /* send it... */
15412   S (mp);
15413
15414   /* Wait for a reply... */
15415   W (ret);
15416   return ret;
15417 }
15418
15419 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15420
15421 /**
15422  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15423  * forwarding entries in data-plane accordingly.
15424  *
15425  * @param vam vpp API test context
15426  * @return return code
15427  */
15428 static int
15429 api_one_add_del_adjacency (vat_main_t * vam)
15430 {
15431   unformat_input_t *input = vam->input;
15432   vl_api_one_add_del_adjacency_t *mp;
15433   u32 vni = 0;
15434   u8 is_add = 1;
15435   int ret;
15436   lisp_eid_vat_t leid, reid;
15437
15438   leid.type = reid.type = (u8) ~ 0;
15439
15440   /* Parse args required to build the message */
15441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15442     {
15443       if (unformat (input, "del"))
15444         {
15445           is_add = 0;
15446         }
15447       else if (unformat (input, "add"))
15448         {
15449           is_add = 1;
15450         }
15451       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15452                          &reid.addr.ip, &reid.len))
15453         {
15454           reid.type = 0;        /* ipv4 */
15455         }
15456       else if (unformat (input, "reid %U", unformat_ethernet_address,
15457                          &reid.addr.mac))
15458         {
15459           reid.type = 1;        /* mac */
15460         }
15461       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15462                          &leid.addr.ip, &leid.len))
15463         {
15464           leid.type = 0;        /* ipv4 */
15465         }
15466       else if (unformat (input, "leid %U", unformat_ethernet_address,
15467                          &leid.addr.mac))
15468         {
15469           leid.type = 1;        /* mac */
15470         }
15471       else if (unformat (input, "vni %d", &vni))
15472         {
15473           ;
15474         }
15475       else
15476         {
15477           errmsg ("parse error '%U'", format_unformat_error, input);
15478           return -99;
15479         }
15480     }
15481
15482   if ((u8) ~ 0 == reid.type)
15483     {
15484       errmsg ("missing params!");
15485       return -99;
15486     }
15487
15488   if (leid.type != reid.type)
15489     {
15490       errmsg ("remote and local EIDs are of different types!");
15491       return -99;
15492     }
15493
15494   M (ONE_ADD_DEL_ADJACENCY, mp);
15495   mp->is_add = is_add;
15496   mp->vni = htonl (vni);
15497   lisp_eid_put_vat (&mp->leid, &leid);
15498   lisp_eid_put_vat (&mp->reid, &reid);
15499
15500   /* send it... */
15501   S (mp);
15502
15503   /* Wait for a reply... */
15504   W (ret);
15505   return ret;
15506 }
15507
15508 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15509
15510 uword
15511 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15512 {
15513   u32 *mode = va_arg (*args, u32 *);
15514
15515   if (unformat (input, "lisp"))
15516     *mode = 0;
15517   else if (unformat (input, "vxlan"))
15518     *mode = 1;
15519   else
15520     return 0;
15521
15522   return 1;
15523 }
15524
15525 static int
15526 api_gpe_get_encap_mode (vat_main_t * vam)
15527 {
15528   vl_api_gpe_get_encap_mode_t *mp;
15529   int ret;
15530
15531   /* Construct the API message */
15532   M (GPE_GET_ENCAP_MODE, mp);
15533
15534   /* send it... */
15535   S (mp);
15536
15537   /* Wait for a reply... */
15538   W (ret);
15539   return ret;
15540 }
15541
15542 static int
15543 api_gpe_set_encap_mode (vat_main_t * vam)
15544 {
15545   unformat_input_t *input = vam->input;
15546   vl_api_gpe_set_encap_mode_t *mp;
15547   int ret;
15548   u32 mode = 0;
15549
15550   /* Parse args required to build the message */
15551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15552     {
15553       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15554         ;
15555       else
15556         break;
15557     }
15558
15559   /* Construct the API message */
15560   M (GPE_SET_ENCAP_MODE, mp);
15561
15562   mp->is_vxlan = mode;
15563
15564   /* send it... */
15565   S (mp);
15566
15567   /* Wait for a reply... */
15568   W (ret);
15569   return ret;
15570 }
15571
15572 static int
15573 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15574 {
15575   unformat_input_t *input = vam->input;
15576   vl_api_gpe_add_del_iface_t *mp;
15577   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15578   u32 dp_table = 0, vni = 0;
15579   int ret;
15580
15581   /* Parse args required to build the message */
15582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15583     {
15584       if (unformat (input, "up"))
15585         {
15586           action_set = 1;
15587           is_add = 1;
15588         }
15589       else if (unformat (input, "down"))
15590         {
15591           action_set = 1;
15592           is_add = 0;
15593         }
15594       else if (unformat (input, "table_id %d", &dp_table))
15595         {
15596           dp_table_set = 1;
15597         }
15598       else if (unformat (input, "bd_id %d", &dp_table))
15599         {
15600           dp_table_set = 1;
15601           is_l2 = 1;
15602         }
15603       else if (unformat (input, "vni %d", &vni))
15604         {
15605           vni_set = 1;
15606         }
15607       else
15608         break;
15609     }
15610
15611   if (action_set == 0)
15612     {
15613       errmsg ("Action not set");
15614       return -99;
15615     }
15616   if (dp_table_set == 0 || vni_set == 0)
15617     {
15618       errmsg ("vni and dp_table must be set");
15619       return -99;
15620     }
15621
15622   /* Construct the API message */
15623   M (GPE_ADD_DEL_IFACE, mp);
15624
15625   mp->is_add = is_add;
15626   mp->dp_table = clib_host_to_net_u32 (dp_table);
15627   mp->is_l2 = is_l2;
15628   mp->vni = clib_host_to_net_u32 (vni);
15629
15630   /* send it... */
15631   S (mp);
15632
15633   /* Wait for a reply... */
15634   W (ret);
15635   return ret;
15636 }
15637
15638 static int
15639 api_one_map_register_fallback_threshold (vat_main_t * vam)
15640 {
15641   unformat_input_t *input = vam->input;
15642   vl_api_one_map_register_fallback_threshold_t *mp;
15643   u32 value = 0;
15644   u8 is_set = 0;
15645   int ret;
15646
15647   /* Parse args required to build the message */
15648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15649     {
15650       if (unformat (input, "%u", &value))
15651         is_set = 1;
15652       else
15653         {
15654           clib_warning ("parse error '%U'", format_unformat_error, input);
15655           return -99;
15656         }
15657     }
15658
15659   if (!is_set)
15660     {
15661       errmsg ("fallback threshold value is missing!");
15662       return -99;
15663     }
15664
15665   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15666   mp->value = clib_host_to_net_u32 (value);
15667
15668   /* send it... */
15669   S (mp);
15670
15671   /* Wait for a reply... */
15672   W (ret);
15673   return ret;
15674 }
15675
15676 static int
15677 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
15678 {
15679   vl_api_show_one_map_register_fallback_threshold_t *mp;
15680   int ret;
15681
15682   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15683
15684   /* send it... */
15685   S (mp);
15686
15687   /* Wait for a reply... */
15688   W (ret);
15689   return ret;
15690 }
15691
15692 uword
15693 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
15694 {
15695   u32 *proto = va_arg (*args, u32 *);
15696
15697   if (unformat (input, "udp"))
15698     *proto = 1;
15699   else if (unformat (input, "api"))
15700     *proto = 2;
15701   else
15702     return 0;
15703
15704   return 1;
15705 }
15706
15707 static int
15708 api_one_set_transport_protocol (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_one_set_transport_protocol_t *mp;
15712   u8 is_set = 0;
15713   u32 protocol = 0;
15714   int ret;
15715
15716   /* Parse args required to build the message */
15717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15718     {
15719       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
15720         is_set = 1;
15721       else
15722         {
15723           clib_warning ("parse error '%U'", format_unformat_error, input);
15724           return -99;
15725         }
15726     }
15727
15728   if (!is_set)
15729     {
15730       errmsg ("Transport protocol missing!");
15731       return -99;
15732     }
15733
15734   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
15735   mp->protocol = (u8) protocol;
15736
15737   /* send it... */
15738   S (mp);
15739
15740   /* Wait for a reply... */
15741   W (ret);
15742   return ret;
15743 }
15744
15745 static int
15746 api_one_get_transport_protocol (vat_main_t * vam)
15747 {
15748   vl_api_one_get_transport_protocol_t *mp;
15749   int ret;
15750
15751   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
15752
15753   /* send it... */
15754   S (mp);
15755
15756   /* Wait for a reply... */
15757   W (ret);
15758   return ret;
15759 }
15760
15761 static int
15762 api_one_map_register_set_ttl (vat_main_t * vam)
15763 {
15764   unformat_input_t *input = vam->input;
15765   vl_api_one_map_register_set_ttl_t *mp;
15766   u32 ttl = 0;
15767   u8 is_set = 0;
15768   int ret;
15769
15770   /* Parse args required to build the message */
15771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15772     {
15773       if (unformat (input, "%u", &ttl))
15774         is_set = 1;
15775       else
15776         {
15777           clib_warning ("parse error '%U'", format_unformat_error, input);
15778           return -99;
15779         }
15780     }
15781
15782   if (!is_set)
15783     {
15784       errmsg ("TTL value missing!");
15785       return -99;
15786     }
15787
15788   M (ONE_MAP_REGISTER_SET_TTL, mp);
15789   mp->ttl = clib_host_to_net_u32 (ttl);
15790
15791   /* send it... */
15792   S (mp);
15793
15794   /* Wait for a reply... */
15795   W (ret);
15796   return ret;
15797 }
15798
15799 static int
15800 api_show_one_map_register_ttl (vat_main_t * vam)
15801 {
15802   vl_api_show_one_map_register_ttl_t *mp;
15803   int ret;
15804
15805   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
15806
15807   /* send it... */
15808   S (mp);
15809
15810   /* Wait for a reply... */
15811   W (ret);
15812   return ret;
15813 }
15814
15815 /**
15816  * Add/del map request itr rlocs from ONE control plane and updates
15817  *
15818  * @param vam vpp API test context
15819  * @return return code
15820  */
15821 static int
15822 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15823 {
15824   unformat_input_t *input = vam->input;
15825   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15826   u8 *locator_set_name = 0;
15827   u8 locator_set_name_set = 0;
15828   u8 is_add = 1;
15829   int ret;
15830
15831   /* Parse args required to build the message */
15832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15833     {
15834       if (unformat (input, "del"))
15835         {
15836           is_add = 0;
15837         }
15838       else if (unformat (input, "%_%v%_", &locator_set_name))
15839         {
15840           locator_set_name_set = 1;
15841         }
15842       else
15843         {
15844           clib_warning ("parse error '%U'", format_unformat_error, input);
15845           return -99;
15846         }
15847     }
15848
15849   if (is_add && !locator_set_name_set)
15850     {
15851       errmsg ("itr-rloc is not set!");
15852       return -99;
15853     }
15854
15855   if (is_add && vec_len (locator_set_name) > 64)
15856     {
15857       errmsg ("itr-rloc locator-set name too long");
15858       vec_free (locator_set_name);
15859       return -99;
15860     }
15861
15862   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15863   mp->is_add = is_add;
15864   if (is_add)
15865     {
15866       clib_memcpy (mp->locator_set_name, locator_set_name,
15867                    vec_len (locator_set_name));
15868     }
15869   else
15870     {
15871       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15872     }
15873   vec_free (locator_set_name);
15874
15875   /* send it... */
15876   S (mp);
15877
15878   /* Wait for a reply... */
15879   W (ret);
15880   return ret;
15881 }
15882
15883 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15884
15885 static int
15886 api_one_locator_dump (vat_main_t * vam)
15887 {
15888   unformat_input_t *input = vam->input;
15889   vl_api_one_locator_dump_t *mp;
15890   vl_api_control_ping_t *mp_ping;
15891   u8 is_index_set = 0, is_name_set = 0;
15892   u8 *ls_name = 0;
15893   u32 ls_index = ~0;
15894   int ret;
15895
15896   /* Parse args required to build the message */
15897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15898     {
15899       if (unformat (input, "ls_name %_%v%_", &ls_name))
15900         {
15901           is_name_set = 1;
15902         }
15903       else if (unformat (input, "ls_index %d", &ls_index))
15904         {
15905           is_index_set = 1;
15906         }
15907       else
15908         {
15909           errmsg ("parse error '%U'", format_unformat_error, input);
15910           return -99;
15911         }
15912     }
15913
15914   if (!is_index_set && !is_name_set)
15915     {
15916       errmsg ("error: expected one of index or name!");
15917       return -99;
15918     }
15919
15920   if (is_index_set && is_name_set)
15921     {
15922       errmsg ("error: only one param expected!");
15923       return -99;
15924     }
15925
15926   if (vec_len (ls_name) > 62)
15927     {
15928       errmsg ("error: locator set name too long!");
15929       return -99;
15930     }
15931
15932   if (!vam->json_output)
15933     {
15934       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15935     }
15936
15937   M (ONE_LOCATOR_DUMP, mp);
15938   mp->is_index_set = is_index_set;
15939
15940   if (is_index_set)
15941     mp->ls_index = clib_host_to_net_u32 (ls_index);
15942   else
15943     {
15944       vec_add1 (ls_name, 0);
15945       strncpy ((char *) mp->ls_name, (char *) ls_name,
15946                sizeof (mp->ls_name) - 1);
15947     }
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Use a control ping for synchronization */
15953   MPING (CONTROL_PING, mp_ping);
15954   S (mp_ping);
15955
15956   /* Wait for a reply... */
15957   W (ret);
15958   return ret;
15959 }
15960
15961 #define api_lisp_locator_dump api_one_locator_dump
15962
15963 static int
15964 api_one_locator_set_dump (vat_main_t * vam)
15965 {
15966   vl_api_one_locator_set_dump_t *mp;
15967   vl_api_control_ping_t *mp_ping;
15968   unformat_input_t *input = vam->input;
15969   u8 filter = 0;
15970   int ret;
15971
15972   /* Parse args required to build the message */
15973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (input, "local"))
15976         {
15977           filter = 1;
15978         }
15979       else if (unformat (input, "remote"))
15980         {
15981           filter = 2;
15982         }
15983       else
15984         {
15985           errmsg ("parse error '%U'", format_unformat_error, input);
15986           return -99;
15987         }
15988     }
15989
15990   if (!vam->json_output)
15991     {
15992       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15993     }
15994
15995   M (ONE_LOCATOR_SET_DUMP, mp);
15996
15997   mp->filter = filter;
15998
15999   /* send it... */
16000   S (mp);
16001
16002   /* Use a control ping for synchronization */
16003   MPING (CONTROL_PING, mp_ping);
16004   S (mp_ping);
16005
16006   /* Wait for a reply... */
16007   W (ret);
16008   return ret;
16009 }
16010
16011 #define api_lisp_locator_set_dump api_one_locator_set_dump
16012
16013 static int
16014 api_one_eid_table_map_dump (vat_main_t * vam)
16015 {
16016   u8 is_l2 = 0;
16017   u8 mode_set = 0;
16018   unformat_input_t *input = vam->input;
16019   vl_api_one_eid_table_map_dump_t *mp;
16020   vl_api_control_ping_t *mp_ping;
16021   int ret;
16022
16023   /* Parse args required to build the message */
16024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16025     {
16026       if (unformat (input, "l2"))
16027         {
16028           is_l2 = 1;
16029           mode_set = 1;
16030         }
16031       else if (unformat (input, "l3"))
16032         {
16033           is_l2 = 0;
16034           mode_set = 1;
16035         }
16036       else
16037         {
16038           errmsg ("parse error '%U'", format_unformat_error, input);
16039           return -99;
16040         }
16041     }
16042
16043   if (!mode_set)
16044     {
16045       errmsg ("expected one of 'l2' or 'l3' parameter!");
16046       return -99;
16047     }
16048
16049   if (!vam->json_output)
16050     {
16051       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16052     }
16053
16054   M (ONE_EID_TABLE_MAP_DUMP, mp);
16055   mp->is_l2 = is_l2;
16056
16057   /* send it... */
16058   S (mp);
16059
16060   /* Use a control ping for synchronization */
16061   MPING (CONTROL_PING, mp_ping);
16062   S (mp_ping);
16063
16064   /* Wait for a reply... */
16065   W (ret);
16066   return ret;
16067 }
16068
16069 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16070
16071 static int
16072 api_one_eid_table_vni_dump (vat_main_t * vam)
16073 {
16074   vl_api_one_eid_table_vni_dump_t *mp;
16075   vl_api_control_ping_t *mp_ping;
16076   int ret;
16077
16078   if (!vam->json_output)
16079     {
16080       print (vam->ofp, "VNI");
16081     }
16082
16083   M (ONE_EID_TABLE_VNI_DUMP, mp);
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Use a control ping for synchronization */
16089   MPING (CONTROL_PING, mp_ping);
16090   S (mp_ping);
16091
16092   /* Wait for a reply... */
16093   W (ret);
16094   return ret;
16095 }
16096
16097 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16098
16099 static int
16100 api_one_eid_table_dump (vat_main_t * vam)
16101 {
16102   unformat_input_t *i = vam->input;
16103   vl_api_one_eid_table_dump_t *mp;
16104   vl_api_control_ping_t *mp_ping;
16105   u8 filter = 0;
16106   int ret;
16107   u32 vni, t = 0;
16108   lisp_eid_vat_t eid;
16109   u8 eid_set = 0;
16110
16111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16112     {
16113       if (unformat
16114           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16115         {
16116           eid_set = 1;
16117           eid.type = 0;
16118         }
16119       else
16120         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16121         {
16122           eid_set = 1;
16123           eid.type = 1;
16124         }
16125       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16126         {
16127           eid_set = 1;
16128           eid.type = 2;
16129         }
16130       else if (unformat (i, "vni %d", &t))
16131         {
16132           vni = t;
16133         }
16134       else if (unformat (i, "local"))
16135         {
16136           filter = 1;
16137         }
16138       else if (unformat (i, "remote"))
16139         {
16140           filter = 2;
16141         }
16142       else
16143         {
16144           errmsg ("parse error '%U'", format_unformat_error, i);
16145           return -99;
16146         }
16147     }
16148
16149   if (!vam->json_output)
16150     {
16151       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16152              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16153     }
16154
16155   M (ONE_EID_TABLE_DUMP, mp);
16156
16157   mp->filter = filter;
16158   if (eid_set)
16159     {
16160       mp->eid_set = 1;
16161       mp->vni = htonl (vni);
16162       lisp_eid_put_vat (&mp->eid, &eid);
16163     }
16164
16165   /* send it... */
16166   S (mp);
16167
16168   /* Use a control ping for synchronization */
16169   MPING (CONTROL_PING, mp_ping);
16170   S (mp_ping);
16171
16172   /* Wait for a reply... */
16173   W (ret);
16174   return ret;
16175 }
16176
16177 #define api_lisp_eid_table_dump api_one_eid_table_dump
16178
16179 static int
16180 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16181 {
16182   unformat_input_t *i = vam->input;
16183   vl_api_gpe_fwd_entries_get_t *mp;
16184   u8 vni_set = 0;
16185   u32 vni = ~0;
16186   int ret;
16187
16188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16189     {
16190       if (unformat (i, "vni %d", &vni))
16191         {
16192           vni_set = 1;
16193         }
16194       else
16195         {
16196           errmsg ("parse error '%U'", format_unformat_error, i);
16197           return -99;
16198         }
16199     }
16200
16201   if (!vni_set)
16202     {
16203       errmsg ("vni not set!");
16204       return -99;
16205     }
16206
16207   if (!vam->json_output)
16208     {
16209       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16210              "leid", "reid");
16211     }
16212
16213   M (GPE_FWD_ENTRIES_GET, mp);
16214   mp->vni = clib_host_to_net_u32 (vni);
16215
16216   /* send it... */
16217   S (mp);
16218
16219   /* Wait for a reply... */
16220   W (ret);
16221   return ret;
16222 }
16223
16224 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16225 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16226 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16227 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16228 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16229 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16230 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16231 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16232
16233 static int
16234 api_one_adjacencies_get (vat_main_t * vam)
16235 {
16236   unformat_input_t *i = vam->input;
16237   vl_api_one_adjacencies_get_t *mp;
16238   u8 vni_set = 0;
16239   u32 vni = ~0;
16240   int ret;
16241
16242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16243     {
16244       if (unformat (i, "vni %d", &vni))
16245         {
16246           vni_set = 1;
16247         }
16248       else
16249         {
16250           errmsg ("parse error '%U'", format_unformat_error, i);
16251           return -99;
16252         }
16253     }
16254
16255   if (!vni_set)
16256     {
16257       errmsg ("vni not set!");
16258       return -99;
16259     }
16260
16261   if (!vam->json_output)
16262     {
16263       print (vam->ofp, "%s %40s", "leid", "reid");
16264     }
16265
16266   M (ONE_ADJACENCIES_GET, mp);
16267   mp->vni = clib_host_to_net_u32 (vni);
16268
16269   /* send it... */
16270   S (mp);
16271
16272   /* Wait for a reply... */
16273   W (ret);
16274   return ret;
16275 }
16276
16277 #define api_lisp_adjacencies_get api_one_adjacencies_get
16278
16279 static int
16280 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16281 {
16282   unformat_input_t *i = vam->input;
16283   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16284   int ret;
16285   u8 ip_family_set = 0, is_ip4 = 1;
16286
16287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16288     {
16289       if (unformat (i, "ip4"))
16290         {
16291           ip_family_set = 1;
16292           is_ip4 = 1;
16293         }
16294       else if (unformat (i, "ip6"))
16295         {
16296           ip_family_set = 1;
16297           is_ip4 = 0;
16298         }
16299       else
16300         {
16301           errmsg ("parse error '%U'", format_unformat_error, i);
16302           return -99;
16303         }
16304     }
16305
16306   if (!ip_family_set)
16307     {
16308       errmsg ("ip family not set!");
16309       return -99;
16310     }
16311
16312   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16313   mp->is_ip4 = is_ip4;
16314
16315   /* send it... */
16316   S (mp);
16317
16318   /* Wait for a reply... */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 static int
16324 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16325 {
16326   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16327   int ret;
16328
16329   if (!vam->json_output)
16330     {
16331       print (vam->ofp, "VNIs");
16332     }
16333
16334   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16335
16336   /* send it... */
16337   S (mp);
16338
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16346 {
16347   unformat_input_t *i = vam->input;
16348   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16349   int ret = 0;
16350   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16351   struct in_addr ip4;
16352   struct in6_addr ip6;
16353   u32 table_id = 0, nh_sw_if_index = ~0;
16354
16355   clib_memset (&ip4, 0, sizeof (ip4));
16356   clib_memset (&ip6, 0, sizeof (ip6));
16357
16358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16359     {
16360       if (unformat (i, "del"))
16361         is_add = 0;
16362       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16363                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16364         {
16365           ip_set = 1;
16366           is_ip4 = 1;
16367         }
16368       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16369                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16370         {
16371           ip_set = 1;
16372           is_ip4 = 0;
16373         }
16374       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16375         {
16376           ip_set = 1;
16377           is_ip4 = 1;
16378           nh_sw_if_index = ~0;
16379         }
16380       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16381         {
16382           ip_set = 1;
16383           is_ip4 = 0;
16384           nh_sw_if_index = ~0;
16385         }
16386       else if (unformat (i, "table %d", &table_id))
16387         ;
16388       else
16389         {
16390           errmsg ("parse error '%U'", format_unformat_error, i);
16391           return -99;
16392         }
16393     }
16394
16395   if (!ip_set)
16396     {
16397       errmsg ("nh addr not set!");
16398       return -99;
16399     }
16400
16401   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16402   mp->is_add = is_add;
16403   mp->table_id = clib_host_to_net_u32 (table_id);
16404   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16405   mp->nh_addr.af = is_ip4 ? 0 : 1;
16406   if (is_ip4)
16407     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16408   else
16409     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16410
16411   /* send it... */
16412   S (mp);
16413
16414   /* Wait for a reply... */
16415   W (ret);
16416   return ret;
16417 }
16418
16419 static int
16420 api_one_map_server_dump (vat_main_t * vam)
16421 {
16422   vl_api_one_map_server_dump_t *mp;
16423   vl_api_control_ping_t *mp_ping;
16424   int ret;
16425
16426   if (!vam->json_output)
16427     {
16428       print (vam->ofp, "%=20s", "Map server");
16429     }
16430
16431   M (ONE_MAP_SERVER_DUMP, mp);
16432   /* send it... */
16433   S (mp);
16434
16435   /* Use a control ping for synchronization */
16436   MPING (CONTROL_PING, mp_ping);
16437   S (mp_ping);
16438
16439   /* Wait for a reply... */
16440   W (ret);
16441   return ret;
16442 }
16443
16444 #define api_lisp_map_server_dump api_one_map_server_dump
16445
16446 static int
16447 api_one_map_resolver_dump (vat_main_t * vam)
16448 {
16449   vl_api_one_map_resolver_dump_t *mp;
16450   vl_api_control_ping_t *mp_ping;
16451   int ret;
16452
16453   if (!vam->json_output)
16454     {
16455       print (vam->ofp, "%=20s", "Map resolver");
16456     }
16457
16458   M (ONE_MAP_RESOLVER_DUMP, mp);
16459   /* send it... */
16460   S (mp);
16461
16462   /* Use a control ping for synchronization */
16463   MPING (CONTROL_PING, mp_ping);
16464   S (mp_ping);
16465
16466   /* Wait for a reply... */
16467   W (ret);
16468   return ret;
16469 }
16470
16471 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16472
16473 static int
16474 api_one_stats_flush (vat_main_t * vam)
16475 {
16476   vl_api_one_stats_flush_t *mp;
16477   int ret = 0;
16478
16479   M (ONE_STATS_FLUSH, mp);
16480   S (mp);
16481   W (ret);
16482   return ret;
16483 }
16484
16485 static int
16486 api_one_stats_dump (vat_main_t * vam)
16487 {
16488   vl_api_one_stats_dump_t *mp;
16489   vl_api_control_ping_t *mp_ping;
16490   int ret;
16491
16492   M (ONE_STATS_DUMP, mp);
16493   /* send it... */
16494   S (mp);
16495
16496   /* Use a control ping for synchronization */
16497   MPING (CONTROL_PING, mp_ping);
16498   S (mp_ping);
16499
16500   /* Wait for a reply... */
16501   W (ret);
16502   return ret;
16503 }
16504
16505 static int
16506 api_show_one_status (vat_main_t * vam)
16507 {
16508   vl_api_show_one_status_t *mp;
16509   int ret;
16510
16511   if (!vam->json_output)
16512     {
16513       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16514     }
16515
16516   M (SHOW_ONE_STATUS, mp);
16517   /* send it... */
16518   S (mp);
16519   /* Wait for a reply... */
16520   W (ret);
16521   return ret;
16522 }
16523
16524 #define api_show_lisp_status api_show_one_status
16525
16526 static int
16527 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16528 {
16529   vl_api_gpe_fwd_entry_path_dump_t *mp;
16530   vl_api_control_ping_t *mp_ping;
16531   unformat_input_t *i = vam->input;
16532   u32 fwd_entry_index = ~0;
16533   int ret;
16534
16535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16536     {
16537       if (unformat (i, "index %d", &fwd_entry_index))
16538         ;
16539       else
16540         break;
16541     }
16542
16543   if (~0 == fwd_entry_index)
16544     {
16545       errmsg ("no index specified!");
16546       return -99;
16547     }
16548
16549   if (!vam->json_output)
16550     {
16551       print (vam->ofp, "first line");
16552     }
16553
16554   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16555
16556   /* send it... */
16557   S (mp);
16558   /* Use a control ping for synchronization */
16559   MPING (CONTROL_PING, mp_ping);
16560   S (mp_ping);
16561
16562   /* Wait for a reply... */
16563   W (ret);
16564   return ret;
16565 }
16566
16567 static int
16568 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16569 {
16570   vl_api_one_get_map_request_itr_rlocs_t *mp;
16571   int ret;
16572
16573   if (!vam->json_output)
16574     {
16575       print (vam->ofp, "%=20s", "itr-rlocs:");
16576     }
16577
16578   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16579   /* send it... */
16580   S (mp);
16581   /* Wait for a reply... */
16582   W (ret);
16583   return ret;
16584 }
16585
16586 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16587
16588 static int
16589 api_af_packet_create (vat_main_t * vam)
16590 {
16591   unformat_input_t *i = vam->input;
16592   vl_api_af_packet_create_t *mp;
16593   u8 *host_if_name = 0;
16594   u8 hw_addr[6];
16595   u8 random_hw_addr = 1;
16596   int ret;
16597
16598   clib_memset (hw_addr, 0, sizeof (hw_addr));
16599
16600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16601     {
16602       if (unformat (i, "name %s", &host_if_name))
16603         vec_add1 (host_if_name, 0);
16604       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16605         random_hw_addr = 0;
16606       else
16607         break;
16608     }
16609
16610   if (!vec_len (host_if_name))
16611     {
16612       errmsg ("host-interface name must be specified");
16613       return -99;
16614     }
16615
16616   if (vec_len (host_if_name) > 64)
16617     {
16618       errmsg ("host-interface name too long");
16619       return -99;
16620     }
16621
16622   M (AF_PACKET_CREATE, mp);
16623
16624   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16625   clib_memcpy (mp->hw_addr, hw_addr, 6);
16626   mp->use_random_hw_addr = random_hw_addr;
16627   vec_free (host_if_name);
16628
16629   S (mp);
16630
16631   /* *INDENT-OFF* */
16632   W2 (ret,
16633       ({
16634         if (ret == 0)
16635           fprintf (vam->ofp ? vam->ofp : stderr,
16636                    " new sw_if_index = %d\n", vam->sw_if_index);
16637       }));
16638   /* *INDENT-ON* */
16639   return ret;
16640 }
16641
16642 static int
16643 api_af_packet_delete (vat_main_t * vam)
16644 {
16645   unformat_input_t *i = vam->input;
16646   vl_api_af_packet_delete_t *mp;
16647   u8 *host_if_name = 0;
16648   int ret;
16649
16650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16651     {
16652       if (unformat (i, "name %s", &host_if_name))
16653         vec_add1 (host_if_name, 0);
16654       else
16655         break;
16656     }
16657
16658   if (!vec_len (host_if_name))
16659     {
16660       errmsg ("host-interface name must be specified");
16661       return -99;
16662     }
16663
16664   if (vec_len (host_if_name) > 64)
16665     {
16666       errmsg ("host-interface name too long");
16667       return -99;
16668     }
16669
16670   M (AF_PACKET_DELETE, mp);
16671
16672   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16673   vec_free (host_if_name);
16674
16675   S (mp);
16676   W (ret);
16677   return ret;
16678 }
16679
16680 static void vl_api_af_packet_details_t_handler
16681   (vl_api_af_packet_details_t * mp)
16682 {
16683   vat_main_t *vam = &vat_main;
16684
16685   print (vam->ofp, "%-16s %d",
16686          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
16687 }
16688
16689 static void vl_api_af_packet_details_t_handler_json
16690   (vl_api_af_packet_details_t * mp)
16691 {
16692   vat_main_t *vam = &vat_main;
16693   vat_json_node_t *node = NULL;
16694
16695   if (VAT_JSON_ARRAY != vam->json_tree.type)
16696     {
16697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16698       vat_json_init_array (&vam->json_tree);
16699     }
16700   node = vat_json_array_add (&vam->json_tree);
16701
16702   vat_json_init_object (node);
16703   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16704   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
16705 }
16706
16707 static int
16708 api_af_packet_dump (vat_main_t * vam)
16709 {
16710   vl_api_af_packet_dump_t *mp;
16711   vl_api_control_ping_t *mp_ping;
16712   int ret;
16713
16714   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
16715   /* Get list of tap interfaces */
16716   M (AF_PACKET_DUMP, mp);
16717   S (mp);
16718
16719   /* Use a control ping for synchronization */
16720   MPING (CONTROL_PING, mp_ping);
16721   S (mp_ping);
16722
16723   W (ret);
16724   return ret;
16725 }
16726
16727 static int
16728 api_policer_add_del (vat_main_t * vam)
16729 {
16730   unformat_input_t *i = vam->input;
16731   vl_api_policer_add_del_t *mp;
16732   u8 is_add = 1;
16733   u8 *name = 0;
16734   u32 cir = 0;
16735   u32 eir = 0;
16736   u64 cb = 0;
16737   u64 eb = 0;
16738   u8 rate_type = 0;
16739   u8 round_type = 0;
16740   u8 type = 0;
16741   u8 color_aware = 0;
16742   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16743   int ret;
16744
16745   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16746   conform_action.dscp = 0;
16747   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16748   exceed_action.dscp = 0;
16749   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16750   violate_action.dscp = 0;
16751
16752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16753     {
16754       if (unformat (i, "del"))
16755         is_add = 0;
16756       else if (unformat (i, "name %s", &name))
16757         vec_add1 (name, 0);
16758       else if (unformat (i, "cir %u", &cir))
16759         ;
16760       else if (unformat (i, "eir %u", &eir))
16761         ;
16762       else if (unformat (i, "cb %u", &cb))
16763         ;
16764       else if (unformat (i, "eb %u", &eb))
16765         ;
16766       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16767                          &rate_type))
16768         ;
16769       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16770                          &round_type))
16771         ;
16772       else if (unformat (i, "type %U", unformat_policer_type, &type))
16773         ;
16774       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16775                          &conform_action))
16776         ;
16777       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16778                          &exceed_action))
16779         ;
16780       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16781                          &violate_action))
16782         ;
16783       else if (unformat (i, "color-aware"))
16784         color_aware = 1;
16785       else
16786         break;
16787     }
16788
16789   if (!vec_len (name))
16790     {
16791       errmsg ("policer name must be specified");
16792       return -99;
16793     }
16794
16795   if (vec_len (name) > 64)
16796     {
16797       errmsg ("policer name too long");
16798       return -99;
16799     }
16800
16801   M (POLICER_ADD_DEL, mp);
16802
16803   clib_memcpy (mp->name, name, vec_len (name));
16804   vec_free (name);
16805   mp->is_add = is_add;
16806   mp->cir = ntohl (cir);
16807   mp->eir = ntohl (eir);
16808   mp->cb = clib_net_to_host_u64 (cb);
16809   mp->eb = clib_net_to_host_u64 (eb);
16810   mp->rate_type = rate_type;
16811   mp->round_type = round_type;
16812   mp->type = type;
16813   mp->conform_action.type = conform_action.action_type;
16814   mp->conform_action.dscp = conform_action.dscp;
16815   mp->exceed_action.type = exceed_action.action_type;
16816   mp->exceed_action.dscp = exceed_action.dscp;
16817   mp->violate_action.type = violate_action.action_type;
16818   mp->violate_action.dscp = violate_action.dscp;
16819   mp->color_aware = color_aware;
16820
16821   S (mp);
16822   W (ret);
16823   return ret;
16824 }
16825
16826 static int
16827 api_policer_dump (vat_main_t * vam)
16828 {
16829   unformat_input_t *i = vam->input;
16830   vl_api_policer_dump_t *mp;
16831   vl_api_control_ping_t *mp_ping;
16832   u8 *match_name = 0;
16833   u8 match_name_valid = 0;
16834   int ret;
16835
16836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16837     {
16838       if (unformat (i, "name %s", &match_name))
16839         {
16840           vec_add1 (match_name, 0);
16841           match_name_valid = 1;
16842         }
16843       else
16844         break;
16845     }
16846
16847   M (POLICER_DUMP, mp);
16848   mp->match_name_valid = match_name_valid;
16849   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16850   vec_free (match_name);
16851   /* send it... */
16852   S (mp);
16853
16854   /* Use a control ping for synchronization */
16855   MPING (CONTROL_PING, mp_ping);
16856   S (mp_ping);
16857
16858   /* Wait for a reply... */
16859   W (ret);
16860   return ret;
16861 }
16862
16863 static int
16864 api_policer_classify_set_interface (vat_main_t * vam)
16865 {
16866   unformat_input_t *i = vam->input;
16867   vl_api_policer_classify_set_interface_t *mp;
16868   u32 sw_if_index;
16869   int sw_if_index_set;
16870   u32 ip4_table_index = ~0;
16871   u32 ip6_table_index = ~0;
16872   u32 l2_table_index = ~0;
16873   u8 is_add = 1;
16874   int ret;
16875
16876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16877     {
16878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16879         sw_if_index_set = 1;
16880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16881         sw_if_index_set = 1;
16882       else if (unformat (i, "del"))
16883         is_add = 0;
16884       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16885         ;
16886       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16887         ;
16888       else if (unformat (i, "l2-table %d", &l2_table_index))
16889         ;
16890       else
16891         {
16892           clib_warning ("parse error '%U'", format_unformat_error, i);
16893           return -99;
16894         }
16895     }
16896
16897   if (sw_if_index_set == 0)
16898     {
16899       errmsg ("missing interface name or sw_if_index");
16900       return -99;
16901     }
16902
16903   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16904
16905   mp->sw_if_index = ntohl (sw_if_index);
16906   mp->ip4_table_index = ntohl (ip4_table_index);
16907   mp->ip6_table_index = ntohl (ip6_table_index);
16908   mp->l2_table_index = ntohl (l2_table_index);
16909   mp->is_add = is_add;
16910
16911   S (mp);
16912   W (ret);
16913   return ret;
16914 }
16915
16916 static int
16917 api_policer_classify_dump (vat_main_t * vam)
16918 {
16919   unformat_input_t *i = vam->input;
16920   vl_api_policer_classify_dump_t *mp;
16921   vl_api_control_ping_t *mp_ping;
16922   u8 type = POLICER_CLASSIFY_N_TABLES;
16923   int ret;
16924
16925   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16926     ;
16927   else
16928     {
16929       errmsg ("classify table type must be specified");
16930       return -99;
16931     }
16932
16933   if (!vam->json_output)
16934     {
16935       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16936     }
16937
16938   M (POLICER_CLASSIFY_DUMP, mp);
16939   mp->type = type;
16940   /* send it... */
16941   S (mp);
16942
16943   /* Use a control ping for synchronization */
16944   MPING (CONTROL_PING, mp_ping);
16945   S (mp_ping);
16946
16947   /* Wait for a reply... */
16948   W (ret);
16949   return ret;
16950 }
16951
16952 static u8 *
16953 format_fib_api_path_nh_proto (u8 * s, va_list * args)
16954 {
16955   vl_api_fib_path_nh_proto_t proto =
16956     va_arg (*args, vl_api_fib_path_nh_proto_t);
16957
16958   switch (proto)
16959     {
16960     case FIB_API_PATH_NH_PROTO_IP4:
16961       s = format (s, "ip4");
16962       break;
16963     case FIB_API_PATH_NH_PROTO_IP6:
16964       s = format (s, "ip6");
16965       break;
16966     case FIB_API_PATH_NH_PROTO_MPLS:
16967       s = format (s, "mpls");
16968       break;
16969     case FIB_API_PATH_NH_PROTO_BIER:
16970       s = format (s, "bier");
16971       break;
16972     case FIB_API_PATH_NH_PROTO_ETHERNET:
16973       s = format (s, "ethernet");
16974       break;
16975     }
16976
16977   return (s);
16978 }
16979
16980 static u8 *
16981 format_vl_api_ip_address_union (u8 * s, va_list * args)
16982 {
16983   vl_api_address_family_t af = va_arg (*args, int);
16984   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
16985
16986   switch (af)
16987     {
16988     case ADDRESS_IP4:
16989       s = format (s, "%U", format_ip4_address, u->ip4);
16990       break;
16991     case ADDRESS_IP6:
16992       s = format (s, "%U", format_ip6_address, u->ip6);
16993       break;
16994     }
16995   return (s);
16996 }
16997
16998 static u8 *
16999 format_vl_api_fib_path_type (u8 * s, va_list * args)
17000 {
17001   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17002
17003   switch (t)
17004     {
17005     case FIB_API_PATH_TYPE_NORMAL:
17006       s = format (s, "normal");
17007       break;
17008     case FIB_API_PATH_TYPE_LOCAL:
17009       s = format (s, "local");
17010       break;
17011     case FIB_API_PATH_TYPE_DROP:
17012       s = format (s, "drop");
17013       break;
17014     case FIB_API_PATH_TYPE_UDP_ENCAP:
17015       s = format (s, "udp-encap");
17016       break;
17017     case FIB_API_PATH_TYPE_BIER_IMP:
17018       s = format (s, "bier-imp");
17019       break;
17020     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17021       s = format (s, "unreach");
17022       break;
17023     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17024       s = format (s, "prohibit");
17025       break;
17026     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17027       s = format (s, "src-lookup");
17028       break;
17029     case FIB_API_PATH_TYPE_DVR:
17030       s = format (s, "dvr");
17031       break;
17032     case FIB_API_PATH_TYPE_INTERFACE_RX:
17033       s = format (s, "interface-rx");
17034       break;
17035     case FIB_API_PATH_TYPE_CLASSIFY:
17036       s = format (s, "classify");
17037       break;
17038     }
17039
17040   return (s);
17041 }
17042
17043 static void
17044 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17045 {
17046   print (vam->ofp,
17047          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17048          ntohl (fp->weight), ntohl (fp->sw_if_index),
17049          format_vl_api_fib_path_type, fp->type,
17050          format_fib_api_path_nh_proto, fp->proto,
17051          format_vl_api_ip_address_union, &fp->nh.address);
17052 }
17053
17054 static void
17055 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17056                                  vl_api_fib_path_t * fp)
17057 {
17058   struct in_addr ip4;
17059   struct in6_addr ip6;
17060
17061   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17062   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17063   vat_json_object_add_uint (node, "type", fp->type);
17064   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17065   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17066     {
17067       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17068       vat_json_object_add_ip4 (node, "next_hop", ip4);
17069     }
17070   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17071     {
17072       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17073       vat_json_object_add_ip6 (node, "next_hop", ip6);
17074     }
17075 }
17076
17077 static void
17078 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17079 {
17080   vat_main_t *vam = &vat_main;
17081   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17082   vl_api_fib_path_t *fp;
17083   i32 i;
17084
17085   print (vam->ofp, "sw_if_index %d via:",
17086          ntohl (mp->mt_tunnel.mt_sw_if_index));
17087   fp = mp->mt_tunnel.mt_paths;
17088   for (i = 0; i < count; i++)
17089     {
17090       vl_api_fib_path_print (vam, fp);
17091       fp++;
17092     }
17093
17094   print (vam->ofp, "");
17095 }
17096
17097 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17098 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17099
17100 static void
17101 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17102 {
17103   vat_main_t *vam = &vat_main;
17104   vat_json_node_t *node = NULL;
17105   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17106   vl_api_fib_path_t *fp;
17107   i32 i;
17108
17109   if (VAT_JSON_ARRAY != vam->json_tree.type)
17110     {
17111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17112       vat_json_init_array (&vam->json_tree);
17113     }
17114   node = vat_json_array_add (&vam->json_tree);
17115
17116   vat_json_init_object (node);
17117   vat_json_object_add_uint (node, "sw_if_index",
17118                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17119
17120   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17121
17122   fp = mp->mt_tunnel.mt_paths;
17123   for (i = 0; i < count; i++)
17124     {
17125       vl_api_mpls_fib_path_json_print (node, fp);
17126       fp++;
17127     }
17128 }
17129
17130 static int
17131 api_mpls_tunnel_dump (vat_main_t * vam)
17132 {
17133   vl_api_mpls_tunnel_dump_t *mp;
17134   vl_api_control_ping_t *mp_ping;
17135   int ret;
17136
17137   M (MPLS_TUNNEL_DUMP, mp);
17138
17139   S (mp);
17140
17141   /* Use a control ping for synchronization */
17142   MPING (CONTROL_PING, mp_ping);
17143   S (mp_ping);
17144
17145   W (ret);
17146   return ret;
17147 }
17148
17149 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17150 #define vl_api_mpls_table_details_t_print vl_noop_handler
17151
17152
17153 static void
17154 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17155 {
17156   vat_main_t *vam = &vat_main;
17157
17158   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17159 }
17160
17161 static void vl_api_mpls_table_details_t_handler_json
17162   (vl_api_mpls_table_details_t * mp)
17163 {
17164   vat_main_t *vam = &vat_main;
17165   vat_json_node_t *node = NULL;
17166
17167   if (VAT_JSON_ARRAY != vam->json_tree.type)
17168     {
17169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17170       vat_json_init_array (&vam->json_tree);
17171     }
17172   node = vat_json_array_add (&vam->json_tree);
17173
17174   vat_json_init_object (node);
17175   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17176 }
17177
17178 static int
17179 api_mpls_table_dump (vat_main_t * vam)
17180 {
17181   vl_api_mpls_table_dump_t *mp;
17182   vl_api_control_ping_t *mp_ping;
17183   int ret;
17184
17185   M (MPLS_TABLE_DUMP, mp);
17186   S (mp);
17187
17188   /* Use a control ping for synchronization */
17189   MPING (CONTROL_PING, mp_ping);
17190   S (mp_ping);
17191
17192   W (ret);
17193   return ret;
17194 }
17195
17196 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17197 #define vl_api_mpls_route_details_t_print vl_noop_handler
17198
17199 static void
17200 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17201 {
17202   vat_main_t *vam = &vat_main;
17203   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17204   vl_api_fib_path_t *fp;
17205   int i;
17206
17207   print (vam->ofp,
17208          "table-id %d, label %u, ess_bit %u",
17209          ntohl (mp->mr_route.mr_table_id),
17210          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17211   fp = mp->mr_route.mr_paths;
17212   for (i = 0; i < count; i++)
17213     {
17214       vl_api_fib_path_print (vam, fp);
17215       fp++;
17216     }
17217 }
17218
17219 static void vl_api_mpls_route_details_t_handler_json
17220   (vl_api_mpls_route_details_t * mp)
17221 {
17222   vat_main_t *vam = &vat_main;
17223   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17224   vat_json_node_t *node = NULL;
17225   vl_api_fib_path_t *fp;
17226   int i;
17227
17228   if (VAT_JSON_ARRAY != vam->json_tree.type)
17229     {
17230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17231       vat_json_init_array (&vam->json_tree);
17232     }
17233   node = vat_json_array_add (&vam->json_tree);
17234
17235   vat_json_init_object (node);
17236   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17237   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17238   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17239   vat_json_object_add_uint (node, "path_count", count);
17240   fp = mp->mr_route.mr_paths;
17241   for (i = 0; i < count; i++)
17242     {
17243       vl_api_mpls_fib_path_json_print (node, fp);
17244       fp++;
17245     }
17246 }
17247
17248 static int
17249 api_mpls_route_dump (vat_main_t * vam)
17250 {
17251   unformat_input_t *input = vam->input;
17252   vl_api_mpls_route_dump_t *mp;
17253   vl_api_control_ping_t *mp_ping;
17254   u32 table_id;
17255   int ret;
17256
17257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (input, "table_id %d", &table_id))
17260         ;
17261       else
17262         break;
17263     }
17264   if (table_id == ~0)
17265     {
17266       errmsg ("missing table id");
17267       return -99;
17268     }
17269
17270   M (MPLS_ROUTE_DUMP, mp);
17271
17272   mp->table.mt_table_id = ntohl (table_id);
17273   S (mp);
17274
17275   /* Use a control ping for synchronization */
17276   MPING (CONTROL_PING, mp_ping);
17277   S (mp_ping);
17278
17279   W (ret);
17280   return ret;
17281 }
17282
17283 #define vl_api_ip_table_details_t_endian vl_noop_handler
17284 #define vl_api_ip_table_details_t_print vl_noop_handler
17285
17286 static void
17287 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17288 {
17289   vat_main_t *vam = &vat_main;
17290
17291   print (vam->ofp,
17292          "%s; table-id %d, prefix %U/%d",
17293          mp->table.name, ntohl (mp->table.table_id));
17294 }
17295
17296
17297 static void vl_api_ip_table_details_t_handler_json
17298   (vl_api_ip_table_details_t * mp)
17299 {
17300   vat_main_t *vam = &vat_main;
17301   vat_json_node_t *node = NULL;
17302
17303   if (VAT_JSON_ARRAY != vam->json_tree.type)
17304     {
17305       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17306       vat_json_init_array (&vam->json_tree);
17307     }
17308   node = vat_json_array_add (&vam->json_tree);
17309
17310   vat_json_init_object (node);
17311   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17312 }
17313
17314 static int
17315 api_ip_table_dump (vat_main_t * vam)
17316 {
17317   vl_api_ip_table_dump_t *mp;
17318   vl_api_control_ping_t *mp_ping;
17319   int ret;
17320
17321   M (IP_TABLE_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_ip_mtable_dump (vat_main_t * vam)
17334 {
17335   vl_api_ip_mtable_dump_t *mp;
17336   vl_api_control_ping_t *mp_ping;
17337   int ret;
17338
17339   M (IP_MTABLE_DUMP, mp);
17340   S (mp);
17341
17342   /* Use a control ping for synchronization */
17343   MPING (CONTROL_PING, mp_ping);
17344   S (mp_ping);
17345
17346   W (ret);
17347   return ret;
17348 }
17349
17350 static int
17351 api_ip_mroute_dump (vat_main_t * vam)
17352 {
17353   unformat_input_t *input = vam->input;
17354   vl_api_control_ping_t *mp_ping;
17355   vl_api_ip_mroute_dump_t *mp;
17356   int ret, is_ip6;
17357   u32 table_id;
17358
17359   is_ip6 = 0;
17360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17361     {
17362       if (unformat (input, "table_id %d", &table_id))
17363         ;
17364       else if (unformat (input, "ip6"))
17365         is_ip6 = 1;
17366       else if (unformat (input, "ip4"))
17367         is_ip6 = 0;
17368       else
17369         break;
17370     }
17371   if (table_id == ~0)
17372     {
17373       errmsg ("missing table id");
17374       return -99;
17375     }
17376
17377   M (IP_MROUTE_DUMP, mp);
17378   mp->table.table_id = table_id;
17379   mp->table.is_ip6 = is_ip6;
17380   S (mp);
17381
17382   /* Use a control ping for synchronization */
17383   MPING (CONTROL_PING, mp_ping);
17384   S (mp_ping);
17385
17386   W (ret);
17387   return ret;
17388 }
17389
17390 #define vl_api_ip_route_details_t_endian vl_noop_handler
17391 #define vl_api_ip_route_details_t_print vl_noop_handler
17392
17393 static void
17394 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17395 {
17396   vat_main_t *vam = &vat_main;
17397   u8 count = mp->route.n_paths;
17398   vl_api_fib_path_t *fp;
17399   int i;
17400
17401   print (vam->ofp,
17402          "table-id %d, prefix %U/%d",
17403          ntohl (mp->route.table_id),
17404          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17405   for (i = 0; i < count; i++)
17406     {
17407       fp = &mp->route.paths[i];
17408
17409       vl_api_fib_path_print (vam, fp);
17410       fp++;
17411     }
17412 }
17413
17414 static void vl_api_ip_route_details_t_handler_json
17415   (vl_api_ip_route_details_t * mp)
17416 {
17417   vat_main_t *vam = &vat_main;
17418   u8 count = mp->route.n_paths;
17419   vat_json_node_t *node = NULL;
17420   struct in_addr ip4;
17421   struct in6_addr ip6;
17422   vl_api_fib_path_t *fp;
17423   int i;
17424
17425   if (VAT_JSON_ARRAY != vam->json_tree.type)
17426     {
17427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17428       vat_json_init_array (&vam->json_tree);
17429     }
17430   node = vat_json_array_add (&vam->json_tree);
17431
17432   vat_json_init_object (node);
17433   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17434   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17435     {
17436       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17437       vat_json_object_add_ip6 (node, "prefix", ip6);
17438     }
17439   else
17440     {
17441       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17442       vat_json_object_add_ip4 (node, "prefix", ip4);
17443     }
17444   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17445   vat_json_object_add_uint (node, "path_count", count);
17446   for (i = 0; i < count; i++)
17447     {
17448       fp = &mp->route.paths[i];
17449       vl_api_mpls_fib_path_json_print (node, fp);
17450     }
17451 }
17452
17453 static int
17454 api_ip_route_dump (vat_main_t * vam)
17455 {
17456   unformat_input_t *input = vam->input;
17457   vl_api_ip_route_dump_t *mp;
17458   vl_api_control_ping_t *mp_ping;
17459   u32 table_id;
17460   u8 is_ip6;
17461   int ret;
17462
17463   is_ip6 = 0;
17464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17465     {
17466       if (unformat (input, "table_id %d", &table_id))
17467         ;
17468       else if (unformat (input, "ip6"))
17469         is_ip6 = 1;
17470       else if (unformat (input, "ip4"))
17471         is_ip6 = 0;
17472       else
17473         break;
17474     }
17475   if (table_id == ~0)
17476     {
17477       errmsg ("missing table id");
17478       return -99;
17479     }
17480
17481   M (IP_ROUTE_DUMP, mp);
17482
17483   mp->table.table_id = table_id;
17484   mp->table.is_ip6 = is_ip6;
17485
17486   S (mp);
17487
17488   /* Use a control ping for synchronization */
17489   MPING (CONTROL_PING, mp_ping);
17490   S (mp_ping);
17491
17492   W (ret);
17493   return ret;
17494 }
17495
17496 int
17497 api_classify_table_ids (vat_main_t * vam)
17498 {
17499   vl_api_classify_table_ids_t *mp;
17500   int ret;
17501
17502   /* Construct the API message */
17503   M (CLASSIFY_TABLE_IDS, mp);
17504   mp->context = 0;
17505
17506   S (mp);
17507   W (ret);
17508   return ret;
17509 }
17510
17511 int
17512 api_classify_table_by_interface (vat_main_t * vam)
17513 {
17514   unformat_input_t *input = vam->input;
17515   vl_api_classify_table_by_interface_t *mp;
17516
17517   u32 sw_if_index = ~0;
17518   int ret;
17519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17520     {
17521       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17522         ;
17523       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17524         ;
17525       else
17526         break;
17527     }
17528   if (sw_if_index == ~0)
17529     {
17530       errmsg ("missing interface name or sw_if_index");
17531       return -99;
17532     }
17533
17534   /* Construct the API message */
17535   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17536   mp->context = 0;
17537   mp->sw_if_index = ntohl (sw_if_index);
17538
17539   S (mp);
17540   W (ret);
17541   return ret;
17542 }
17543
17544 int
17545 api_classify_table_info (vat_main_t * vam)
17546 {
17547   unformat_input_t *input = vam->input;
17548   vl_api_classify_table_info_t *mp;
17549
17550   u32 table_id = ~0;
17551   int ret;
17552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17553     {
17554       if (unformat (input, "table_id %d", &table_id))
17555         ;
17556       else
17557         break;
17558     }
17559   if (table_id == ~0)
17560     {
17561       errmsg ("missing table id");
17562       return -99;
17563     }
17564
17565   /* Construct the API message */
17566   M (CLASSIFY_TABLE_INFO, mp);
17567   mp->context = 0;
17568   mp->table_id = ntohl (table_id);
17569
17570   S (mp);
17571   W (ret);
17572   return ret;
17573 }
17574
17575 int
17576 api_classify_session_dump (vat_main_t * vam)
17577 {
17578   unformat_input_t *input = vam->input;
17579   vl_api_classify_session_dump_t *mp;
17580   vl_api_control_ping_t *mp_ping;
17581
17582   u32 table_id = ~0;
17583   int ret;
17584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17585     {
17586       if (unformat (input, "table_id %d", &table_id))
17587         ;
17588       else
17589         break;
17590     }
17591   if (table_id == ~0)
17592     {
17593       errmsg ("missing table id");
17594       return -99;
17595     }
17596
17597   /* Construct the API message */
17598   M (CLASSIFY_SESSION_DUMP, mp);
17599   mp->context = 0;
17600   mp->table_id = ntohl (table_id);
17601   S (mp);
17602
17603   /* Use a control ping for synchronization */
17604   MPING (CONTROL_PING, mp_ping);
17605   S (mp_ping);
17606
17607   W (ret);
17608   return ret;
17609 }
17610
17611 static void
17612 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17613 {
17614   vat_main_t *vam = &vat_main;
17615
17616   print (vam->ofp, "collector_address %U, collector_port %d, "
17617          "src_address %U, vrf_id %d, path_mtu %u, "
17618          "template_interval %u, udp_checksum %d",
17619          format_ip4_address, mp->collector_address,
17620          ntohs (mp->collector_port),
17621          format_ip4_address, mp->src_address,
17622          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17623          ntohl (mp->template_interval), mp->udp_checksum);
17624
17625   vam->retval = 0;
17626   vam->result_ready = 1;
17627 }
17628
17629 static void
17630   vl_api_ipfix_exporter_details_t_handler_json
17631   (vl_api_ipfix_exporter_details_t * mp)
17632 {
17633   vat_main_t *vam = &vat_main;
17634   vat_json_node_t node;
17635   struct in_addr collector_address;
17636   struct in_addr src_address;
17637
17638   vat_json_init_object (&node);
17639   clib_memcpy (&collector_address, &mp->collector_address,
17640                sizeof (collector_address));
17641   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17642   vat_json_object_add_uint (&node, "collector_port",
17643                             ntohs (mp->collector_port));
17644   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17645   vat_json_object_add_ip4 (&node, "src_address", src_address);
17646   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17647   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17648   vat_json_object_add_uint (&node, "template_interval",
17649                             ntohl (mp->template_interval));
17650   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17651
17652   vat_json_print (vam->ofp, &node);
17653   vat_json_free (&node);
17654   vam->retval = 0;
17655   vam->result_ready = 1;
17656 }
17657
17658 int
17659 api_ipfix_exporter_dump (vat_main_t * vam)
17660 {
17661   vl_api_ipfix_exporter_dump_t *mp;
17662   int ret;
17663
17664   /* Construct the API message */
17665   M (IPFIX_EXPORTER_DUMP, mp);
17666   mp->context = 0;
17667
17668   S (mp);
17669   W (ret);
17670   return ret;
17671 }
17672
17673 static int
17674 api_ipfix_classify_stream_dump (vat_main_t * vam)
17675 {
17676   vl_api_ipfix_classify_stream_dump_t *mp;
17677   int ret;
17678
17679   /* Construct the API message */
17680   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17681   mp->context = 0;
17682
17683   S (mp);
17684   W (ret);
17685   return ret;
17686   /* NOTREACHED */
17687   return 0;
17688 }
17689
17690 static void
17691   vl_api_ipfix_classify_stream_details_t_handler
17692   (vl_api_ipfix_classify_stream_details_t * mp)
17693 {
17694   vat_main_t *vam = &vat_main;
17695   print (vam->ofp, "domain_id %d, src_port %d",
17696          ntohl (mp->domain_id), ntohs (mp->src_port));
17697   vam->retval = 0;
17698   vam->result_ready = 1;
17699 }
17700
17701 static void
17702   vl_api_ipfix_classify_stream_details_t_handler_json
17703   (vl_api_ipfix_classify_stream_details_t * mp)
17704 {
17705   vat_main_t *vam = &vat_main;
17706   vat_json_node_t node;
17707
17708   vat_json_init_object (&node);
17709   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17710   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17711
17712   vat_json_print (vam->ofp, &node);
17713   vat_json_free (&node);
17714   vam->retval = 0;
17715   vam->result_ready = 1;
17716 }
17717
17718 static int
17719 api_ipfix_classify_table_dump (vat_main_t * vam)
17720 {
17721   vl_api_ipfix_classify_table_dump_t *mp;
17722   vl_api_control_ping_t *mp_ping;
17723   int ret;
17724
17725   if (!vam->json_output)
17726     {
17727       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17728              "transport_protocol");
17729     }
17730
17731   /* Construct the API message */
17732   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17733
17734   /* send it... */
17735   S (mp);
17736
17737   /* Use a control ping for synchronization */
17738   MPING (CONTROL_PING, mp_ping);
17739   S (mp_ping);
17740
17741   W (ret);
17742   return ret;
17743 }
17744
17745 static void
17746   vl_api_ipfix_classify_table_details_t_handler
17747   (vl_api_ipfix_classify_table_details_t * mp)
17748 {
17749   vat_main_t *vam = &vat_main;
17750   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17751          mp->transport_protocol);
17752 }
17753
17754 static void
17755   vl_api_ipfix_classify_table_details_t_handler_json
17756   (vl_api_ipfix_classify_table_details_t * mp)
17757 {
17758   vat_json_node_t *node = NULL;
17759   vat_main_t *vam = &vat_main;
17760
17761   if (VAT_JSON_ARRAY != vam->json_tree.type)
17762     {
17763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17764       vat_json_init_array (&vam->json_tree);
17765     }
17766
17767   node = vat_json_array_add (&vam->json_tree);
17768   vat_json_init_object (node);
17769
17770   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17771   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17772   vat_json_object_add_uint (node, "transport_protocol",
17773                             mp->transport_protocol);
17774 }
17775
17776 static int
17777 api_sw_interface_span_enable_disable (vat_main_t * vam)
17778 {
17779   unformat_input_t *i = vam->input;
17780   vl_api_sw_interface_span_enable_disable_t *mp;
17781   u32 src_sw_if_index = ~0;
17782   u32 dst_sw_if_index = ~0;
17783   u8 state = 3;
17784   int ret;
17785   u8 is_l2 = 0;
17786
17787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17788     {
17789       if (unformat
17790           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17791         ;
17792       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17793         ;
17794       else
17795         if (unformat
17796             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17797         ;
17798       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17799         ;
17800       else if (unformat (i, "disable"))
17801         state = 0;
17802       else if (unformat (i, "rx"))
17803         state = 1;
17804       else if (unformat (i, "tx"))
17805         state = 2;
17806       else if (unformat (i, "both"))
17807         state = 3;
17808       else if (unformat (i, "l2"))
17809         is_l2 = 1;
17810       else
17811         break;
17812     }
17813
17814   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17815
17816   mp->sw_if_index_from = htonl (src_sw_if_index);
17817   mp->sw_if_index_to = htonl (dst_sw_if_index);
17818   mp->state = state;
17819   mp->is_l2 = is_l2;
17820
17821   S (mp);
17822   W (ret);
17823   return ret;
17824 }
17825
17826 static void
17827 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17828                                             * mp)
17829 {
17830   vat_main_t *vam = &vat_main;
17831   u8 *sw_if_from_name = 0;
17832   u8 *sw_if_to_name = 0;
17833   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17834   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17835   char *states[] = { "none", "rx", "tx", "both" };
17836   hash_pair_t *p;
17837
17838   /* *INDENT-OFF* */
17839   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17840   ({
17841     if ((u32) p->value[0] == sw_if_index_from)
17842       {
17843         sw_if_from_name = (u8 *)(p->key);
17844         if (sw_if_to_name)
17845           break;
17846       }
17847     if ((u32) p->value[0] == sw_if_index_to)
17848       {
17849         sw_if_to_name = (u8 *)(p->key);
17850         if (sw_if_from_name)
17851           break;
17852       }
17853   }));
17854   /* *INDENT-ON* */
17855   print (vam->ofp, "%20s => %20s (%s) %s",
17856          sw_if_from_name, sw_if_to_name, states[mp->state],
17857          mp->is_l2 ? "l2" : "device");
17858 }
17859
17860 static void
17861   vl_api_sw_interface_span_details_t_handler_json
17862   (vl_api_sw_interface_span_details_t * mp)
17863 {
17864   vat_main_t *vam = &vat_main;
17865   vat_json_node_t *node = NULL;
17866   u8 *sw_if_from_name = 0;
17867   u8 *sw_if_to_name = 0;
17868   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17869   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17870   hash_pair_t *p;
17871
17872   /* *INDENT-OFF* */
17873   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17874   ({
17875     if ((u32) p->value[0] == sw_if_index_from)
17876       {
17877         sw_if_from_name = (u8 *)(p->key);
17878         if (sw_if_to_name)
17879           break;
17880       }
17881     if ((u32) p->value[0] == sw_if_index_to)
17882       {
17883         sw_if_to_name = (u8 *)(p->key);
17884         if (sw_if_from_name)
17885           break;
17886       }
17887   }));
17888   /* *INDENT-ON* */
17889
17890   if (VAT_JSON_ARRAY != vam->json_tree.type)
17891     {
17892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17893       vat_json_init_array (&vam->json_tree);
17894     }
17895   node = vat_json_array_add (&vam->json_tree);
17896
17897   vat_json_init_object (node);
17898   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17899   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17900   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17901   if (0 != sw_if_to_name)
17902     {
17903       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17904     }
17905   vat_json_object_add_uint (node, "state", mp->state);
17906   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
17907 }
17908
17909 static int
17910 api_sw_interface_span_dump (vat_main_t * vam)
17911 {
17912   unformat_input_t *input = vam->input;
17913   vl_api_sw_interface_span_dump_t *mp;
17914   vl_api_control_ping_t *mp_ping;
17915   u8 is_l2 = 0;
17916   int ret;
17917
17918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17919     {
17920       if (unformat (input, "l2"))
17921         is_l2 = 1;
17922       else
17923         break;
17924     }
17925
17926   M (SW_INTERFACE_SPAN_DUMP, mp);
17927   mp->is_l2 = is_l2;
17928   S (mp);
17929
17930   /* Use a control ping for synchronization */
17931   MPING (CONTROL_PING, mp_ping);
17932   S (mp_ping);
17933
17934   W (ret);
17935   return ret;
17936 }
17937
17938 int
17939 api_pg_create_interface (vat_main_t * vam)
17940 {
17941   unformat_input_t *input = vam->input;
17942   vl_api_pg_create_interface_t *mp;
17943
17944   u32 if_id = ~0, gso_size = 0;
17945   u8 gso_enabled = 0;
17946   int ret;
17947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17948     {
17949       if (unformat (input, "if_id %d", &if_id))
17950         ;
17951       else if (unformat (input, "gso-enabled"))
17952         {
17953           gso_enabled = 1;
17954           if (unformat (input, "gso-size %u", &gso_size))
17955             ;
17956           else
17957             {
17958               errmsg ("missing gso-size");
17959               return -99;
17960             }
17961         }
17962       else
17963         break;
17964     }
17965   if (if_id == ~0)
17966     {
17967       errmsg ("missing pg interface index");
17968       return -99;
17969     }
17970
17971   /* Construct the API message */
17972   M (PG_CREATE_INTERFACE, mp);
17973   mp->context = 0;
17974   mp->interface_id = ntohl (if_id);
17975   mp->gso_enabled = gso_enabled;
17976
17977   S (mp);
17978   W (ret);
17979   return ret;
17980 }
17981
17982 int
17983 api_pg_capture (vat_main_t * vam)
17984 {
17985   unformat_input_t *input = vam->input;
17986   vl_api_pg_capture_t *mp;
17987
17988   u32 if_id = ~0;
17989   u8 enable = 1;
17990   u32 count = 1;
17991   u8 pcap_file_set = 0;
17992   u8 *pcap_file = 0;
17993   int ret;
17994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17995     {
17996       if (unformat (input, "if_id %d", &if_id))
17997         ;
17998       else if (unformat (input, "pcap %s", &pcap_file))
17999         pcap_file_set = 1;
18000       else if (unformat (input, "count %d", &count))
18001         ;
18002       else if (unformat (input, "disable"))
18003         enable = 0;
18004       else
18005         break;
18006     }
18007   if (if_id == ~0)
18008     {
18009       errmsg ("missing pg interface index");
18010       return -99;
18011     }
18012   if (pcap_file_set > 0)
18013     {
18014       if (vec_len (pcap_file) > 255)
18015         {
18016           errmsg ("pcap file name is too long");
18017           return -99;
18018         }
18019     }
18020
18021   /* Construct the API message */
18022   M (PG_CAPTURE, mp);
18023   mp->context = 0;
18024   mp->interface_id = ntohl (if_id);
18025   mp->is_enabled = enable;
18026   mp->count = ntohl (count);
18027   if (pcap_file_set != 0)
18028     {
18029       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18030     }
18031   vec_free (pcap_file);
18032
18033   S (mp);
18034   W (ret);
18035   return ret;
18036 }
18037
18038 int
18039 api_pg_enable_disable (vat_main_t * vam)
18040 {
18041   unformat_input_t *input = vam->input;
18042   vl_api_pg_enable_disable_t *mp;
18043
18044   u8 enable = 1;
18045   u8 stream_name_set = 0;
18046   u8 *stream_name = 0;
18047   int ret;
18048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18049     {
18050       if (unformat (input, "stream %s", &stream_name))
18051         stream_name_set = 1;
18052       else if (unformat (input, "disable"))
18053         enable = 0;
18054       else
18055         break;
18056     }
18057
18058   if (stream_name_set > 0)
18059     {
18060       if (vec_len (stream_name) > 255)
18061         {
18062           errmsg ("stream name too long");
18063           return -99;
18064         }
18065     }
18066
18067   /* Construct the API message */
18068   M (PG_ENABLE_DISABLE, mp);
18069   mp->context = 0;
18070   mp->is_enabled = enable;
18071   if (stream_name_set != 0)
18072     {
18073       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18074     }
18075   vec_free (stream_name);
18076
18077   S (mp);
18078   W (ret);
18079   return ret;
18080 }
18081
18082 int
18083 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18084 {
18085   unformat_input_t *input = vam->input;
18086   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18087
18088   u32 sw_if_index = ~0;
18089   u8 enable = 1;
18090   int ret;
18091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18092     {
18093       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18094         ;
18095       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18096         ;
18097       else if (unformat (input, "disable"))
18098         enable = 0;
18099       else
18100         break;
18101     }
18102
18103   if (sw_if_index == ~0)
18104     {
18105       errmsg ("Interface required but not specified");
18106       return -99;
18107     }
18108
18109   /* Construct the API message */
18110   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18111   mp->context = 0;
18112   mp->coalesce_enabled = enable;
18113   mp->sw_if_index = htonl (sw_if_index);
18114
18115   S (mp);
18116   W (ret);
18117   return ret;
18118 }
18119
18120 int
18121 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18122 {
18123   unformat_input_t *input = vam->input;
18124   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18125
18126   u16 *low_ports = 0;
18127   u16 *high_ports = 0;
18128   u16 this_low;
18129   u16 this_hi;
18130   vl_api_prefix_t prefix;
18131   u32 tmp, tmp2;
18132   u8 prefix_set = 0;
18133   u32 vrf_id = ~0;
18134   u8 is_add = 1;
18135   int ret;
18136
18137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18138     {
18139       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18140         prefix_set = 1;
18141       else if (unformat (input, "vrf %d", &vrf_id))
18142         ;
18143       else if (unformat (input, "del"))
18144         is_add = 0;
18145       else if (unformat (input, "port %d", &tmp))
18146         {
18147           if (tmp == 0 || tmp > 65535)
18148             {
18149               errmsg ("port %d out of range", tmp);
18150               return -99;
18151             }
18152           this_low = tmp;
18153           this_hi = this_low + 1;
18154           vec_add1 (low_ports, this_low);
18155           vec_add1 (high_ports, this_hi);
18156         }
18157       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18158         {
18159           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18160             {
18161               errmsg ("incorrect range parameters");
18162               return -99;
18163             }
18164           this_low = tmp;
18165           /* Note: in debug CLI +1 is added to high before
18166              passing to real fn that does "the work"
18167              (ip_source_and_port_range_check_add_del).
18168              This fn is a wrapper around the binary API fn a
18169              control plane will call, which expects this increment
18170              to have occurred. Hence letting the binary API control
18171              plane fn do the increment for consistency between VAT
18172              and other control planes.
18173            */
18174           this_hi = tmp2;
18175           vec_add1 (low_ports, this_low);
18176           vec_add1 (high_ports, this_hi);
18177         }
18178       else
18179         break;
18180     }
18181
18182   if (prefix_set == 0)
18183     {
18184       errmsg ("<address>/<mask> not specified");
18185       return -99;
18186     }
18187
18188   if (vrf_id == ~0)
18189     {
18190       errmsg ("VRF ID required, not specified");
18191       return -99;
18192     }
18193
18194   if (vrf_id == 0)
18195     {
18196       errmsg
18197         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18198       return -99;
18199     }
18200
18201   if (vec_len (low_ports) == 0)
18202     {
18203       errmsg ("At least one port or port range required");
18204       return -99;
18205     }
18206
18207   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18208
18209   mp->is_add = is_add;
18210
18211   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18212
18213   mp->number_of_ranges = vec_len (low_ports);
18214
18215   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18216   vec_free (low_ports);
18217
18218   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18219   vec_free (high_ports);
18220
18221   mp->vrf_id = ntohl (vrf_id);
18222
18223   S (mp);
18224   W (ret);
18225   return ret;
18226 }
18227
18228 int
18229 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18230 {
18231   unformat_input_t *input = vam->input;
18232   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18233   u32 sw_if_index = ~0;
18234   int vrf_set = 0;
18235   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18236   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18237   u8 is_add = 1;
18238   int ret;
18239
18240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18241     {
18242       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18243         ;
18244       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18245         ;
18246       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18247         vrf_set = 1;
18248       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18249         vrf_set = 1;
18250       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18251         vrf_set = 1;
18252       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18253         vrf_set = 1;
18254       else if (unformat (input, "del"))
18255         is_add = 0;
18256       else
18257         break;
18258     }
18259
18260   if (sw_if_index == ~0)
18261     {
18262       errmsg ("Interface required but not specified");
18263       return -99;
18264     }
18265
18266   if (vrf_set == 0)
18267     {
18268       errmsg ("VRF ID required but not specified");
18269       return -99;
18270     }
18271
18272   if (tcp_out_vrf_id == 0
18273       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18274     {
18275       errmsg
18276         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18277       return -99;
18278     }
18279
18280   /* Construct the API message */
18281   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18282
18283   mp->sw_if_index = ntohl (sw_if_index);
18284   mp->is_add = is_add;
18285   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18286   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18287   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18288   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18289
18290   /* send it... */
18291   S (mp);
18292
18293   /* Wait for a reply... */
18294   W (ret);
18295   return ret;
18296 }
18297
18298 static int
18299 api_set_punt (vat_main_t * vam)
18300 {
18301   unformat_input_t *i = vam->input;
18302   vl_api_address_family_t af;
18303   vl_api_set_punt_t *mp;
18304   u32 protocol = ~0;
18305   u32 port = ~0;
18306   int is_add = 1;
18307   int ret;
18308
18309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18310     {
18311       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18312         ;
18313       else if (unformat (i, "protocol %d", &protocol))
18314         ;
18315       else if (unformat (i, "port %d", &port))
18316         ;
18317       else if (unformat (i, "del"))
18318         is_add = 0;
18319       else
18320         {
18321           clib_warning ("parse error '%U'", format_unformat_error, i);
18322           return -99;
18323         }
18324     }
18325
18326   M (SET_PUNT, mp);
18327
18328   mp->is_add = (u8) is_add;
18329   mp->punt.type = PUNT_API_TYPE_L4;
18330   mp->punt.punt.l4.af = af;
18331   mp->punt.punt.l4.protocol = (u8) protocol;
18332   mp->punt.punt.l4.port = htons ((u16) port);
18333
18334   S (mp);
18335   W (ret);
18336   return ret;
18337 }
18338
18339 static int
18340 api_delete_subif (vat_main_t * vam)
18341 {
18342   unformat_input_t *i = vam->input;
18343   vl_api_delete_subif_t *mp;
18344   u32 sw_if_index = ~0;
18345   int ret;
18346
18347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18348     {
18349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18350         ;
18351       if (unformat (i, "sw_if_index %d", &sw_if_index))
18352         ;
18353       else
18354         break;
18355     }
18356
18357   if (sw_if_index == ~0)
18358     {
18359       errmsg ("missing sw_if_index");
18360       return -99;
18361     }
18362
18363   /* Construct the API message */
18364   M (DELETE_SUBIF, mp);
18365   mp->sw_if_index = ntohl (sw_if_index);
18366
18367   S (mp);
18368   W (ret);
18369   return ret;
18370 }
18371
18372 #define foreach_pbb_vtr_op      \
18373 _("disable",  L2_VTR_DISABLED)  \
18374 _("pop",  L2_VTR_POP_2)         \
18375 _("push",  L2_VTR_PUSH_2)
18376
18377 static int
18378 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18379 {
18380   unformat_input_t *i = vam->input;
18381   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18382   u32 sw_if_index = ~0, vtr_op = ~0;
18383   u16 outer_tag = ~0;
18384   u8 dmac[6], smac[6];
18385   u8 dmac_set = 0, smac_set = 0;
18386   u16 vlanid = 0;
18387   u32 sid = ~0;
18388   u32 tmp;
18389   int ret;
18390
18391   /* Shut up coverity */
18392   clib_memset (dmac, 0, sizeof (dmac));
18393   clib_memset (smac, 0, sizeof (smac));
18394
18395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18396     {
18397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18398         ;
18399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18400         ;
18401       else if (unformat (i, "vtr_op %d", &vtr_op))
18402         ;
18403 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18404       foreach_pbb_vtr_op
18405 #undef _
18406         else if (unformat (i, "translate_pbb_stag"))
18407         {
18408           if (unformat (i, "%d", &tmp))
18409             {
18410               vtr_op = L2_VTR_TRANSLATE_2_1;
18411               outer_tag = tmp;
18412             }
18413           else
18414             {
18415               errmsg
18416                 ("translate_pbb_stag operation requires outer tag definition");
18417               return -99;
18418             }
18419         }
18420       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18421         dmac_set++;
18422       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18423         smac_set++;
18424       else if (unformat (i, "sid %d", &sid))
18425         ;
18426       else if (unformat (i, "vlanid %d", &tmp))
18427         vlanid = tmp;
18428       else
18429         {
18430           clib_warning ("parse error '%U'", format_unformat_error, i);
18431           return -99;
18432         }
18433     }
18434
18435   if ((sw_if_index == ~0) || (vtr_op == ~0))
18436     {
18437       errmsg ("missing sw_if_index or vtr operation");
18438       return -99;
18439     }
18440   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18441       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18442     {
18443       errmsg
18444         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18445       return -99;
18446     }
18447
18448   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18449   mp->sw_if_index = ntohl (sw_if_index);
18450   mp->vtr_op = ntohl (vtr_op);
18451   mp->outer_tag = ntohs (outer_tag);
18452   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18453   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18454   mp->b_vlanid = ntohs (vlanid);
18455   mp->i_sid = ntohl (sid);
18456
18457   S (mp);
18458   W (ret);
18459   return ret;
18460 }
18461
18462 static int
18463 api_flow_classify_set_interface (vat_main_t * vam)
18464 {
18465   unformat_input_t *i = vam->input;
18466   vl_api_flow_classify_set_interface_t *mp;
18467   u32 sw_if_index;
18468   int sw_if_index_set;
18469   u32 ip4_table_index = ~0;
18470   u32 ip6_table_index = ~0;
18471   u8 is_add = 1;
18472   int ret;
18473
18474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18475     {
18476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18477         sw_if_index_set = 1;
18478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18479         sw_if_index_set = 1;
18480       else if (unformat (i, "del"))
18481         is_add = 0;
18482       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18483         ;
18484       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18485         ;
18486       else
18487         {
18488           clib_warning ("parse error '%U'", format_unformat_error, i);
18489           return -99;
18490         }
18491     }
18492
18493   if (sw_if_index_set == 0)
18494     {
18495       errmsg ("missing interface name or sw_if_index");
18496       return -99;
18497     }
18498
18499   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18500
18501   mp->sw_if_index = ntohl (sw_if_index);
18502   mp->ip4_table_index = ntohl (ip4_table_index);
18503   mp->ip6_table_index = ntohl (ip6_table_index);
18504   mp->is_add = is_add;
18505
18506   S (mp);
18507   W (ret);
18508   return ret;
18509 }
18510
18511 static int
18512 api_flow_classify_dump (vat_main_t * vam)
18513 {
18514   unformat_input_t *i = vam->input;
18515   vl_api_flow_classify_dump_t *mp;
18516   vl_api_control_ping_t *mp_ping;
18517   u8 type = FLOW_CLASSIFY_N_TABLES;
18518   int ret;
18519
18520   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18521     ;
18522   else
18523     {
18524       errmsg ("classify table type must be specified");
18525       return -99;
18526     }
18527
18528   if (!vam->json_output)
18529     {
18530       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18531     }
18532
18533   M (FLOW_CLASSIFY_DUMP, mp);
18534   mp->type = type;
18535   /* send it... */
18536   S (mp);
18537
18538   /* Use a control ping for synchronization */
18539   MPING (CONTROL_PING, mp_ping);
18540   S (mp_ping);
18541
18542   /* Wait for a reply... */
18543   W (ret);
18544   return ret;
18545 }
18546
18547 static int
18548 api_feature_enable_disable (vat_main_t * vam)
18549 {
18550   unformat_input_t *i = vam->input;
18551   vl_api_feature_enable_disable_t *mp;
18552   u8 *arc_name = 0;
18553   u8 *feature_name = 0;
18554   u32 sw_if_index = ~0;
18555   u8 enable = 1;
18556   int ret;
18557
18558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18559     {
18560       if (unformat (i, "arc_name %s", &arc_name))
18561         ;
18562       else if (unformat (i, "feature_name %s", &feature_name))
18563         ;
18564       else
18565         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18566         ;
18567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18568         ;
18569       else if (unformat (i, "disable"))
18570         enable = 0;
18571       else
18572         break;
18573     }
18574
18575   if (arc_name == 0)
18576     {
18577       errmsg ("missing arc name");
18578       return -99;
18579     }
18580   if (vec_len (arc_name) > 63)
18581     {
18582       errmsg ("arc name too long");
18583     }
18584
18585   if (feature_name == 0)
18586     {
18587       errmsg ("missing feature name");
18588       return -99;
18589     }
18590   if (vec_len (feature_name) > 63)
18591     {
18592       errmsg ("feature name too long");
18593     }
18594
18595   if (sw_if_index == ~0)
18596     {
18597       errmsg ("missing interface name or sw_if_index");
18598       return -99;
18599     }
18600
18601   /* Construct the API message */
18602   M (FEATURE_ENABLE_DISABLE, mp);
18603   mp->sw_if_index = ntohl (sw_if_index);
18604   mp->enable = enable;
18605   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18606   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18607   vec_free (arc_name);
18608   vec_free (feature_name);
18609
18610   S (mp);
18611   W (ret);
18612   return ret;
18613 }
18614
18615 static int
18616 api_feature_gso_enable_disable (vat_main_t * vam)
18617 {
18618   unformat_input_t *i = vam->input;
18619   vl_api_feature_gso_enable_disable_t *mp;
18620   u32 sw_if_index = ~0;
18621   u8 enable = 1;
18622   int ret;
18623
18624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18625     {
18626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18627         ;
18628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18629         ;
18630       else if (unformat (i, "enable"))
18631         enable = 1;
18632       else if (unformat (i, "disable"))
18633         enable = 0;
18634       else
18635         break;
18636     }
18637
18638   if (sw_if_index == ~0)
18639     {
18640       errmsg ("missing interface name or sw_if_index");
18641       return -99;
18642     }
18643
18644   /* Construct the API message */
18645   M (FEATURE_GSO_ENABLE_DISABLE, mp);
18646   mp->sw_if_index = ntohl (sw_if_index);
18647   mp->enable_disable = enable;
18648
18649   S (mp);
18650   W (ret);
18651   return ret;
18652 }
18653
18654 static int
18655 api_sw_interface_tag_add_del (vat_main_t * vam)
18656 {
18657   unformat_input_t *i = vam->input;
18658   vl_api_sw_interface_tag_add_del_t *mp;
18659   u32 sw_if_index = ~0;
18660   u8 *tag = 0;
18661   u8 enable = 1;
18662   int ret;
18663
18664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18665     {
18666       if (unformat (i, "tag %s", &tag))
18667         ;
18668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18669         ;
18670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18671         ;
18672       else if (unformat (i, "del"))
18673         enable = 0;
18674       else
18675         break;
18676     }
18677
18678   if (sw_if_index == ~0)
18679     {
18680       errmsg ("missing interface name or sw_if_index");
18681       return -99;
18682     }
18683
18684   if (enable && (tag == 0))
18685     {
18686       errmsg ("no tag specified");
18687       return -99;
18688     }
18689
18690   /* Construct the API message */
18691   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18692   mp->sw_if_index = ntohl (sw_if_index);
18693   mp->is_add = enable;
18694   if (enable)
18695     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18696   vec_free (tag);
18697
18698   S (mp);
18699   W (ret);
18700   return ret;
18701 }
18702
18703 static int
18704 api_sw_interface_add_del_mac_address (vat_main_t * vam)
18705 {
18706   unformat_input_t *i = vam->input;
18707   vl_api_mac_address_t mac = { 0 };
18708   vl_api_sw_interface_add_del_mac_address_t *mp;
18709   u32 sw_if_index = ~0;
18710   u8 is_add = 1;
18711   u8 mac_set = 0;
18712   int ret;
18713
18714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18715     {
18716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18717         ;
18718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18719         ;
18720       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
18721         mac_set++;
18722       else if (unformat (i, "del"))
18723         is_add = 0;
18724       else
18725         break;
18726     }
18727
18728   if (sw_if_index == ~0)
18729     {
18730       errmsg ("missing interface name or sw_if_index");
18731       return -99;
18732     }
18733
18734   if (!mac_set)
18735     {
18736       errmsg ("missing MAC address");
18737       return -99;
18738     }
18739
18740   /* Construct the API message */
18741   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
18742   mp->sw_if_index = ntohl (sw_if_index);
18743   mp->is_add = is_add;
18744   clib_memcpy (&mp->addr, &mac, sizeof (mac));
18745
18746   S (mp);
18747   W (ret);
18748   return ret;
18749 }
18750
18751 static void vl_api_l2_xconnect_details_t_handler
18752   (vl_api_l2_xconnect_details_t * mp)
18753 {
18754   vat_main_t *vam = &vat_main;
18755
18756   print (vam->ofp, "%15d%15d",
18757          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18758 }
18759
18760 static void vl_api_l2_xconnect_details_t_handler_json
18761   (vl_api_l2_xconnect_details_t * mp)
18762 {
18763   vat_main_t *vam = &vat_main;
18764   vat_json_node_t *node = NULL;
18765
18766   if (VAT_JSON_ARRAY != vam->json_tree.type)
18767     {
18768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18769       vat_json_init_array (&vam->json_tree);
18770     }
18771   node = vat_json_array_add (&vam->json_tree);
18772
18773   vat_json_init_object (node);
18774   vat_json_object_add_uint (node, "rx_sw_if_index",
18775                             ntohl (mp->rx_sw_if_index));
18776   vat_json_object_add_uint (node, "tx_sw_if_index",
18777                             ntohl (mp->tx_sw_if_index));
18778 }
18779
18780 static int
18781 api_l2_xconnect_dump (vat_main_t * vam)
18782 {
18783   vl_api_l2_xconnect_dump_t *mp;
18784   vl_api_control_ping_t *mp_ping;
18785   int ret;
18786
18787   if (!vam->json_output)
18788     {
18789       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18790     }
18791
18792   M (L2_XCONNECT_DUMP, mp);
18793
18794   S (mp);
18795
18796   /* Use a control ping for synchronization */
18797   MPING (CONTROL_PING, mp_ping);
18798   S (mp_ping);
18799
18800   W (ret);
18801   return ret;
18802 }
18803
18804 static int
18805 api_hw_interface_set_mtu (vat_main_t * vam)
18806 {
18807   unformat_input_t *i = vam->input;
18808   vl_api_hw_interface_set_mtu_t *mp;
18809   u32 sw_if_index = ~0;
18810   u32 mtu = 0;
18811   int ret;
18812
18813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18814     {
18815       if (unformat (i, "mtu %d", &mtu))
18816         ;
18817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18818         ;
18819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18820         ;
18821       else
18822         break;
18823     }
18824
18825   if (sw_if_index == ~0)
18826     {
18827       errmsg ("missing interface name or sw_if_index");
18828       return -99;
18829     }
18830
18831   if (mtu == 0)
18832     {
18833       errmsg ("no mtu specified");
18834       return -99;
18835     }
18836
18837   /* Construct the API message */
18838   M (HW_INTERFACE_SET_MTU, mp);
18839   mp->sw_if_index = ntohl (sw_if_index);
18840   mp->mtu = ntohs ((u16) mtu);
18841
18842   S (mp);
18843   W (ret);
18844   return ret;
18845 }
18846
18847 static int
18848 api_p2p_ethernet_add (vat_main_t * vam)
18849 {
18850   unformat_input_t *i = vam->input;
18851   vl_api_p2p_ethernet_add_t *mp;
18852   u32 parent_if_index = ~0;
18853   u32 sub_id = ~0;
18854   u8 remote_mac[6];
18855   u8 mac_set = 0;
18856   int ret;
18857
18858   clib_memset (remote_mac, 0, sizeof (remote_mac));
18859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18860     {
18861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18862         ;
18863       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18864         ;
18865       else
18866         if (unformat
18867             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18868         mac_set++;
18869       else if (unformat (i, "sub_id %d", &sub_id))
18870         ;
18871       else
18872         {
18873           clib_warning ("parse error '%U'", format_unformat_error, i);
18874           return -99;
18875         }
18876     }
18877
18878   if (parent_if_index == ~0)
18879     {
18880       errmsg ("missing interface name or sw_if_index");
18881       return -99;
18882     }
18883   if (mac_set == 0)
18884     {
18885       errmsg ("missing remote mac address");
18886       return -99;
18887     }
18888   if (sub_id == ~0)
18889     {
18890       errmsg ("missing sub-interface id");
18891       return -99;
18892     }
18893
18894   M (P2P_ETHERNET_ADD, mp);
18895   mp->parent_if_index = ntohl (parent_if_index);
18896   mp->subif_id = ntohl (sub_id);
18897   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18898
18899   S (mp);
18900   W (ret);
18901   return ret;
18902 }
18903
18904 static int
18905 api_p2p_ethernet_del (vat_main_t * vam)
18906 {
18907   unformat_input_t *i = vam->input;
18908   vl_api_p2p_ethernet_del_t *mp;
18909   u32 parent_if_index = ~0;
18910   u8 remote_mac[6];
18911   u8 mac_set = 0;
18912   int ret;
18913
18914   clib_memset (remote_mac, 0, sizeof (remote_mac));
18915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18916     {
18917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18918         ;
18919       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18920         ;
18921       else
18922         if (unformat
18923             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18924         mac_set++;
18925       else
18926         {
18927           clib_warning ("parse error '%U'", format_unformat_error, i);
18928           return -99;
18929         }
18930     }
18931
18932   if (parent_if_index == ~0)
18933     {
18934       errmsg ("missing interface name or sw_if_index");
18935       return -99;
18936     }
18937   if (mac_set == 0)
18938     {
18939       errmsg ("missing remote mac address");
18940       return -99;
18941     }
18942
18943   M (P2P_ETHERNET_DEL, mp);
18944   mp->parent_if_index = ntohl (parent_if_index);
18945   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18946
18947   S (mp);
18948   W (ret);
18949   return ret;
18950 }
18951
18952 static int
18953 api_tcp_configure_src_addresses (vat_main_t * vam)
18954 {
18955   vl_api_tcp_configure_src_addresses_t *mp;
18956   unformat_input_t *i = vam->input;
18957   vl_api_address_t first, last;
18958   u8 range_set = 0;
18959   u32 vrf_id = 0;
18960   int ret;
18961
18962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18963     {
18964       if (unformat (i, "%U - %U",
18965                     unformat_vl_api_address, &first,
18966                     unformat_vl_api_address, &last))
18967         {
18968           if (range_set)
18969             {
18970               errmsg ("one range per message (range already set)");
18971               return -99;
18972             }
18973           range_set = 1;
18974         }
18975       else if (unformat (i, "vrf %d", &vrf_id))
18976         ;
18977       else
18978         break;
18979     }
18980
18981   if (range_set == 0)
18982     {
18983       errmsg ("address range not set");
18984       return -99;
18985     }
18986
18987   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
18988
18989   mp->vrf_id = ntohl (vrf_id);
18990   clib_memcpy (&mp->first_address, &first, sizeof (first));
18991   clib_memcpy (&mp->last_address, &last, sizeof (last));
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 static void vl_api_app_namespace_add_del_reply_t_handler
18999   (vl_api_app_namespace_add_del_reply_t * mp)
19000 {
19001   vat_main_t *vam = &vat_main;
19002   i32 retval = ntohl (mp->retval);
19003   if (vam->async_mode)
19004     {
19005       vam->async_errors += (retval < 0);
19006     }
19007   else
19008     {
19009       vam->retval = retval;
19010       if (retval == 0)
19011         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19012       vam->result_ready = 1;
19013     }
19014 }
19015
19016 static void vl_api_app_namespace_add_del_reply_t_handler_json
19017   (vl_api_app_namespace_add_del_reply_t * mp)
19018 {
19019   vat_main_t *vam = &vat_main;
19020   vat_json_node_t node;
19021
19022   vat_json_init_object (&node);
19023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19024   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19025
19026   vat_json_print (vam->ofp, &node);
19027   vat_json_free (&node);
19028
19029   vam->retval = ntohl (mp->retval);
19030   vam->result_ready = 1;
19031 }
19032
19033 static int
19034 api_app_namespace_add_del (vat_main_t * vam)
19035 {
19036   vl_api_app_namespace_add_del_t *mp;
19037   unformat_input_t *i = vam->input;
19038   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19039   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19040   u64 secret;
19041   int ret;
19042
19043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19044     {
19045       if (unformat (i, "id %_%v%_", &ns_id))
19046         ;
19047       else if (unformat (i, "secret %lu", &secret))
19048         secret_set = 1;
19049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19050         sw_if_index_set = 1;
19051       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19052         ;
19053       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19054         ;
19055       else
19056         break;
19057     }
19058   if (!ns_id || !secret_set || !sw_if_index_set)
19059     {
19060       errmsg ("namespace id, secret and sw_if_index must be set");
19061       return -99;
19062     }
19063   if (vec_len (ns_id) > 64)
19064     {
19065       errmsg ("namespace id too long");
19066       return -99;
19067     }
19068   M (APP_NAMESPACE_ADD_DEL, mp);
19069
19070   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19071   mp->secret = clib_host_to_net_u64 (secret);
19072   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19073   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19074   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19075   vec_free (ns_id);
19076   S (mp);
19077   W (ret);
19078   return ret;
19079 }
19080
19081 static int
19082 api_sock_init_shm (vat_main_t * vam)
19083 {
19084 #if VPP_API_TEST_BUILTIN == 0
19085   unformat_input_t *i = vam->input;
19086   vl_api_shm_elem_config_t *config = 0;
19087   u64 size = 64 << 20;
19088   int rv;
19089
19090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19091     {
19092       if (unformat (i, "size %U", unformat_memory_size, &size))
19093         ;
19094       else
19095         break;
19096     }
19097
19098   /*
19099    * Canned custom ring allocator config.
19100    * Should probably parse all of this
19101    */
19102   vec_validate (config, 6);
19103   config[0].type = VL_API_VLIB_RING;
19104   config[0].size = 256;
19105   config[0].count = 32;
19106
19107   config[1].type = VL_API_VLIB_RING;
19108   config[1].size = 1024;
19109   config[1].count = 16;
19110
19111   config[2].type = VL_API_VLIB_RING;
19112   config[2].size = 4096;
19113   config[2].count = 2;
19114
19115   config[3].type = VL_API_CLIENT_RING;
19116   config[3].size = 256;
19117   config[3].count = 32;
19118
19119   config[4].type = VL_API_CLIENT_RING;
19120   config[4].size = 1024;
19121   config[4].count = 16;
19122
19123   config[5].type = VL_API_CLIENT_RING;
19124   config[5].size = 4096;
19125   config[5].count = 2;
19126
19127   config[6].type = VL_API_QUEUE;
19128   config[6].count = 128;
19129   config[6].size = sizeof (uword);
19130
19131   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19132   if (!rv)
19133     vam->client_index_invalid = 1;
19134   return rv;
19135 #else
19136   return -99;
19137 #endif
19138 }
19139
19140 static void
19141 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19142 {
19143   vat_main_t *vam = &vat_main;
19144   fib_prefix_t lcl, rmt;
19145
19146   ip_prefix_decode (&mp->lcl, &lcl);
19147   ip_prefix_decode (&mp->rmt, &rmt);
19148
19149   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19150     {
19151       print (vam->ofp,
19152              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19153              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19154              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19155              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19156              &rmt.fp_addr.ip4, rmt.fp_len,
19157              clib_net_to_host_u16 (mp->rmt_port),
19158              clib_net_to_host_u32 (mp->action_index), mp->tag);
19159     }
19160   else
19161     {
19162       print (vam->ofp,
19163              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19164              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19165              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19166              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19167              &rmt.fp_addr.ip6, rmt.fp_len,
19168              clib_net_to_host_u16 (mp->rmt_port),
19169              clib_net_to_host_u32 (mp->action_index), mp->tag);
19170     }
19171 }
19172
19173 static void
19174 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19175                                              mp)
19176 {
19177   vat_main_t *vam = &vat_main;
19178   vat_json_node_t *node = NULL;
19179   struct in6_addr ip6;
19180   struct in_addr ip4;
19181
19182   fib_prefix_t lcl, rmt;
19183
19184   ip_prefix_decode (&mp->lcl, &lcl);
19185   ip_prefix_decode (&mp->rmt, &rmt);
19186
19187   if (VAT_JSON_ARRAY != vam->json_tree.type)
19188     {
19189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19190       vat_json_init_array (&vam->json_tree);
19191     }
19192   node = vat_json_array_add (&vam->json_tree);
19193   vat_json_init_object (node);
19194
19195   vat_json_object_add_uint (node, "appns_index",
19196                             clib_net_to_host_u32 (mp->appns_index));
19197   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19198   vat_json_object_add_uint (node, "scope", mp->scope);
19199   vat_json_object_add_uint (node, "action_index",
19200                             clib_net_to_host_u32 (mp->action_index));
19201   vat_json_object_add_uint (node, "lcl_port",
19202                             clib_net_to_host_u16 (mp->lcl_port));
19203   vat_json_object_add_uint (node, "rmt_port",
19204                             clib_net_to_host_u16 (mp->rmt_port));
19205   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19206   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19207   vat_json_object_add_string_copy (node, "tag", mp->tag);
19208   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19209     {
19210       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19211       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19212       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19213       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19214     }
19215   else
19216     {
19217       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19218       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19219       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19220       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19221     }
19222 }
19223
19224 static int
19225 api_session_rule_add_del (vat_main_t * vam)
19226 {
19227   vl_api_session_rule_add_del_t *mp;
19228   unformat_input_t *i = vam->input;
19229   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19230   u32 appns_index = 0, scope = 0;
19231   ip4_address_t lcl_ip4, rmt_ip4;
19232   ip6_address_t lcl_ip6, rmt_ip6;
19233   u8 is_ip4 = 1, conn_set = 0;
19234   u8 is_add = 1, *tag = 0;
19235   int ret;
19236   fib_prefix_t lcl, rmt;
19237
19238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19239     {
19240       if (unformat (i, "del"))
19241         is_add = 0;
19242       else if (unformat (i, "add"))
19243         ;
19244       else if (unformat (i, "proto tcp"))
19245         proto = 0;
19246       else if (unformat (i, "proto udp"))
19247         proto = 1;
19248       else if (unformat (i, "appns %d", &appns_index))
19249         ;
19250       else if (unformat (i, "scope %d", &scope))
19251         ;
19252       else if (unformat (i, "tag %_%v%_", &tag))
19253         ;
19254       else
19255         if (unformat
19256             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19257              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19258              &rmt_port))
19259         {
19260           is_ip4 = 1;
19261           conn_set = 1;
19262         }
19263       else
19264         if (unformat
19265             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19266              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19267              &rmt_port))
19268         {
19269           is_ip4 = 0;
19270           conn_set = 1;
19271         }
19272       else if (unformat (i, "action %d", &action))
19273         ;
19274       else
19275         break;
19276     }
19277   if (proto == ~0 || !conn_set || action == ~0)
19278     {
19279       errmsg ("transport proto, connection and action must be set");
19280       return -99;
19281     }
19282
19283   if (scope > 3)
19284     {
19285       errmsg ("scope should be 0-3");
19286       return -99;
19287     }
19288
19289   M (SESSION_RULE_ADD_DEL, mp);
19290
19291   clib_memset (&lcl, 0, sizeof (lcl));
19292   clib_memset (&rmt, 0, sizeof (rmt));
19293   if (is_ip4)
19294     {
19295       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19296       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19297       lcl.fp_len = lcl_plen;
19298       rmt.fp_len = rmt_plen;
19299     }
19300   else
19301     {
19302       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19303       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19304       lcl.fp_len = lcl_plen;
19305       rmt.fp_len = rmt_plen;
19306     }
19307
19308
19309   ip_prefix_encode (&lcl, &mp->lcl);
19310   ip_prefix_encode (&rmt, &mp->rmt);
19311   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19312   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19313   mp->transport_proto =
19314     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19315   mp->action_index = clib_host_to_net_u32 (action);
19316   mp->appns_index = clib_host_to_net_u32 (appns_index);
19317   mp->scope = scope;
19318   mp->is_add = is_add;
19319   if (tag)
19320     {
19321       clib_memcpy (mp->tag, tag, vec_len (tag));
19322       vec_free (tag);
19323     }
19324
19325   S (mp);
19326   W (ret);
19327   return ret;
19328 }
19329
19330 static int
19331 api_session_rules_dump (vat_main_t * vam)
19332 {
19333   vl_api_session_rules_dump_t *mp;
19334   vl_api_control_ping_t *mp_ping;
19335   int ret;
19336
19337   if (!vam->json_output)
19338     {
19339       print (vam->ofp, "%=20s", "Session Rules");
19340     }
19341
19342   M (SESSION_RULES_DUMP, mp);
19343   /* send it... */
19344   S (mp);
19345
19346   /* Use a control ping for synchronization */
19347   MPING (CONTROL_PING, mp_ping);
19348   S (mp_ping);
19349
19350   /* Wait for a reply... */
19351   W (ret);
19352   return ret;
19353 }
19354
19355 static int
19356 api_ip_container_proxy_add_del (vat_main_t * vam)
19357 {
19358   vl_api_ip_container_proxy_add_del_t *mp;
19359   unformat_input_t *i = vam->input;
19360   u32 sw_if_index = ~0;
19361   vl_api_prefix_t pfx = { };
19362   u8 is_add = 1;
19363   int ret;
19364
19365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19366     {
19367       if (unformat (i, "del"))
19368         is_add = 0;
19369       else if (unformat (i, "add"))
19370         ;
19371       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19372         ;
19373       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19374         ;
19375       else
19376         break;
19377     }
19378   if (sw_if_index == ~0 || pfx.len == 0)
19379     {
19380       errmsg ("address and sw_if_index must be set");
19381       return -99;
19382     }
19383
19384   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19385
19386   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19387   mp->is_add = is_add;
19388   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19389
19390   S (mp);
19391   W (ret);
19392   return ret;
19393 }
19394
19395 static int
19396 api_qos_record_enable_disable (vat_main_t * vam)
19397 {
19398   unformat_input_t *i = vam->input;
19399   vl_api_qos_record_enable_disable_t *mp;
19400   u32 sw_if_index, qs = 0xff;
19401   u8 sw_if_index_set = 0;
19402   u8 enable = 1;
19403   int ret;
19404
19405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19406     {
19407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19408         sw_if_index_set = 1;
19409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19410         sw_if_index_set = 1;
19411       else if (unformat (i, "%U", unformat_qos_source, &qs))
19412         ;
19413       else if (unformat (i, "disable"))
19414         enable = 0;
19415       else
19416         {
19417           clib_warning ("parse error '%U'", format_unformat_error, i);
19418           return -99;
19419         }
19420     }
19421
19422   if (sw_if_index_set == 0)
19423     {
19424       errmsg ("missing interface name or sw_if_index");
19425       return -99;
19426     }
19427   if (qs == 0xff)
19428     {
19429       errmsg ("input location must be specified");
19430       return -99;
19431     }
19432
19433   M (QOS_RECORD_ENABLE_DISABLE, mp);
19434
19435   mp->record.sw_if_index = ntohl (sw_if_index);
19436   mp->record.input_source = qs;
19437   mp->enable = enable;
19438
19439   S (mp);
19440   W (ret);
19441   return ret;
19442 }
19443
19444
19445 static int
19446 q_or_quit (vat_main_t * vam)
19447 {
19448 #if VPP_API_TEST_BUILTIN == 0
19449   longjmp (vam->jump_buf, 1);
19450 #endif
19451   return 0;                     /* not so much */
19452 }
19453
19454 static int
19455 q (vat_main_t * vam)
19456 {
19457   return q_or_quit (vam);
19458 }
19459
19460 static int
19461 quit (vat_main_t * vam)
19462 {
19463   return q_or_quit (vam);
19464 }
19465
19466 static int
19467 comment (vat_main_t * vam)
19468 {
19469   return 0;
19470 }
19471
19472 static int
19473 elog_save (vat_main_t * vam)
19474 {
19475 #if VPP_API_TEST_BUILTIN == 0
19476   elog_main_t *em = &vam->elog_main;
19477   unformat_input_t *i = vam->input;
19478   char *file, *chroot_file;
19479   clib_error_t *error;
19480
19481   if (!unformat (i, "%s", &file))
19482     {
19483       errmsg ("expected file name, got `%U'", format_unformat_error, i);
19484       return 0;
19485     }
19486
19487   /* It's fairly hard to get "../oopsie" through unformat; just in case */
19488   if (strstr (file, "..") || index (file, '/'))
19489     {
19490       errmsg ("illegal characters in filename '%s'", file);
19491       return 0;
19492     }
19493
19494   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
19495
19496   vec_free (file);
19497
19498   errmsg ("Saving %wd of %wd events to %s",
19499           elog_n_events_in_buffer (em),
19500           elog_buffer_capacity (em), chroot_file);
19501
19502   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
19503   vec_free (chroot_file);
19504
19505   if (error)
19506     clib_error_report (error);
19507 #else
19508   errmsg ("Use the vpp event loger...");
19509 #endif
19510
19511   return 0;
19512 }
19513
19514 static int
19515 elog_setup (vat_main_t * vam)
19516 {
19517 #if VPP_API_TEST_BUILTIN == 0
19518   elog_main_t *em = &vam->elog_main;
19519   unformat_input_t *i = vam->input;
19520   u32 nevents = 128 << 10;
19521
19522   (void) unformat (i, "nevents %d", &nevents);
19523
19524   elog_init (em, nevents);
19525   vl_api_set_elog_main (em);
19526   vl_api_set_elog_trace_api_messages (1);
19527   errmsg ("Event logger initialized with %u events", nevents);
19528 #else
19529   errmsg ("Use the vpp event loger...");
19530 #endif
19531   return 0;
19532 }
19533
19534 static int
19535 elog_enable (vat_main_t * vam)
19536 {
19537 #if VPP_API_TEST_BUILTIN == 0
19538   elog_main_t *em = &vam->elog_main;
19539
19540   elog_enable_disable (em, 1 /* enable */ );
19541   vl_api_set_elog_trace_api_messages (1);
19542   errmsg ("Event logger enabled...");
19543 #else
19544   errmsg ("Use the vpp event loger...");
19545 #endif
19546   return 0;
19547 }
19548
19549 static int
19550 elog_disable (vat_main_t * vam)
19551 {
19552 #if VPP_API_TEST_BUILTIN == 0
19553   elog_main_t *em = &vam->elog_main;
19554
19555   elog_enable_disable (em, 0 /* enable */ );
19556   vl_api_set_elog_trace_api_messages (1);
19557   errmsg ("Event logger disabled...");
19558 #else
19559   errmsg ("Use the vpp event loger...");
19560 #endif
19561   return 0;
19562 }
19563
19564 static int
19565 statseg (vat_main_t * vam)
19566 {
19567   ssvm_private_t *ssvmp = &vam->stat_segment;
19568   ssvm_shared_header_t *shared_header = ssvmp->sh;
19569   vlib_counter_t **counters;
19570   u64 thread0_index1_packets;
19571   u64 thread0_index1_bytes;
19572   f64 vector_rate, input_rate;
19573   uword *p;
19574
19575   uword *counter_vector_by_name;
19576   if (vam->stat_segment_lockp == 0)
19577     {
19578       errmsg ("Stat segment not mapped...");
19579       return -99;
19580     }
19581
19582   /* look up "/if/rx for sw_if_index 1 as a test */
19583
19584   clib_spinlock_lock (vam->stat_segment_lockp);
19585
19586   counter_vector_by_name = (uword *) shared_header->opaque[1];
19587
19588   p = hash_get_mem (counter_vector_by_name, "/if/rx");
19589   if (p == 0)
19590     {
19591       clib_spinlock_unlock (vam->stat_segment_lockp);
19592       errmsg ("/if/tx not found?");
19593       return -99;
19594     }
19595
19596   /* Fish per-thread vector of combined counters from shared memory */
19597   counters = (vlib_counter_t **) p[0];
19598
19599   if (vec_len (counters[0]) < 2)
19600     {
19601       clib_spinlock_unlock (vam->stat_segment_lockp);
19602       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
19603       return -99;
19604     }
19605
19606   /* Read thread 0 sw_if_index 1 counter */
19607   thread0_index1_packets = counters[0][1].packets;
19608   thread0_index1_bytes = counters[0][1].bytes;
19609
19610   p = hash_get_mem (counter_vector_by_name, "vector_rate");
19611   if (p == 0)
19612     {
19613       clib_spinlock_unlock (vam->stat_segment_lockp);
19614       errmsg ("vector_rate not found?");
19615       return -99;
19616     }
19617
19618   vector_rate = *(f64 *) (p[0]);
19619   p = hash_get_mem (counter_vector_by_name, "input_rate");
19620   if (p == 0)
19621     {
19622       clib_spinlock_unlock (vam->stat_segment_lockp);
19623       errmsg ("input_rate not found?");
19624       return -99;
19625     }
19626   input_rate = *(f64 *) (p[0]);
19627
19628   clib_spinlock_unlock (vam->stat_segment_lockp);
19629
19630   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
19631          vector_rate, input_rate);
19632   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
19633          thread0_index1_packets, thread0_index1_bytes);
19634
19635   return 0;
19636 }
19637
19638 static int
19639 cmd_cmp (void *a1, void *a2)
19640 {
19641   u8 **c1 = a1;
19642   u8 **c2 = a2;
19643
19644   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19645 }
19646
19647 static int
19648 help (vat_main_t * vam)
19649 {
19650   u8 **cmds = 0;
19651   u8 *name = 0;
19652   hash_pair_t *p;
19653   unformat_input_t *i = vam->input;
19654   int j;
19655
19656   if (unformat (i, "%s", &name))
19657     {
19658       uword *hs;
19659
19660       vec_add1 (name, 0);
19661
19662       hs = hash_get_mem (vam->help_by_name, name);
19663       if (hs)
19664         print (vam->ofp, "usage: %s %s", name, hs[0]);
19665       else
19666         print (vam->ofp, "No such msg / command '%s'", name);
19667       vec_free (name);
19668       return 0;
19669     }
19670
19671   print (vam->ofp, "Help is available for the following:");
19672
19673     /* *INDENT-OFF* */
19674     hash_foreach_pair (p, vam->function_by_name,
19675     ({
19676       vec_add1 (cmds, (u8 *)(p->key));
19677     }));
19678     /* *INDENT-ON* */
19679
19680   vec_sort_with_function (cmds, cmd_cmp);
19681
19682   for (j = 0; j < vec_len (cmds); j++)
19683     print (vam->ofp, "%s", cmds[j]);
19684
19685   vec_free (cmds);
19686   return 0;
19687 }
19688
19689 static int
19690 set (vat_main_t * vam)
19691 {
19692   u8 *name = 0, *value = 0;
19693   unformat_input_t *i = vam->input;
19694
19695   if (unformat (i, "%s", &name))
19696     {
19697       /* The input buffer is a vector, not a string. */
19698       value = vec_dup (i->buffer);
19699       vec_delete (value, i->index, 0);
19700       /* Almost certainly has a trailing newline */
19701       if (value[vec_len (value) - 1] == '\n')
19702         value[vec_len (value) - 1] = 0;
19703       /* Make sure it's a proper string, one way or the other */
19704       vec_add1 (value, 0);
19705       (void) clib_macro_set_value (&vam->macro_main,
19706                                    (char *) name, (char *) value);
19707     }
19708   else
19709     errmsg ("usage: set <name> <value>");
19710
19711   vec_free (name);
19712   vec_free (value);
19713   return 0;
19714 }
19715
19716 static int
19717 unset (vat_main_t * vam)
19718 {
19719   u8 *name = 0;
19720
19721   if (unformat (vam->input, "%s", &name))
19722     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19723       errmsg ("unset: %s wasn't set", name);
19724   vec_free (name);
19725   return 0;
19726 }
19727
19728 typedef struct
19729 {
19730   u8 *name;
19731   u8 *value;
19732 } macro_sort_t;
19733
19734
19735 static int
19736 macro_sort_cmp (void *a1, void *a2)
19737 {
19738   macro_sort_t *s1 = a1;
19739   macro_sort_t *s2 = a2;
19740
19741   return strcmp ((char *) (s1->name), (char *) (s2->name));
19742 }
19743
19744 static int
19745 dump_macro_table (vat_main_t * vam)
19746 {
19747   macro_sort_t *sort_me = 0, *sm;
19748   int i;
19749   hash_pair_t *p;
19750
19751     /* *INDENT-OFF* */
19752     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19753     ({
19754       vec_add2 (sort_me, sm, 1);
19755       sm->name = (u8 *)(p->key);
19756       sm->value = (u8 *) (p->value[0]);
19757     }));
19758     /* *INDENT-ON* */
19759
19760   vec_sort_with_function (sort_me, macro_sort_cmp);
19761
19762   if (vec_len (sort_me))
19763     print (vam->ofp, "%-15s%s", "Name", "Value");
19764   else
19765     print (vam->ofp, "The macro table is empty...");
19766
19767   for (i = 0; i < vec_len (sort_me); i++)
19768     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19769   return 0;
19770 }
19771
19772 static int
19773 dump_node_table (vat_main_t * vam)
19774 {
19775   int i, j;
19776   vlib_node_t *node, *next_node;
19777
19778   if (vec_len (vam->graph_nodes) == 0)
19779     {
19780       print (vam->ofp, "Node table empty, issue get_node_graph...");
19781       return 0;
19782     }
19783
19784   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
19785     {
19786       node = vam->graph_nodes[0][i];
19787       print (vam->ofp, "[%d] %s", i, node->name);
19788       for (j = 0; j < vec_len (node->next_nodes); j++)
19789         {
19790           if (node->next_nodes[j] != ~0)
19791             {
19792               next_node = vam->graph_nodes[0][node->next_nodes[j]];
19793               print (vam->ofp, "  [%d] %s", j, next_node->name);
19794             }
19795         }
19796     }
19797   return 0;
19798 }
19799
19800 static int
19801 value_sort_cmp (void *a1, void *a2)
19802 {
19803   name_sort_t *n1 = a1;
19804   name_sort_t *n2 = a2;
19805
19806   if (n1->value < n2->value)
19807     return -1;
19808   if (n1->value > n2->value)
19809     return 1;
19810   return 0;
19811 }
19812
19813
19814 static int
19815 dump_msg_api_table (vat_main_t * vam)
19816 {
19817   api_main_t *am = vlibapi_get_main ();
19818   name_sort_t *nses = 0, *ns;
19819   hash_pair_t *hp;
19820   int i;
19821
19822   /* *INDENT-OFF* */
19823   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19824   ({
19825     vec_add2 (nses, ns, 1);
19826     ns->name = (u8 *)(hp->key);
19827     ns->value = (u32) hp->value[0];
19828   }));
19829   /* *INDENT-ON* */
19830
19831   vec_sort_with_function (nses, value_sort_cmp);
19832
19833   for (i = 0; i < vec_len (nses); i++)
19834     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19835   vec_free (nses);
19836   return 0;
19837 }
19838
19839 static int
19840 get_msg_id (vat_main_t * vam)
19841 {
19842   u8 *name_and_crc;
19843   u32 message_index;
19844
19845   if (unformat (vam->input, "%s", &name_and_crc))
19846     {
19847       message_index = vl_msg_api_get_msg_index (name_and_crc);
19848       if (message_index == ~0)
19849         {
19850           print (vam->ofp, " '%s' not found", name_and_crc);
19851           return 0;
19852         }
19853       print (vam->ofp, " '%s' has message index %d",
19854              name_and_crc, message_index);
19855       return 0;
19856     }
19857   errmsg ("name_and_crc required...");
19858   return 0;
19859 }
19860
19861 static int
19862 search_node_table (vat_main_t * vam)
19863 {
19864   unformat_input_t *line_input = vam->input;
19865   u8 *node_to_find;
19866   int j;
19867   vlib_node_t *node, *next_node;
19868   uword *p;
19869
19870   if (vam->graph_node_index_by_name == 0)
19871     {
19872       print (vam->ofp, "Node table empty, issue get_node_graph...");
19873       return 0;
19874     }
19875
19876   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19877     {
19878       if (unformat (line_input, "%s", &node_to_find))
19879         {
19880           vec_add1 (node_to_find, 0);
19881           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19882           if (p == 0)
19883             {
19884               print (vam->ofp, "%s not found...", node_to_find);
19885               goto out;
19886             }
19887           node = vam->graph_nodes[0][p[0]];
19888           print (vam->ofp, "[%d] %s", p[0], node->name);
19889           for (j = 0; j < vec_len (node->next_nodes); j++)
19890             {
19891               if (node->next_nodes[j] != ~0)
19892                 {
19893                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
19894                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19895                 }
19896             }
19897         }
19898
19899       else
19900         {
19901           clib_warning ("parse error '%U'", format_unformat_error,
19902                         line_input);
19903           return -99;
19904         }
19905
19906     out:
19907       vec_free (node_to_find);
19908
19909     }
19910
19911   return 0;
19912 }
19913
19914
19915 static int
19916 script (vat_main_t * vam)
19917 {
19918 #if (VPP_API_TEST_BUILTIN==0)
19919   u8 *s = 0;
19920   char *save_current_file;
19921   unformat_input_t save_input;
19922   jmp_buf save_jump_buf;
19923   u32 save_line_number;
19924
19925   FILE *new_fp, *save_ifp;
19926
19927   if (unformat (vam->input, "%s", &s))
19928     {
19929       new_fp = fopen ((char *) s, "r");
19930       if (new_fp == 0)
19931         {
19932           errmsg ("Couldn't open script file %s", s);
19933           vec_free (s);
19934           return -99;
19935         }
19936     }
19937   else
19938     {
19939       errmsg ("Missing script name");
19940       return -99;
19941     }
19942
19943   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19944   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19945   save_ifp = vam->ifp;
19946   save_line_number = vam->input_line_number;
19947   save_current_file = (char *) vam->current_file;
19948
19949   vam->input_line_number = 0;
19950   vam->ifp = new_fp;
19951   vam->current_file = s;
19952   do_one_file (vam);
19953
19954   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
19955   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19956   vam->ifp = save_ifp;
19957   vam->input_line_number = save_line_number;
19958   vam->current_file = (u8 *) save_current_file;
19959   vec_free (s);
19960
19961   return 0;
19962 #else
19963   clib_warning ("use the exec command...");
19964   return -99;
19965 #endif
19966 }
19967
19968 static int
19969 echo (vat_main_t * vam)
19970 {
19971   print (vam->ofp, "%v", vam->input->buffer);
19972   return 0;
19973 }
19974
19975 /* List of API message constructors, CLI names map to api_xxx */
19976 #define foreach_vpe_api_msg                                             \
19977 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19978 _(sw_interface_dump,"")                                                 \
19979 _(sw_interface_set_flags,                                               \
19980   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19981 _(sw_interface_add_del_address,                                         \
19982   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19983 _(sw_interface_set_rx_mode,                                             \
19984   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
19985 _(sw_interface_set_rx_placement,                                        \
19986   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
19987 _(sw_interface_rx_placement_dump,                                       \
19988   "[<intfc> | sw_if_index <id>]")                                         \
19989 _(sw_interface_set_table,                                               \
19990   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19991 _(sw_interface_set_mpls_enable,                                         \
19992   "<intfc> | sw_if_index [disable | dis]")                              \
19993 _(sw_interface_set_vpath,                                               \
19994   "<intfc> | sw_if_index <id> enable | disable")                        \
19995 _(sw_interface_set_vxlan_bypass,                                        \
19996   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19997 _(sw_interface_set_l2_xconnect,                                         \
19998   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19999   "enable | disable")                                                   \
20000 _(sw_interface_set_l2_bridge,                                           \
20001   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20002   "[shg <split-horizon-group>] [bvi]\n"                                 \
20003   "enable | disable")                                                   \
20004 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20005 _(bridge_domain_add_del,                                                \
20006   "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") \
20007 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20008 _(l2fib_add_del,                                                        \
20009   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20010 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20011 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20012 _(l2_flags,                                                             \
20013   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20014 _(bridge_flags,                                                         \
20015   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20016 _(tap_create_v2,                                                        \
20017   "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 | gro-coalesce] [persist] [attach] [tun] [packed] [in-order]") \
20018 _(tap_delete_v2,                                                        \
20019   "<vpp-if-name> | sw_if_index <id>")                                   \
20020 _(sw_interface_tap_v2_dump, "")                                         \
20021 _(virtio_pci_create_v2,                                                    \
20022   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order]") \
20023 _(virtio_pci_delete,                                                    \
20024   "<vpp-if-name> | sw_if_index <id>")                                   \
20025 _(sw_interface_virtio_pci_dump, "")                                     \
20026 _(bond_create,                                                          \
20027   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20028   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20029   "[id <if-id>]")                                                       \
20030 _(bond_create2,                                                         \
20031   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
20032   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20033   "[id <if-id>] [gso]")                                                 \
20034 _(bond_delete,                                                          \
20035   "<vpp-if-name> | sw_if_index <id>")                                   \
20036 _(bond_add_member,                                                      \
20037   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20038 _(bond_detach_member,                                                   \
20039   "sw_if_index <n>")                                                    \
20040  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20041  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20042  _(sw_member_interface_dump,                                            \
20043   "<vpp-if-name> | sw_if_index <id>")                                   \
20044 _(ip_table_add_del,                                                     \
20045   "table <n> [ipv6] [add | del]\n")                                     \
20046 _(ip_route_add_del,                                                     \
20047   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20048   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20049   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20050   "[multipath] [count <n>] [del]")                                      \
20051 _(ip_mroute_add_del,                                                    \
20052   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20053   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20054 _(mpls_table_add_del,                                                   \
20055   "table <n> [add | del]\n")                                            \
20056 _(mpls_route_add_del,                                                   \
20057   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20058   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20059   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20060   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20061   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20062   "[count <n>] [del]")                                                  \
20063 _(mpls_ip_bind_unbind,                                                  \
20064   "<label> <addr/len>")                                                 \
20065 _(mpls_tunnel_add_del,                                                  \
20066   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20067   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20068   "[l2-only]  [out-label <n>]")                                         \
20069 _(sr_mpls_policy_add,                                                   \
20070   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20071 _(sr_mpls_policy_del,                                                   \
20072   "bsid <id>")                                                          \
20073 _(bier_table_add_del,                                                   \
20074   "<label> <sub-domain> <set> <bsl> [del]")                             \
20075 _(bier_route_add_del,                                                   \
20076   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20077   "[<intfc> | sw_if_index <id>]"                                        \
20078   "[weight <n>] [del] [multipath]")                                     \
20079 _(sw_interface_set_unnumbered,                                          \
20080   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20081 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20082 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20083   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20084   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20085   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20086 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20087 _(ip_table_flush, "table <n> [ipv6]")                                   \
20088 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20089 _(set_ip_flow_hash,                                                     \
20090   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20091 _(sw_interface_ip6_enable_disable,                                      \
20092   "<intfc> | sw_if_index <id> enable | disable")                        \
20093 _(l2_patch_add_del,                                                     \
20094   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20095   "enable | disable")                                                   \
20096 _(sr_localsid_add_del,                                                  \
20097   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20098   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20099 _(classify_add_del_table,                                               \
20100   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20101   " [del] [del-chain] mask <mask-value>\n"                              \
20102   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20103   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20104 _(classify_add_del_session,                                             \
20105   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20106   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20107   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20108   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20109 _(classify_set_interface_ip_table,                                      \
20110   "<intfc> | sw_if_index <nn> table <nn>")                              \
20111 _(classify_set_interface_l2_tables,                                     \
20112   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20113   "  [other-table <nn>]")                                               \
20114 _(get_node_index, "node <node-name")                                    \
20115 _(add_node_next, "node <node-name> next <next-node-name>")              \
20116 _(vxlan_offload_rx,                                                     \
20117   "hw { <interface name> | hw_if_index <nn>} "                          \
20118   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20119 _(vxlan_add_del_tunnel,                                                 \
20120   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20121   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20122   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20123 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20124 _(gre_tunnel_add_del,                                                   \
20125   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20126   "[teb | erspan <session-id>] [del]")                                  \
20127 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20128 _(l2_fib_clear_table, "")                                               \
20129 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20130 _(l2_interface_vlan_tag_rewrite,                                        \
20131   "<intfc> | sw_if_index <nn> \n"                                       \
20132   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20133   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20134 _(create_vhost_user_if,                                                 \
20135         "socket <filename> [server] [renumber <dev_instance>] "         \
20136         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20137         "[mac <mac_address>] [packed]")                                 \
20138 _(modify_vhost_user_if,                                                 \
20139         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20140         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20141 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20142 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20143 _(show_version, "")                                                     \
20144 _(show_threads, "")                                                     \
20145 _(vxlan_gpe_add_del_tunnel,                                             \
20146   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20147   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20148   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20149   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20150 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20151 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20152 _(interface_name_renumber,                                              \
20153   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20154 _(input_acl_set_interface,                                              \
20155   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20156   "  [l2-table <nn>] [del]")                                            \
20157 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20158 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20159 _(ip_dump, "ipv4 | ipv6")                                               \
20160 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20161 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20162   "  spid_id <n> ")                                                     \
20163 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20164   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20165   "  integ_alg <alg> integ_key <hex>")                                  \
20166 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20167   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20168   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20169   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20170 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20171   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20172   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20173   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20174   "  [instance <n>]")     \
20175 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20176 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20177 _(delete_loopback,"sw_if_index <nn>")                                   \
20178 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20179 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20180 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20181 _(want_interface_events,  "enable|disable")                             \
20182 _(get_first_msg_id, "client <name>")                                    \
20183 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20184 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20185   "fib-id <nn> [ip4][ip6][default]")                                    \
20186 _(get_node_graph, " ")                                                  \
20187 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20188 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20189 _(ioam_disable, "")                                                     \
20190 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20191                             " sw_if_index <sw_if_index> p <priority> "  \
20192                             "w <weight>] [del]")                        \
20193 _(one_add_del_locator, "locator-set <locator_name> "                    \
20194                         "iface <intf> | sw_if_index <sw_if_index> "     \
20195                         "p <priority> w <weight> [del]")                \
20196 _(one_add_del_local_eid,"vni <vni> eid "                                \
20197                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20198                          "locator-set <locator_name> [del]"             \
20199                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20200 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20201 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20202 _(one_enable_disable, "enable|disable")                                 \
20203 _(one_map_register_enable_disable, "enable|disable")                    \
20204 _(one_map_register_fallback_threshold, "<value>")                       \
20205 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20206 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20207                                "[seid <seid>] "                         \
20208                                "rloc <locator> p <prio> "               \
20209                                "w <weight> [rloc <loc> ... ] "          \
20210                                "action <action> [del-all]")             \
20211 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20212                           "<local-eid>")                                \
20213 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20214 _(one_use_petr, "ip-address> | disable")                                \
20215 _(one_map_request_mode, "src-dst|dst-only")                             \
20216 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20217 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20218 _(one_locator_set_dump, "[local | remote]")                             \
20219 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20220 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20221                        "[local] | [remote]")                            \
20222 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20223 _(one_ndp_bd_get, "")                                                   \
20224 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20225 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip <ip4>")        \
20226 _(one_l2_arp_bd_get, "")                                                \
20227 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20228 _(one_stats_enable_disable, "enable|disable")                           \
20229 _(show_one_stats_enable_disable, "")                                    \
20230 _(one_eid_table_vni_dump, "")                                           \
20231 _(one_eid_table_map_dump, "l2|l3")                                      \
20232 _(one_map_resolver_dump, "")                                            \
20233 _(one_map_server_dump, "")                                              \
20234 _(one_adjacencies_get, "vni <vni>")                                     \
20235 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20236 _(show_one_rloc_probe_state, "")                                        \
20237 _(show_one_map_register_state, "")                                      \
20238 _(show_one_status, "")                                                  \
20239 _(one_stats_dump, "")                                                   \
20240 _(one_stats_flush, "")                                                  \
20241 _(one_get_map_request_itr_rlocs, "")                                    \
20242 _(one_map_register_set_ttl, "<ttl>")                                    \
20243 _(one_set_transport_protocol, "udp|api")                                \
20244 _(one_get_transport_protocol, "")                                       \
20245 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20246 _(one_show_xtr_mode, "")                                                \
20247 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20248 _(one_show_pitr_mode, "")                                               \
20249 _(one_enable_disable_petr_mode, "enable|disable")                       \
20250 _(one_show_petr_mode, "")                                               \
20251 _(show_one_nsh_mapping, "")                                             \
20252 _(show_one_pitr, "")                                                    \
20253 _(show_one_use_petr, "")                                                \
20254 _(show_one_map_request_mode, "")                                        \
20255 _(show_one_map_register_ttl, "")                                        \
20256 _(show_one_map_register_fallback_threshold, "")                         \
20257 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20258                             " sw_if_index <sw_if_index> p <priority> "  \
20259                             "w <weight>] [del]")                        \
20260 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20261                         "iface <intf> | sw_if_index <sw_if_index> "     \
20262                         "p <priority> w <weight> [del]")                \
20263 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20264                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20265                          "locator-set <locator_name> [del]"             \
20266                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20267 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20268 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20269 _(lisp_enable_disable, "enable|disable")                                \
20270 _(lisp_map_register_enable_disable, "enable|disable")                   \
20271 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20272 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20273                                "[seid <seid>] "                         \
20274                                "rloc <locator> p <prio> "               \
20275                                "w <weight> [rloc <loc> ... ] "          \
20276                                "action <action> [del-all]")             \
20277 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20278                           "<local-eid>")                                \
20279 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20280 _(lisp_use_petr, "<ip-address> | disable")                              \
20281 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20282 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20283 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20284 _(lisp_locator_set_dump, "[local | remote]")                            \
20285 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20286 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20287                        "[local] | [remote]")                            \
20288 _(lisp_eid_table_vni_dump, "")                                          \
20289 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20290 _(lisp_map_resolver_dump, "")                                           \
20291 _(lisp_map_server_dump, "")                                             \
20292 _(lisp_adjacencies_get, "vni <vni>")                                    \
20293 _(gpe_fwd_entry_vnis_get, "")                                           \
20294 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20295 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20296                                 "[table <table-id>]")                   \
20297 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20298 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20299 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20300 _(gpe_get_encap_mode, "")                                               \
20301 _(lisp_gpe_add_del_iface, "up|down")                                    \
20302 _(lisp_gpe_enable_disable, "enable|disable")                            \
20303 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20304   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20305 _(show_lisp_rloc_probe_state, "")                                       \
20306 _(show_lisp_map_register_state, "")                                     \
20307 _(show_lisp_status, "")                                                 \
20308 _(lisp_get_map_request_itr_rlocs, "")                                   \
20309 _(show_lisp_pitr, "")                                                   \
20310 _(show_lisp_use_petr, "")                                               \
20311 _(show_lisp_map_request_mode, "")                                       \
20312 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20313 _(af_packet_delete, "name <host interface name>")                       \
20314 _(af_packet_dump, "")                                                   \
20315 _(policer_add_del, "name <policer name> <params> [del]")                \
20316 _(policer_dump, "[name <policer name>]")                                \
20317 _(policer_classify_set_interface,                                       \
20318   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20319   "  [l2-table <nn>] [del]")                                            \
20320 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20321 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20322 _(mpls_table_dump, "")                                                  \
20323 _(mpls_route_dump, "table-id <ID>")                                     \
20324 _(classify_table_ids, "")                                               \
20325 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20326 _(classify_table_info, "table_id <nn>")                                 \
20327 _(classify_session_dump, "table_id <nn>")                               \
20328 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20329     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20330     "[template_interval <nn>] [udp_checksum]")                          \
20331 _(ipfix_exporter_dump, "")                                              \
20332 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20333 _(ipfix_classify_stream_dump, "")                                       \
20334 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20335 _(ipfix_classify_table_dump, "")                                        \
20336 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20337 _(sw_interface_span_dump, "[l2]")                                           \
20338 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20339 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20340 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20341 _(pg_enable_disable, "[stream <id>] disable")                           \
20342 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
20343 _(ip_source_and_port_range_check_add_del,                               \
20344   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20345 _(ip_source_and_port_range_check_interface_add_del,                     \
20346   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20347   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20348 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20349 _(l2_interface_pbb_tag_rewrite,                                         \
20350   "<intfc> | sw_if_index <nn> \n"                                       \
20351   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20352   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20353 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20354 _(flow_classify_set_interface,                                          \
20355   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20356 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20357 _(ip_table_dump, "")                                                    \
20358 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20359 _(ip_mtable_dump, "")                                                   \
20360 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20361 _(feature_enable_disable, "arc_name <arc_name> "                        \
20362   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20363 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20364   "[enable | disable] ")                                                \
20365 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20366 "[disable]")                                                            \
20367 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20368   "mac <mac-address> [del]")                                            \
20369 _(l2_xconnect_dump, "")                                                 \
20370 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20371 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20372 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20373 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20374 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20375 _(sock_init_shm, "size <nnn>")                                          \
20376 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20377 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20378   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20379 _(session_rules_dump, "")                                               \
20380 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20381 _(output_acl_set_interface,                                             \
20382   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20383   "  [l2-table <nn>] [del]")                                            \
20384 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20385
20386 /* List of command functions, CLI names map directly to functions */
20387 #define foreach_cli_function                                    \
20388 _(comment, "usage: comment <ignore-rest-of-line>")              \
20389 _(dump_interface_table, "usage: dump_interface_table")          \
20390 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20391 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20392 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20393 _(dump_macro_table, "usage: dump_macro_table ")                 \
20394 _(dump_node_table, "usage: dump_node_table")                    \
20395 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20396 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
20397 _(elog_disable, "usage: elog_disable")                          \
20398 _(elog_enable, "usage: elog_enable")                            \
20399 _(elog_save, "usage: elog_save <filename>")                     \
20400 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20401 _(echo, "usage: echo <message>")                                \
20402 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20403 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20404 _(help, "usage: help")                                          \
20405 _(q, "usage: quit")                                             \
20406 _(quit, "usage: quit")                                          \
20407 _(search_node_table, "usage: search_node_table <name>...")      \
20408 _(set, "usage: set <variable-name> <value>")                    \
20409 _(script, "usage: script <file-name>")                          \
20410 _(statseg, "usage: statseg")                                    \
20411 _(unset, "usage: unset <variable-name>")
20412
20413 #define _(N,n)                                  \
20414     static void vl_api_##n##_t_handler_uni      \
20415     (vl_api_##n##_t * mp)                       \
20416     {                                           \
20417         vat_main_t * vam = &vat_main;           \
20418         if (vam->json_output) {                 \
20419             vl_api_##n##_t_handler_json(mp);    \
20420         } else {                                \
20421             vl_api_##n##_t_handler(mp);         \
20422         }                                       \
20423     }
20424 foreach_vpe_api_reply_msg;
20425 #if VPP_API_TEST_BUILTIN == 0
20426 foreach_standalone_reply_msg;
20427 #endif
20428 #undef _
20429
20430 void
20431 vat_api_hookup (vat_main_t * vam)
20432 {
20433 #define _(N,n)                                                  \
20434     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20435                            vl_api_##n##_t_handler_uni,          \
20436                            vl_noop_handler,                     \
20437                            vl_api_##n##_t_endian,               \
20438                            vl_api_##n##_t_print,                \
20439                            sizeof(vl_api_##n##_t), 1);
20440   foreach_vpe_api_reply_msg;
20441 #if VPP_API_TEST_BUILTIN == 0
20442   foreach_standalone_reply_msg;
20443 #endif
20444 #undef _
20445
20446 #if (VPP_API_TEST_BUILTIN==0)
20447   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20448
20449   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20450
20451   vam->function_by_name = hash_create_string (0, sizeof (uword));
20452
20453   vam->help_by_name = hash_create_string (0, sizeof (uword));
20454 #endif
20455
20456   /* API messages we can send */
20457 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20458   foreach_vpe_api_msg;
20459 #undef _
20460
20461   /* Help strings */
20462 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20463   foreach_vpe_api_msg;
20464 #undef _
20465
20466   /* CLI functions */
20467 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20468   foreach_cli_function;
20469 #undef _
20470
20471   /* Help strings */
20472 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20473   foreach_cli_function;
20474 #undef _
20475 }
20476
20477 #if VPP_API_TEST_BUILTIN
20478 static clib_error_t *
20479 vat_api_hookup_shim (vlib_main_t * vm)
20480 {
20481   vat_api_hookup (&vat_main);
20482   return 0;
20483 }
20484
20485 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20486 #endif
20487
20488 /*
20489  * fd.io coding-style-patch-verification: ON
20490  *
20491  * Local Variables:
20492  * eval: (c-set-style "gnu")
20493  * End:
20494  */