2 *------------------------------------------------------------------
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:
10 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
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/udp/udp_local.h>
32 #include <vnet/l2/l2_classify.h>
33 #include <vnet/l2/l2_vtr.h>
34 #include <vnet/classify/in_out_acl.h>
35 #include <vnet/classify/policer_classify.h>
36 #include <vnet/classify/flow_classify.h>
37 #include <vnet/mpls/mpls.h>
38 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ip/ip6_hop_by_hop.h>
41 #include <vnet/ip/ip_source_and_port_range_check.h>
42 #include <vnet/policer/xlate.h>
43 #include <vnet/span/span.h>
44 #include <vnet/policer/policer.h>
45 #include <vnet/policer/police.h>
46 #include <vnet/mfib/mfib_types.h>
47 #include <vnet/bonding/node.h>
48 #include <vnet/qos/qos_types.h>
49 #include <vnet/ethernet/ethernet_types_api.h>
50 #include <vnet/ip/ip_types_api.h>
51 #include "vat/json_format.h"
52 #include <vnet/ip/ip_types_api.h>
53 #include <vnet/ethernet/ethernet_types_api.h>
58 #include <vlibmemory/memclnt.api_enum.h>
59 #include <vlibmemory/memclnt.api_types.h>
60 #include <vlibmemory/memclnt.api_tojson.h>
61 #include <vlibmemory/memclnt.api_fromjson.h>
63 #define vl_endianfun /* define message structures */
64 #include <vlibmemory/memclnt.api.h>
67 /* instantiate all the print functions we know about */
68 #if VPP_API_TEST_BUILTIN == 0
69 #define vl_print(handle, ...)
71 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
74 #include <vlibmemory/memclnt.api.h>
77 #define __plugin_msg_base 0
78 #include <vlibapi/vat_helper_macros.h>
80 void vl_api_set_elog_main (elog_main_t * m);
81 int vl_api_set_elog_trace_api_messages (int enable);
83 #if VPP_API_TEST_BUILTIN == 0
93 vat_socket_connect (vat_main_t * vam)
96 api_main_t *am = vlibapi_get_main ();
97 vam->socket_client_main = &socket_client_main;
98 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
100 0 /* default socket rx, tx buffer */ )))
103 /* vpp expects the client index in network order */
104 vam->my_client_index = htonl (socket_client_main.client_index);
105 am->my_client_index = vam->my_client_index;
108 #else /* vpp built-in case, we don't do sockets... */
110 vat_socket_connect (vat_main_t * vam)
116 vl_socket_client_read (int wait)
122 vl_socket_client_write ()
128 vl_socket_client_msg_alloc (int nbytes)
136 vat_time_now (vat_main_t * vam)
138 #if VPP_API_TEST_BUILTIN
139 return vlib_time_now (vam->vlib_main);
141 return clib_time_now (&vam->clib_time);
146 errmsg (char *fmt, ...)
148 vat_main_t *vam = &vat_main;
153 s = va_format (0, fmt, &va);
158 #if VPP_API_TEST_BUILTIN
159 vlib_cli_output (vam->vlib_main, (char *) s);
162 if (vam->ifp != stdin)
163 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
164 vam->input_line_number);
166 fformat (vam->ofp, "%s\n", (char *) s);
174 #if VPP_API_TEST_BUILTIN == 0
176 /* Parse an IP4 address %d.%d.%d.%d. */
178 unformat_ip4_address (unformat_input_t * input, va_list * args)
180 u8 *result = va_arg (*args, u8 *);
183 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
186 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
198 unformat_ethernet_address (unformat_input_t * input, va_list * args)
200 u8 *result = va_arg (*args, u8 *);
203 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
204 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
208 for (i = 0; i < 6; i++)
209 if (a[i] >= (1 << 8))
212 for (i = 0; i < 6; i++)
218 /* Returns ethernet type as an int in host byte order. */
220 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
223 u16 *result = va_arg (*args, u16 *);
227 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
229 if (type >= (1 << 16))
237 /* Parse an IP46 address. */
239 unformat_ip46_address (unformat_input_t * input, va_list * args)
241 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
242 ip46_type_t type = va_arg (*args, ip46_type_t);
243 if ((type != IP46_TYPE_IP6) &&
244 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
246 ip46_address_mask_ip4 (ip46);
249 else if ((type != IP46_TYPE_IP4) &&
250 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
257 /* Parse an IP6 address. */
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
261 ip6_address_t *result = va_arg (*args, ip6_address_t *);
263 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264 uword c, n_colon, double_colon_index;
266 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267 double_colon_index = ARRAY_LEN (hex_quads);
268 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
271 if (c >= '0' && c <= '9')
273 else if (c >= 'a' && c <= 'f')
274 hex_digit = c + 10 - 'a';
275 else if (c >= 'A' && c <= 'F')
276 hex_digit = c + 10 - 'A';
277 else if (c == ':' && n_colon < 2)
281 unformat_put_input (input);
285 /* Too many hex quads. */
286 if (n_hex_quads >= ARRAY_LEN (hex_quads))
291 hex_quad = (hex_quad << 4) | hex_digit;
293 /* Hex quad must fit in 16 bits. */
294 if (n_hex_digits >= 4)
301 /* Save position of :: */
304 /* More than one :: ? */
305 if (double_colon_index < ARRAY_LEN (hex_quads))
307 double_colon_index = n_hex_quads;
310 if (n_colon > 0 && n_hex_digits > 0)
312 hex_quads[n_hex_quads++] = hex_quad;
318 if (n_hex_digits > 0)
319 hex_quads[n_hex_quads++] = hex_quad;
324 /* Expand :: to appropriate number of zero hex quads. */
325 if (double_colon_index < ARRAY_LEN (hex_quads))
327 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
329 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330 hex_quads[n_zero + i] = hex_quads[i];
332 for (i = 0; i < n_zero; i++)
333 hex_quads[double_colon_index + i] = 0;
335 n_hex_quads = ARRAY_LEN (hex_quads);
338 /* Too few hex quads given. */
339 if (n_hex_quads < ARRAY_LEN (hex_quads))
342 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
352 u32 *r = va_arg (*args, u32 *);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356 foreach_ipsec_policy_action
364 format_ipsec_crypto_alg (u8 * s, va_list * args)
366 u32 i = va_arg (*args, u32);
371 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
372 foreach_ipsec_crypto_alg
375 return format (s, "unknown");
377 return format (s, "%s", t);
381 format_ipsec_integ_alg (u8 * s, va_list * args)
383 u32 i = va_arg (*args, u32);
388 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
389 foreach_ipsec_integ_alg
392 return format (s, "unknown");
394 return format (s, "%s", t);
397 #else /* VPP_API_TEST_BUILTIN == 1 */
399 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
401 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
402 vnet_main_t *vnm = vnet_get_main ();
403 u32 *result = va_arg (*args, u32 *);
405 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
408 #endif /* VPP_API_TEST_BUILTIN */
410 #if (VPP_API_TEST_BUILTIN==0)
412 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
413 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
414 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
415 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
418 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
420 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
421 mfib_itf_attribute_t attr;
424 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
426 if (unformat (input, mfib_itf_flag_long_names[attr]))
427 *iflags |= (1 << attr);
429 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
431 if (unformat (input, mfib_itf_flag_names[attr]))
432 *iflags |= (1 << attr);
435 return (old == *iflags ? 0 : 1);
439 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
441 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
442 mfib_entry_attribute_t attr;
445 FOR_EACH_MFIB_ATTRIBUTE (attr)
447 if (unformat (input, mfib_flag_long_names[attr]))
448 *eflags |= (1 << attr);
450 FOR_EACH_MFIB_ATTRIBUTE (attr)
452 if (unformat (input, mfib_flag_names[attr]))
453 *eflags |= (1 << attr);
456 return (old == *eflags ? 0 : 1);
460 format_ip4_address (u8 * s, va_list * args)
462 u8 *a = va_arg (*args, u8 *);
463 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
467 format_ip6_address (u8 * s, va_list * args)
469 ip6_address_t *a = va_arg (*args, ip6_address_t *);
470 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
472 i_max_n_zero = ARRAY_LEN (a->as_u16);
474 i_first_zero = i_max_n_zero;
476 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
478 u32 is_zero = a->as_u16[i] == 0;
479 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
485 if ((!is_zero && n_zeros > max_n_zeros)
486 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
488 i_max_n_zero = i_first_zero;
489 max_n_zeros = n_zeros;
490 i_first_zero = ARRAY_LEN (a->as_u16);
495 last_double_colon = 0;
496 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
498 if (i == i_max_n_zero && max_n_zeros > 1)
500 s = format (s, "::");
501 i += max_n_zeros - 1;
502 last_double_colon = 1;
506 s = format (s, "%s%x",
507 (last_double_colon || i == 0) ? "" : ":",
508 clib_net_to_host_u16 (a->as_u16[i]));
509 last_double_colon = 0;
516 /* Format an IP46 address. */
518 format_ip46_address (u8 * s, va_list * args)
520 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
521 ip46_type_t type = va_arg (*args, ip46_type_t);
527 is_ip4 = ip46_address_is_ip4 (ip46);
538 format (s, "%U", format_ip4_address, &ip46->ip4) :
539 format (s, "%U", format_ip6_address, &ip46->ip6);
543 format_ethernet_address (u8 * s, va_list * args)
545 u8 *a = va_arg (*args, u8 *);
547 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
548 a[0], a[1], a[2], a[3], a[4], a[5]);
553 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
556 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
558 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
559 sizeof (ip6_address_t));
563 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
564 #define vl_api_bridge_domain_details_t_print vl_noop_handler
566 static void vl_api_get_first_msg_id_reply_t_handler
567 (vl_api_get_first_msg_id_reply_t * mp)
569 vat_main_t *vam = &vat_main;
570 i32 retval = ntohl (mp->retval);
574 vam->async_errors += (retval < 0);
578 vam->retval = retval;
579 vam->result_ready = 1;
583 errmsg ("first message id %d", ntohs (mp->first_msg_id));
587 static void vl_api_get_first_msg_id_reply_t_handler_json
588 (vl_api_get_first_msg_id_reply_t * mp)
590 vat_main_t *vam = &vat_main;
591 vat_json_node_t node;
593 vat_json_init_object (&node);
594 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
595 vat_json_object_add_uint (&node, "first_msg_id",
596 (uint) ntohs (mp->first_msg_id));
598 vat_json_print (vam->ofp, &node);
599 vat_json_free (&node);
601 vam->retval = ntohl (mp->retval);
602 vam->result_ready = 1;
605 /* Format hex dump. */
607 format_hex_bytes (u8 * s, va_list * va)
609 u8 *bytes = va_arg (*va, u8 *);
610 int n_bytes = va_arg (*va, int);
613 /* Print short or long form depending on byte count. */
614 uword short_form = n_bytes <= 32;
615 u32 indent = format_get_indent (s);
620 for (i = 0; i < n_bytes; i++)
622 if (!short_form && (i % 32) == 0)
623 s = format (s, "%08x: ", i);
624 s = format (s, "%02x", bytes[i]);
625 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
626 s = format (s, "\n%U", format_white_space, indent);
633 vl_api_control_ping_reply_t_handler (vl_api_control_ping_reply_t *mp)
635 vat_main_t *vam = &vat_main;
636 i32 retval = ntohl (mp->retval);
639 vam->async_errors += (retval < 0);
643 vam->retval = retval;
644 vam->result_ready = 1;
646 if (vam->socket_client_main)
647 vam->socket_client_main->control_pings_outstanding--;
651 vl_api_control_ping_reply_t_handler_json (vl_api_control_ping_reply_t *mp)
653 vat_main_t *vam = &vat_main;
654 i32 retval = ntohl (mp->retval);
656 if (VAT_JSON_NONE != vam->json_tree.type)
658 vat_json_print (vam->ofp, &vam->json_tree);
659 vat_json_free (&vam->json_tree);
660 vam->json_tree.type = VAT_JSON_NONE;
665 vat_json_init_array (&vam->json_tree);
666 vat_json_print (vam->ofp, &vam->json_tree);
667 vam->json_tree.type = VAT_JSON_NONE;
670 vam->retval = retval;
671 vam->result_ready = 1;
675 * Generate boilerplate reply handlers, which
676 * dig the return value out of the xxx_reply_t API message,
677 * stick it into vam->retval, and set vam->result_ready
679 * Could also do this by pointing N message decode slots at
680 * a single function, but that could break in subtle ways.
683 #define foreach_standard_reply_retval_handler
686 static void vl_api_##n##_t_handler \
687 (vl_api_##n##_t * mp) \
689 vat_main_t * vam = &vat_main; \
690 i32 retval = ntohl(mp->retval); \
691 if (vam->async_mode) { \
692 vam->async_errors += (retval < 0); \
694 vam->retval = retval; \
695 vam->result_ready = 1; \
698 foreach_standard_reply_retval_handler;
702 static void vl_api_##n##_t_handler_json \
703 (vl_api_##n##_t * mp) \
705 vat_main_t * vam = &vat_main; \
706 vat_json_node_t node; \
707 vat_json_init_object(&node); \
708 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
709 vat_json_print(vam->ofp, &node); \
710 vam->retval = ntohl(mp->retval); \
711 vam->result_ready = 1; \
713 foreach_standard_reply_retval_handler;
717 * Table of message reply handlers, must include boilerplate handlers
721 #define foreach_vpe_api_reply_msg \
722 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
723 _ (CONTROL_PING_REPLY, control_ping_reply)
725 #define foreach_standalone_reply_msg \
733 #define STR_VTR_OP_CASE(op) \
734 case L2_VTR_ ## op: \
738 str_vtr_op (u32 vtr_op)
742 STR_VTR_OP_CASE (DISABLED);
743 STR_VTR_OP_CASE (PUSH_1);
744 STR_VTR_OP_CASE (PUSH_2);
745 STR_VTR_OP_CASE (POP_1);
746 STR_VTR_OP_CASE (POP_2);
747 STR_VTR_OP_CASE (TRANSLATE_1_1);
748 STR_VTR_OP_CASE (TRANSLATE_1_2);
749 STR_VTR_OP_CASE (TRANSLATE_2_1);
750 STR_VTR_OP_CASE (TRANSLATE_2_2);
757 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
759 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
762 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
768 addr->function = x[3];
774 unformat_fib_path (unformat_input_t *input, va_list *args)
776 vat_main_t *vam = va_arg (*args, vat_main_t *);
777 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
778 u32 weight, preference;
779 mpls_label_t out_label;
781 clib_memset (path, 0, sizeof (*path));
783 path->sw_if_index = ~0;
787 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
789 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
790 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
793 path->proto = FIB_API_PATH_NH_PROTO_IP4;
795 else if (unformat (input, "%U %U",
796 unformat_vl_api_ip6_address,
797 &path->nh.address.ip6,
798 api_unformat_sw_if_index, vam, &path->sw_if_index))
800 path->proto = FIB_API_PATH_NH_PROTO_IP6;
802 else if (unformat (input, "weight %u", &weight))
804 path->weight = weight;
806 else if (unformat (input, "preference %u", &preference))
808 path->preference = preference;
810 else if (unformat (input, "%U next-hop-table %d",
811 unformat_vl_api_ip4_address,
812 &path->nh.address.ip4, &path->table_id))
814 path->proto = FIB_API_PATH_NH_PROTO_IP4;
816 else if (unformat (input, "%U next-hop-table %d",
817 unformat_vl_api_ip6_address,
818 &path->nh.address.ip6, &path->table_id))
820 path->proto = FIB_API_PATH_NH_PROTO_IP6;
822 else if (unformat (input, "%U",
823 unformat_vl_api_ip4_address, &path->nh.address.ip4))
826 * the recursive next-hops are by default in the default table
829 path->sw_if_index = ~0;
830 path->proto = FIB_API_PATH_NH_PROTO_IP4;
832 else if (unformat (input, "%U",
833 unformat_vl_api_ip6_address, &path->nh.address.ip6))
836 * the recursive next-hops are by default in the default table
839 path->sw_if_index = ~0;
840 path->proto = FIB_API_PATH_NH_PROTO_IP6;
842 else if (unformat (input, "resolve-via-host"))
844 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
846 else if (unformat (input, "resolve-via-attached"))
848 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
850 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
852 path->type = FIB_API_PATH_TYPE_LOCAL;
853 path->sw_if_index = ~0;
854 path->proto = FIB_API_PATH_NH_PROTO_IP4;
856 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
858 path->type = FIB_API_PATH_TYPE_LOCAL;
859 path->sw_if_index = ~0;
860 path->proto = FIB_API_PATH_NH_PROTO_IP6;
862 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
864 else if (unformat (input, "via-label %d", &path->nh.via_label))
866 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
867 path->sw_if_index = ~0;
869 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
871 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
872 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
874 else if (unformat (input, "local"))
876 path->type = FIB_API_PATH_TYPE_LOCAL;
878 else if (unformat (input, "out-labels"))
880 while (unformat (input, "%d", &out_label))
882 path->label_stack[path->n_labels].label = out_label;
883 path->label_stack[path->n_labels].is_uniform = 0;
884 path->label_stack[path->n_labels].ttl = 64;
888 else if (unformat (input, "via"))
890 /* new path, back up and return */
891 unformat_put_input (input);
892 unformat_put_input (input);
893 unformat_put_input (input);
894 unformat_put_input (input);
903 path->proto = ntohl (path->proto);
904 path->type = ntohl (path->type);
905 path->flags = ntohl (path->flags);
906 path->table_id = ntohl (path->table_id);
907 path->sw_if_index = ntohl (path->sw_if_index);
912 #define foreach_create_subif_bit \
919 _(outer_vlan_id_any) \
922 #define foreach_create_subif_flag \
927 _(4, "exact_match") \
928 _(5, "default_sub") \
929 _(6, "outer_vlan_id_any") \
930 _(7, "inner_vlan_id_any")
933 #define foreach_tcp_proto_field \
937 #define foreach_udp_proto_field \
941 #define foreach_ip4_proto_field \
953 u16 src_port, dst_port;
956 #if VPP_API_TEST_BUILTIN == 0
958 unformat_tcp_mask (unformat_input_t *input, va_list *args)
960 u8 **maskp = va_arg (*args, u8 **);
962 u8 found_something = 0;
965 #define _(a) u8 a = 0;
966 foreach_tcp_proto_field;
969 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
973 #define _(a) else if (unformat (input, #a)) a = 1;
974 foreach_tcp_proto_field
979 #define _(a) found_something += a;
980 foreach_tcp_proto_field;
983 if (found_something == 0)
986 vec_validate (mask, sizeof (*tcp) - 1);
988 tcp = (tcp_header_t *) mask;
992 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
993 foreach_tcp_proto_field;
1001 unformat_udp_mask (unformat_input_t *input, va_list *args)
1003 u8 **maskp = va_arg (*args, u8 **);
1005 u8 found_something = 0;
1008 #define _(a) u8 a = 0;
1009 foreach_udp_proto_field;
1012 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1016 #define _(a) else if (unformat (input, #a)) a = 1;
1017 foreach_udp_proto_field
1022 #define _(a) found_something += a;
1023 foreach_udp_proto_field;
1026 if (found_something == 0)
1029 vec_validate (mask, sizeof (*udp) - 1);
1031 udp = (udp_header_t *) mask;
1035 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1036 foreach_udp_proto_field;
1044 unformat_l4_mask (unformat_input_t *input, va_list *args)
1046 u8 **maskp = va_arg (*args, u8 **);
1047 u16 src_port = 0, dst_port = 0;
1048 tcpudp_header_t *tcpudp;
1050 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1052 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1054 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1056 else if (unformat (input, "src_port"))
1058 else if (unformat (input, "dst_port"))
1064 if (!src_port && !dst_port)
1068 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1070 tcpudp = (tcpudp_header_t *) mask;
1071 tcpudp->src_port = src_port;
1072 tcpudp->dst_port = dst_port;
1080 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1082 u8 **maskp = va_arg (*args, u8 **);
1084 u8 found_something = 0;
1087 #define _(a) u8 a=0;
1088 foreach_ip4_proto_field;
1094 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1096 if (unformat (input, "version"))
1098 else if (unformat (input, "hdr_length"))
1100 else if (unformat (input, "src"))
1102 else if (unformat (input, "dst"))
1104 else if (unformat (input, "proto"))
1107 #define _(a) else if (unformat (input, #a)) a=1;
1108 foreach_ip4_proto_field
1114 #define _(a) found_something += a;
1115 foreach_ip4_proto_field;
1118 if (found_something == 0)
1121 vec_validate (mask, sizeof (*ip) - 1);
1123 ip = (ip4_header_t *) mask;
1125 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1126 foreach_ip4_proto_field;
1129 ip->ip_version_and_header_length = 0;
1132 ip->ip_version_and_header_length |= 0xF0;
1135 ip->ip_version_and_header_length |= 0x0F;
1141 #define foreach_ip6_proto_field \
1149 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1151 u8 **maskp = va_arg (*args, u8 **);
1153 u8 found_something = 0;
1155 u32 ip_version_traffic_class_and_flow_label;
1157 #define _(a) u8 a=0;
1158 foreach_ip6_proto_field;
1161 u8 traffic_class = 0;
1164 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1166 if (unformat (input, "version"))
1168 else if (unformat (input, "traffic-class"))
1170 else if (unformat (input, "flow-label"))
1172 else if (unformat (input, "src"))
1174 else if (unformat (input, "dst"))
1176 else if (unformat (input, "proto"))
1179 #define _(a) else if (unformat (input, #a)) a=1;
1180 foreach_ip6_proto_field
1186 #define _(a) found_something += a;
1187 foreach_ip6_proto_field;
1190 if (found_something == 0)
1193 vec_validate (mask, sizeof (*ip) - 1);
1195 ip = (ip6_header_t *) mask;
1197 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1198 foreach_ip6_proto_field;
1201 ip_version_traffic_class_and_flow_label = 0;
1204 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1207 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1210 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1212 ip->ip_version_traffic_class_and_flow_label =
1213 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1220 unformat_l3_mask (unformat_input_t * input, va_list * args)
1222 u8 **maskp = va_arg (*args, u8 **);
1224 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1226 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1228 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1237 unformat_l2_mask (unformat_input_t * input, va_list * args)
1239 u8 **maskp = va_arg (*args, u8 **);
1254 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1256 if (unformat (input, "src"))
1258 else if (unformat (input, "dst"))
1260 else if (unformat (input, "proto"))
1262 else if (unformat (input, "tag1"))
1264 else if (unformat (input, "tag2"))
1266 else if (unformat (input, "ignore-tag1"))
1268 else if (unformat (input, "ignore-tag2"))
1270 else if (unformat (input, "cos1"))
1272 else if (unformat (input, "cos2"))
1274 else if (unformat (input, "dot1q"))
1276 else if (unformat (input, "dot1ad"))
1281 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1282 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1285 if (tag1 || ignore_tag1 || cos1 || dot1q)
1287 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1290 vec_validate (mask, len - 1);
1293 clib_memset (mask, 0xff, 6);
1296 clib_memset (mask + 6, 0xff, 6);
1300 /* inner vlan tag */
1309 mask[21] = mask[20] = 0xff;
1330 mask[16] = mask[17] = 0xff;
1340 mask[12] = mask[13] = 0xff;
1347 unformat_classify_mask (unformat_input_t * input, va_list * args)
1349 u8 **maskp = va_arg (*args, u8 **);
1350 u32 *skipp = va_arg (*args, u32 *);
1351 u32 *matchp = va_arg (*args, u32 *);
1359 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1361 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1363 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1365 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1367 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1381 if (mask || l2 || l3 || l4)
1385 /* "With a free Ethernet header in every package" */
1387 vec_validate (l2, 13);
1391 vec_append (mask, l3);
1396 vec_append (mask, l4);
1401 /* Scan forward looking for the first significant mask octet */
1402 for (i = 0; i < vec_len (mask); i++)
1406 /* compute (skip, match) params */
1407 *skipp = i / sizeof (u32x4);
1408 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1410 /* Pad mask to an even multiple of the vector size */
1411 while (vec_len (mask) % sizeof (u32x4))
1414 match = vec_len (mask) / sizeof (u32x4);
1416 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1418 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1419 if (*tmp || *(tmp + 1))
1424 clib_warning ("BUG: match 0");
1426 _vec_len (mask) = match * sizeof (u32x4);
1436 #endif /* VPP_API_TEST_BUILTIN */
1438 #define foreach_l2_next \
1440 _(ethernet, ETHERNET_INPUT) \
1445 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1447 u32 *miss_next_indexp = va_arg (*args, u32 *);
1452 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1456 if (unformat (input, "%d", &tmp))
1465 *miss_next_indexp = next_index;
1469 #define foreach_ip_next \
1475 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1477 u32 *miss_next_indexp = va_arg (*args, u32 *);
1482 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1486 if (unformat (input, "%d", &tmp))
1495 *miss_next_indexp = next_index;
1499 #define foreach_acl_next \
1503 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1505 u32 *miss_next_indexp = va_arg (*args, u32 *);
1510 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1514 if (unformat (input, "permit"))
1519 else if (unformat (input, "%d", &tmp))
1528 *miss_next_indexp = next_index;
1533 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1535 u32 *r = va_arg (*args, u32 *);
1537 if (unformat (input, "conform-color"))
1538 *r = POLICE_CONFORM;
1539 else if (unformat (input, "exceed-color"))
1547 #if VPP_API_TEST_BUILTIN == 0
1549 unformat_l4_match (unformat_input_t * input, va_list * args)
1551 u8 **matchp = va_arg (*args, u8 **);
1553 u8 *proto_header = 0;
1559 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1561 if (unformat (input, "src_port %d", &src_port))
1563 else if (unformat (input, "dst_port %d", &dst_port))
1569 h.src_port = clib_host_to_net_u16 (src_port);
1570 h.dst_port = clib_host_to_net_u16 (dst_port);
1571 vec_validate (proto_header, sizeof (h) - 1);
1572 memcpy (proto_header, &h, sizeof (h));
1574 *matchp = proto_header;
1580 unformat_ip4_match (unformat_input_t * input, va_list * args)
1582 u8 **matchp = va_arg (*args, u8 **);
1589 int src = 0, dst = 0;
1590 ip4_address_t src_val, dst_val;
1597 int fragment_id = 0;
1598 u32 fragment_id_val;
1604 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1606 if (unformat (input, "version %d", &version_val))
1608 else if (unformat (input, "hdr_length %d", &hdr_length_val))
1610 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
1612 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
1614 else if (unformat (input, "proto %d", &proto_val))
1616 else if (unformat (input, "tos %d", &tos_val))
1618 else if (unformat (input, "length %d", &length_val))
1620 else if (unformat (input, "fragment_id %d", &fragment_id_val))
1622 else if (unformat (input, "ttl %d", &ttl_val))
1624 else if (unformat (input, "checksum %d", &checksum_val))
1630 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1631 + ttl + checksum == 0)
1635 * Aligned because we use the real comparison functions
1637 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1639 ip = (ip4_header_t *) match;
1641 /* These are realistically matched in practice */
1643 ip->src_address.as_u32 = src_val.as_u32;
1646 ip->dst_address.as_u32 = dst_val.as_u32;
1649 ip->protocol = proto_val;
1652 /* These are not, but they're included for completeness */
1654 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
1657 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
1663 ip->length = clib_host_to_net_u16 (length_val);
1669 ip->checksum = clib_host_to_net_u16 (checksum_val);
1676 unformat_ip6_match (unformat_input_t * input, va_list * args)
1678 u8 **matchp = va_arg (*args, u8 **);
1683 u8 traffic_class = 0;
1684 u32 traffic_class_val = 0;
1687 int src = 0, dst = 0;
1688 ip6_address_t src_val, dst_val;
1691 int payload_length = 0;
1692 u32 payload_length_val;
1695 u32 ip_version_traffic_class_and_flow_label;
1697 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1699 if (unformat (input, "version %d", &version_val))
1701 else if (unformat (input, "traffic_class %d", &traffic_class_val))
1703 else if (unformat (input, "flow_label %d", &flow_label_val))
1705 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
1707 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
1709 else if (unformat (input, "proto %d", &proto_val))
1711 else if (unformat (input, "payload_length %d", &payload_length_val))
1713 else if (unformat (input, "hop_limit %d", &hop_limit_val))
1719 if (version + traffic_class + flow_label + src + dst + proto +
1720 payload_length + hop_limit == 0)
1724 * Aligned because we use the real comparison functions
1726 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1728 ip = (ip6_header_t *) match;
1731 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
1734 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
1737 ip->protocol = proto_val;
1739 ip_version_traffic_class_and_flow_label = 0;
1742 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1745 ip_version_traffic_class_and_flow_label |=
1746 (traffic_class_val & 0xFF) << 20;
1749 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1751 ip->ip_version_traffic_class_and_flow_label =
1752 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1755 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
1758 ip->hop_limit = hop_limit_val;
1765 unformat_l3_match (unformat_input_t * input, va_list * args)
1767 u8 **matchp = va_arg (*args, u8 **);
1769 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1771 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
1773 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
1782 unformat_vlan_tag (unformat_input_t * input, va_list * args)
1784 u8 *tagp = va_arg (*args, u8 *);
1787 if (unformat (input, "%d", &tag))
1789 tagp[0] = (tag >> 8) & 0x0F;
1790 tagp[1] = tag & 0xFF;
1798 unformat_l2_match (unformat_input_t * input, va_list * args)
1800 u8 **matchp = va_arg (*args, u8 **);
1820 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1822 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
1825 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
1827 else if (unformat (input, "proto %U",
1828 unformat_ethernet_type_host_byte_order, &proto_val))
1830 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
1832 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
1834 else if (unformat (input, "ignore-tag1"))
1836 else if (unformat (input, "ignore-tag2"))
1838 else if (unformat (input, "cos1 %d", &cos1_val))
1840 else if (unformat (input, "cos2 %d", &cos2_val))
1845 if ((src + dst + proto + tag1 + tag2 +
1846 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1849 if (tag1 || ignore_tag1 || cos1)
1851 if (tag2 || ignore_tag2 || cos2)
1854 vec_validate_aligned (match, len - 1, sizeof (u32x4));
1857 clib_memcpy (match, dst_val, 6);
1860 clib_memcpy (match + 6, src_val, 6);
1864 /* inner vlan tag */
1865 match[19] = tag2_val[1];
1866 match[18] = tag2_val[0];
1868 match[18] |= (cos2_val & 0x7) << 5;
1871 match[21] = proto_val & 0xff;
1872 match[20] = proto_val >> 8;
1876 match[15] = tag1_val[1];
1877 match[14] = tag1_val[0];
1880 match[14] |= (cos1_val & 0x7) << 5;
1886 match[15] = tag1_val[1];
1887 match[14] = tag1_val[0];
1890 match[17] = proto_val & 0xff;
1891 match[16] = proto_val >> 8;
1894 match[14] |= (cos1_val & 0x7) << 5;
1900 match[18] |= (cos2_val & 0x7) << 5;
1902 match[14] |= (cos1_val & 0x7) << 5;
1905 match[13] = proto_val & 0xff;
1906 match[12] = proto_val >> 8;
1914 unformat_qos_source (unformat_input_t * input, va_list * args)
1916 int *qs = va_arg (*args, int *);
1918 if (unformat (input, "ip"))
1919 *qs = QOS_SOURCE_IP;
1920 else if (unformat (input, "mpls"))
1921 *qs = QOS_SOURCE_MPLS;
1922 else if (unformat (input, "ext"))
1923 *qs = QOS_SOURCE_EXT;
1924 else if (unformat (input, "vlan"))
1925 *qs = QOS_SOURCE_VLAN;
1934 api_unformat_classify_match (unformat_input_t * input, va_list * args)
1936 u8 **matchp = va_arg (*args, u8 **);
1937 u32 skip_n_vectors = va_arg (*args, u32);
1938 u32 match_n_vectors = va_arg (*args, u32);
1945 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1947 if (unformat (input, "hex %U", unformat_hex_string, &match))
1949 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
1951 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
1953 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
1967 if (match || l2 || l3 || l4)
1971 /* "Win a free Ethernet header in every packet" */
1973 vec_validate_aligned (l2, 13, sizeof (u32x4));
1977 vec_append_aligned (match, l3, sizeof (u32x4));
1982 vec_append_aligned (match, l4, sizeof (u32x4));
1987 /* Make sure the vector is big enough even if key is all 0's */
1988 vec_validate_aligned
1989 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
1992 /* Set size, include skipped vectors */
1993 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
2003 #define foreach_vtr_op \
2004 _ ("disable", L2_VTR_DISABLED) \
2005 _ ("push-1", L2_VTR_PUSH_1) \
2006 _ ("push-2", L2_VTR_PUSH_2) \
2007 _ ("pop-1", L2_VTR_POP_1) \
2008 _ ("pop-2", L2_VTR_POP_2) \
2009 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2010 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2011 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2012 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2015 api_get_first_msg_id (vat_main_t *vam)
2017 vl_api_get_first_msg_id_t *mp;
2018 unformat_input_t *i = vam->input;
2023 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2025 if (unformat (i, "client %s", &name))
2033 errmsg ("missing client name");
2038 if (vec_len (name) > 63)
2040 errmsg ("client name too long");
2044 M (GET_FIRST_MSG_ID, mp);
2045 clib_memcpy (mp->name, name, vec_len (name));
2051 #define foreach_pbb_vtr_op \
2052 _("disable", L2_VTR_DISABLED) \
2053 _("pop", L2_VTR_POP_2) \
2054 _("push", L2_VTR_PUSH_2)
2057 api_sock_init_shm (vat_main_t * vam)
2059 #if VPP_API_TEST_BUILTIN == 0
2060 unformat_input_t *i = vam->input;
2061 vl_api_shm_elem_config_t *config = 0;
2062 u64 size = 64 << 20;
2065 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2067 if (unformat (i, "size %U", unformat_memory_size, &size))
2074 * Canned custom ring allocator config.
2075 * Should probably parse all of this
2077 vec_validate (config, 6);
2078 config[0].type = VL_API_VLIB_RING;
2079 config[0].size = 256;
2080 config[0].count = 32;
2082 config[1].type = VL_API_VLIB_RING;
2083 config[1].size = 1024;
2084 config[1].count = 16;
2086 config[2].type = VL_API_VLIB_RING;
2087 config[2].size = 4096;
2088 config[2].count = 2;
2090 config[3].type = VL_API_CLIENT_RING;
2091 config[3].size = 256;
2092 config[3].count = 32;
2094 config[4].type = VL_API_CLIENT_RING;
2095 config[4].size = 1024;
2096 config[4].count = 16;
2098 config[5].type = VL_API_CLIENT_RING;
2099 config[5].size = 4096;
2100 config[5].count = 2;
2102 config[6].type = VL_API_QUEUE;
2103 config[6].count = 128;
2104 config[6].size = sizeof (uword);
2106 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2108 vam->client_index_invalid = 1;
2116 q_or_quit (vat_main_t * vam)
2118 #if VPP_API_TEST_BUILTIN == 0
2119 longjmp (vam->jump_buf, 1);
2121 return 0; /* not so much */
2125 q (vat_main_t * vam)
2127 return q_or_quit (vam);
2131 quit (vat_main_t * vam)
2133 return q_or_quit (vam);
2137 comment (vat_main_t * vam)
2143 elog_save (vat_main_t * vam)
2145 #if VPP_API_TEST_BUILTIN == 0
2146 elog_main_t *em = &vam->elog_main;
2147 unformat_input_t *i = vam->input;
2148 char *file, *chroot_file;
2149 clib_error_t *error;
2151 if (!unformat (i, "%s", &file))
2153 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2157 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2158 if (strstr (file, "..") || index (file, '/'))
2160 errmsg ("illegal characters in filename '%s'", file);
2164 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2168 errmsg ("Saving %wd of %wd events to %s",
2169 elog_n_events_in_buffer (em),
2170 elog_buffer_capacity (em), chroot_file);
2172 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2173 vec_free (chroot_file);
2176 clib_error_report (error);
2178 errmsg ("Use the vpp event loger...");
2185 elog_setup (vat_main_t * vam)
2187 #if VPP_API_TEST_BUILTIN == 0
2188 elog_main_t *em = &vam->elog_main;
2189 unformat_input_t *i = vam->input;
2190 u32 nevents = 128 << 10;
2192 (void) unformat (i, "nevents %d", &nevents);
2194 elog_init (em, nevents);
2195 vl_api_set_elog_main (em);
2196 vl_api_set_elog_trace_api_messages (1);
2197 errmsg ("Event logger initialized with %u events", nevents);
2199 errmsg ("Use the vpp event loger...");
2205 elog_enable (vat_main_t * vam)
2207 #if VPP_API_TEST_BUILTIN == 0
2208 elog_main_t *em = &vam->elog_main;
2210 elog_enable_disable (em, 1 /* enable */ );
2211 vl_api_set_elog_trace_api_messages (1);
2212 errmsg ("Event logger enabled...");
2214 errmsg ("Use the vpp event loger...");
2220 elog_disable (vat_main_t * vam)
2222 #if VPP_API_TEST_BUILTIN == 0
2223 elog_main_t *em = &vam->elog_main;
2225 elog_enable_disable (em, 0 /* enable */ );
2226 vl_api_set_elog_trace_api_messages (1);
2227 errmsg ("Event logger disabled...");
2229 errmsg ("Use the vpp event loger...");
2235 statseg (vat_main_t * vam)
2237 ssvm_private_t *ssvmp = &vam->stat_segment;
2238 ssvm_shared_header_t *shared_header = ssvmp->sh;
2239 vlib_counter_t **counters;
2240 u64 thread0_index1_packets;
2241 u64 thread0_index1_bytes;
2242 f64 vector_rate, input_rate;
2245 uword *counter_vector_by_name;
2246 if (vam->stat_segment_lockp == 0)
2248 errmsg ("Stat segment not mapped...");
2252 /* look up "/if/rx for sw_if_index 1 as a test */
2254 clib_spinlock_lock (vam->stat_segment_lockp);
2256 counter_vector_by_name = (uword *) shared_header->opaque[1];
2258 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2261 clib_spinlock_unlock (vam->stat_segment_lockp);
2262 errmsg ("/if/tx not found?");
2266 /* Fish per-thread vector of combined counters from shared memory */
2267 counters = (vlib_counter_t **) p[0];
2269 if (vec_len (counters[0]) < 2)
2271 clib_spinlock_unlock (vam->stat_segment_lockp);
2272 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2276 /* Read thread 0 sw_if_index 1 counter */
2277 thread0_index1_packets = counters[0][1].packets;
2278 thread0_index1_bytes = counters[0][1].bytes;
2280 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2283 clib_spinlock_unlock (vam->stat_segment_lockp);
2284 errmsg ("vector_rate not found?");
2288 vector_rate = *(f64 *) (p[0]);
2289 p = hash_get_mem (counter_vector_by_name, "input_rate");
2292 clib_spinlock_unlock (vam->stat_segment_lockp);
2293 errmsg ("input_rate not found?");
2296 input_rate = *(f64 *) (p[0]);
2298 clib_spinlock_unlock (vam->stat_segment_lockp);
2300 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2301 vector_rate, input_rate);
2302 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2303 thread0_index1_packets, thread0_index1_bytes);
2309 cmd_cmp (void *a1, void *a2)
2314 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2318 help (vat_main_t * vam)
2323 unformat_input_t *i = vam->input;
2326 if (unformat (i, "%s", &name))
2332 hs = hash_get_mem (vam->help_by_name, name);
2334 print (vam->ofp, "usage: %s %s", name, hs[0]);
2336 print (vam->ofp, "No such msg / command '%s'", name);
2341 print (vam->ofp, "Help is available for the following:");
2343 hash_foreach_pair (p, vam->function_by_name,
2345 vec_add1 (cmds, (u8 *)(p->key));
2348 vec_sort_with_function (cmds, cmd_cmp);
2350 for (j = 0; j < vec_len (cmds); j++)
2351 print (vam->ofp, "%s", cmds[j]);
2358 set (vat_main_t * vam)
2360 u8 *name = 0, *value = 0;
2361 unformat_input_t *i = vam->input;
2363 if (unformat (i, "%s", &name))
2365 /* The input buffer is a vector, not a string. */
2366 value = vec_dup (i->buffer);
2367 vec_delete (value, i->index, 0);
2368 /* Almost certainly has a trailing newline */
2369 if (value[vec_len (value) - 1] == '\n')
2370 value[vec_len (value) - 1] = 0;
2371 /* Make sure it's a proper string, one way or the other */
2372 vec_add1 (value, 0);
2373 (void) clib_macro_set_value (&vam->macro_main,
2374 (char *) name, (char *) value);
2377 errmsg ("usage: set <name> <value>");
2385 unset (vat_main_t * vam)
2389 if (unformat (vam->input, "%s", &name))
2390 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2391 errmsg ("unset: %s wasn't set", name);
2404 macro_sort_cmp (void *a1, void *a2)
2406 macro_sort_t *s1 = a1;
2407 macro_sort_t *s2 = a2;
2409 return strcmp ((char *) (s1->name), (char *) (s2->name));
2413 dump_macro_table (vat_main_t * vam)
2415 macro_sort_t *sort_me = 0, *sm;
2419 hash_foreach_pair (p, vam->macro_main.the_value_table_hash, ({
2420 vec_add2 (sort_me, sm, 1);
2421 sm->name = (u8 *) (p->key);
2422 sm->value = (u8 *) (p->value[0]);
2425 vec_sort_with_function (sort_me, macro_sort_cmp);
2427 if (vec_len (sort_me))
2428 print (vam->ofp, "%-15s%s", "Name", "Value");
2430 print (vam->ofp, "The macro table is empty...");
2432 for (i = 0; i < vec_len (sort_me); i++)
2433 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
2438 value_sort_cmp (void *a1, void *a2)
2440 name_sort_t *n1 = a1;
2441 name_sort_t *n2 = a2;
2443 if (n1->value < n2->value)
2445 if (n1->value > n2->value)
2452 dump_msg_api_table (vat_main_t * vam)
2454 api_main_t *am = vlibapi_get_main ();
2455 name_sort_t *nses = 0, *ns;
2459 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
2461 vec_add2 (nses, ns, 1);
2462 ns->name = (u8 *)(hp->key);
2463 ns->value = (u32) hp->value[0];
2466 vec_sort_with_function (nses, value_sort_cmp);
2468 for (i = 0; i < vec_len (nses); i++)
2469 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
2475 get_msg_id (vat_main_t * vam)
2480 if (unformat (vam->input, "%s", &name_and_crc))
2482 message_index = vl_msg_api_get_msg_index (name_and_crc);
2483 if (message_index == ~0)
2485 print (vam->ofp, " '%s' not found", name_and_crc);
2488 print (vam->ofp, " '%s' has message index %d",
2489 name_and_crc, message_index);
2492 errmsg ("name_and_crc required...");
2497 search_node_table (vat_main_t * vam)
2499 unformat_input_t *line_input = vam->input;
2502 vlib_node_t *node, *next_node;
2505 if (vam->graph_node_index_by_name == 0)
2507 print (vam->ofp, "Node table empty, issue get_node_graph...");
2511 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2513 if (unformat (line_input, "%s", &node_to_find))
2515 vec_add1 (node_to_find, 0);
2516 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
2519 print (vam->ofp, "%s not found...", node_to_find);
2522 node = vam->graph_nodes[0][p[0]];
2523 print (vam->ofp, "[%d] %s", p[0], node->name);
2524 for (j = 0; j < vec_len (node->next_nodes); j++)
2526 if (node->next_nodes[j] != ~0)
2528 next_node = vam->graph_nodes[0][node->next_nodes[j]];
2529 print (vam->ofp, " [%d] %s", j, next_node->name);
2536 clib_warning ("parse error '%U'", format_unformat_error,
2542 vec_free (node_to_find);
2551 script (vat_main_t * vam)
2553 #if (VPP_API_TEST_BUILTIN==0)
2555 char *save_current_file;
2556 unformat_input_t save_input;
2557 jmp_buf save_jump_buf;
2558 u32 save_line_number;
2560 FILE *new_fp, *save_ifp;
2562 if (unformat (vam->input, "%s", &s))
2564 new_fp = fopen ((char *) s, "r");
2567 errmsg ("Couldn't open script file %s", s);
2574 errmsg ("Missing script name");
2578 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
2579 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
2580 save_ifp = vam->ifp;
2581 save_line_number = vam->input_line_number;
2582 save_current_file = (char *) vam->current_file;
2584 vam->input_line_number = 0;
2586 vam->current_file = s;
2589 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
2590 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
2591 vam->ifp = save_ifp;
2592 vam->input_line_number = save_line_number;
2593 vam->current_file = (u8 *) save_current_file;
2598 clib_warning ("use the exec command...");
2604 echo (vat_main_t * vam)
2606 print (vam->ofp, "%v", vam->input->buffer);
2610 int exec (vat_main_t *vam) __attribute__ ((weak));
2612 exec (vat_main_t *vam)
2618 name_sort_cmp (void *a1, void *a2)
2620 name_sort_t *n1 = a1;
2621 name_sort_t *n2 = a2;
2623 return strcmp ((char *) n1->name, (char *) n2->name);
2627 dump_interface_table (vat_main_t *vam)
2630 name_sort_t *nses = 0, *ns;
2632 if (vam->json_output)
2635 "JSON output supported only for VPE API calls and dump_stats_table");
2639 hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
2640 vec_add2 (nses, ns, 1);
2641 ns->name = (u8 *) (p->key);
2642 ns->value = (u32) p->value[0];
2645 vec_sort_with_function (nses, name_sort_cmp);
2647 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
2648 vec_foreach (ns, nses)
2650 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
2657 dump_sub_interface_table (vat_main_t *vam)
2659 const sw_interface_subif_t *sub = NULL;
2661 if (vam->json_output)
2664 "JSON output supported only for VPE API calls and dump_stats_table");
2668 print (vam->ofp, "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
2669 "Interface", "sw_if_index", "sub id", "dot1ad", "tags", "outer id",
2670 "inner id", "exact", "default", "outer any", "inner any");
2672 vec_foreach (sub, vam->sw_if_subif_table)
2674 print (vam->ofp, "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
2675 sub->interface_name, sub->sw_if_index, sub->sub_id,
2676 sub->sub_dot1ad ? "dot1ad" : "dot1q", sub->sub_number_of_tags,
2677 sub->sub_outer_vlan_id, sub->sub_inner_vlan_id,
2678 sub->sub_exact_match, sub->sub_default,
2679 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2680 if (sub->vtr_op != L2_VTR_DISABLED)
2683 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2684 "tag1: %d tag2: %d ]",
2685 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q, sub->vtr_tag1,
2693 /* List of API message constructors, CLI names map to api_xxx */
2694 #define foreach_vpe_api_msg \
2695 _(get_first_msg_id, "client <name>") \
2696 _(sock_init_shm, "size <nnn>") \
2697 /* List of command functions, CLI names map directly to functions */
2698 #define foreach_cli_function \
2699 _ (comment, "usage: comment <ignore-rest-of-line>") \
2700 _ (dump_interface_table, "usage: dump_interface_table") \
2701 _ (dump_sub_interface_table, "usage: dump_sub_interface_table") \
2702 _ (dump_macro_table, "usage: dump_macro_table ") \
2703 _ (dump_msg_api_table, "usage: dump_msg_api_table") \
2704 _ (elog_setup, "usage: elog_setup [nevents, default 128K]") \
2705 _ (elog_disable, "usage: elog_disable") \
2706 _ (elog_enable, "usage: elog_enable") \
2707 _ (elog_save, "usage: elog_save <filename>") \
2708 _ (get_msg_id, "usage: get_msg_id name_and_crc") \
2709 _ (echo, "usage: echo <message>") \
2710 _ (help, "usage: help") \
2711 _ (q, "usage: quit") \
2712 _ (quit, "usage: quit") \
2713 _ (search_node_table, "usage: search_node_table <name>...") \
2714 _ (set, "usage: set <variable-name> <value>") \
2715 _ (script, "usage: script <file-name>") \
2716 _ (statseg, "usage: statseg") \
2717 _ (unset, "usage: unset <variable-name>")
2720 static void vl_api_##n##_t_handler_uni \
2721 (vl_api_##n##_t * mp) \
2723 vat_main_t * vam = &vat_main; \
2724 if (vam->json_output) { \
2725 vl_api_##n##_t_handler_json(mp); \
2727 vl_api_##n##_t_handler(mp); \
2730 foreach_vpe_api_reply_msg;
2731 #if VPP_API_TEST_BUILTIN == 0
2732 foreach_standalone_reply_msg;
2737 vat_api_hookup (vat_main_t * vam)
2740 vl_msg_api_set_handlers (VL_API_##N + 1, #n, vl_api_##n##_t_handler_uni, \
2741 vl_noop_handler, vl_api_##n##_t_endian, \
2742 vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1, \
2743 vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
2744 vl_api_##n##_t_fromjson);
2745 foreach_vpe_api_reply_msg;
2746 #if VPP_API_TEST_BUILTIN == 0
2747 foreach_standalone_reply_msg;
2751 #if (VPP_API_TEST_BUILTIN==0)
2752 vl_msg_api_set_first_available_msg_id (VL_MSG_MEMCLNT_LAST + 1);
2754 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2756 vam->function_by_name = hash_create_string (0, sizeof (uword));
2758 vam->help_by_name = hash_create_string (0, sizeof (uword));
2761 /* API messages we can send */
2762 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
2763 foreach_vpe_api_msg;
2767 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2768 foreach_vpe_api_msg;
2772 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
2773 foreach_cli_function;
2777 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2778 foreach_cli_function;
2782 #if VPP_API_TEST_BUILTIN
2783 static clib_error_t *
2784 vat_api_hookup_shim (vlib_main_t * vm)
2786 vat_api_hookup (&vat_main);
2790 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
2794 * fd.io coding-style-patch-verification: ON
2797 * eval: (c-set-style "gnu")