From 3d81267945a732753b0dbd0a83a50ab0625b448a Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Tue, 15 Sep 2020 10:53:34 +0200 Subject: vat: add infrastructure to align vnet test code and plugin test code Split vat/api_format.c also for VNET features. Use auto-generated VAT test code and support dynamic message ID allocation as for plugins. The arp and geneve features as Guinea pigs. Type: improvement Signed-off-by: Ole Troan Change-Id: I461591496766bdf10c5f950fd30f1a0ae05909da Signed-off-by: Ole Troan --- src/vat/CMakeLists.txt | 2 + src/vat/api_format.c | 383 ------------------------------------------------- src/vat/main.c | 22 +++ src/vat/vat.h | 29 ++++ 4 files changed, 53 insertions(+), 383 deletions(-) (limited to 'src/vat') diff --git a/src/vat/CMakeLists.txt b/src/vat/CMakeLists.txt index 9d37b7ba83e..ed14e846625 100644 --- a/src/vat/CMakeLists.txt +++ b/src/vat/CMakeLists.txt @@ -32,6 +32,8 @@ add_vpp_executable(vpp_api_test ENABLE_EXPORTS ip_types_api.c ip_types.c protocols.def + ../vnet/arp/arp_test.c + ../vnet/geneve/geneve_test.c DEPENDS api_headers diff --git a/src/vat/api_format.c b/src/vat/api_format.c index e3a2fe734be..765f4f4e7da 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -2523,40 +2522,6 @@ static void vl_api_vxlan_offload_rx_reply_t_handler_json vam->result_ready = 1; } -static void vl_api_geneve_add_del_tunnel_reply_t_handler - (vl_api_geneve_add_del_tunnel_reply_t * mp) -{ - vat_main_t *vam = &vat_main; - i32 retval = ntohl (mp->retval); - if (vam->async_mode) - { - vam->async_errors += (retval < 0); - } - else - { - vam->retval = retval; - vam->sw_if_index = ntohl (mp->sw_if_index); - vam->result_ready = 1; - } -} - -static void vl_api_geneve_add_del_tunnel_reply_t_handler_json - (vl_api_geneve_add_del_tunnel_reply_t * mp) -{ - vat_main_t *vam = &vat_main; - vat_json_node_t node; - - vat_json_init_object (&node); - vat_json_object_add_int (&node, "retval", ntohl (mp->retval)); - vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index)); - - vat_json_print (vam->ofp, &node); - vat_json_free (&node); - - vam->retval = ntohl (mp->retval); - vam->result_ready = 1; -} - static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp) { @@ -5122,7 +5087,6 @@ _(sw_interface_set_table_reply) \ _(sw_interface_set_mpls_enable_reply) \ _(sw_interface_set_vpath_reply) \ _(sw_interface_set_vxlan_bypass_reply) \ -_(sw_interface_set_geneve_bypass_reply) \ _(sw_interface_set_vxlan_gpe_bypass_reply) \ _(sw_interface_set_l2_bridge_reply) \ _(sw_interface_set_bond_weight_reply) \ @@ -5294,7 +5258,6 @@ _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \ _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \ _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \ _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \ -_(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \ _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \ _(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \ sw_interface_set_l2_xconnect_reply) \ @@ -5367,9 +5330,7 @@ _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \ _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \ _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \ _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply) \ -_(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply) \ _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \ -_(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details) \ _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply) \ _(GRE_TUNNEL_DETAILS, gre_tunnel_details) \ _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \ @@ -6527,57 +6488,6 @@ api_sw_interface_set_vxlan_bypass (vat_main_t * vam) return ret; } -static int -api_sw_interface_set_geneve_bypass (vat_main_t * vam) -{ - unformat_input_t *i = vam->input; - vl_api_sw_interface_set_geneve_bypass_t *mp; - u32 sw_if_index = 0; - u8 sw_if_index_set = 0; - u8 is_enable = 1; - u8 is_ipv6 = 0; - int ret; - - /* Parse args required to build the message */ - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) - { - if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) - sw_if_index_set = 1; - else if (unformat (i, "sw_if_index %d", &sw_if_index)) - sw_if_index_set = 1; - else if (unformat (i, "enable")) - is_enable = 1; - else if (unformat (i, "disable")) - is_enable = 0; - else if (unformat (i, "ip4")) - is_ipv6 = 0; - else if (unformat (i, "ip6")) - is_ipv6 = 1; - else - break; - } - - if (sw_if_index_set == 0) - { - errmsg ("missing interface name or sw_if_index"); - return -99; - } - - /* Construct the API message */ - M (SW_INTERFACE_SET_GENEVE_BYPASS, mp); - - mp->sw_if_index = ntohl (sw_if_index); - mp->enable = is_enable; - mp->is_ipv6 = is_ipv6; - - /* send it... */ - S (mp); - - /* Wait for a reply... */ - W (ret); - return ret; -} - static int api_sw_interface_set_l2_xconnect (vat_main_t * vam) { @@ -12022,292 +11932,6 @@ api_vxlan_tunnel_dump (vat_main_t * vam) return ret; } -static uword unformat_geneve_decap_next - (unformat_input_t * input, va_list * args) -{ - u32 *result = va_arg (*args, u32 *); - u32 tmp; - - if (unformat (input, "l2")) - *result = GENEVE_INPUT_NEXT_L2_INPUT; - else if (unformat (input, "%d", &tmp)) - *result = tmp; - else - return 0; - return 1; -} - -static int -api_geneve_add_del_tunnel (vat_main_t * vam) -{ - unformat_input_t *line_input = vam->input; - vl_api_geneve_add_del_tunnel_t *mp; - ip46_address_t src, dst; - u8 is_add = 1; - u8 ipv4_set = 0, ipv6_set = 0; - u8 src_set = 0; - u8 dst_set = 0; - u8 grp_set = 0; - u32 mcast_sw_if_index = ~0; - u32 encap_vrf_id = 0; - u32 decap_next_index = ~0; - u32 vni = 0; - int ret; - - /* Can't "universally zero init" (={0}) due to GCC bug 53119 */ - clib_memset (&src, 0, sizeof src); - clib_memset (&dst, 0, sizeof dst); - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "del")) - is_add = 0; - else - if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4)) - { - ipv4_set = 1; - src_set = 1; - } - else - if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4)) - { - ipv4_set = 1; - dst_set = 1; - } - else - if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6)) - { - ipv6_set = 1; - src_set = 1; - } - else - if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6)) - { - ipv6_set = 1; - dst_set = 1; - } - else if (unformat (line_input, "group %U %U", - unformat_ip4_address, &dst.ip4, - api_unformat_sw_if_index, vam, &mcast_sw_if_index)) - { - grp_set = dst_set = 1; - ipv4_set = 1; - } - else if (unformat (line_input, "group %U", - unformat_ip4_address, &dst.ip4)) - { - grp_set = dst_set = 1; - ipv4_set = 1; - } - else if (unformat (line_input, "group %U %U", - unformat_ip6_address, &dst.ip6, - api_unformat_sw_if_index, vam, &mcast_sw_if_index)) - { - grp_set = dst_set = 1; - ipv6_set = 1; - } - else if (unformat (line_input, "group %U", - unformat_ip6_address, &dst.ip6)) - { - grp_set = dst_set = 1; - ipv6_set = 1; - } - else - if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index)) - ; - else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id)) - ; - else if (unformat (line_input, "decap-next %U", - unformat_geneve_decap_next, &decap_next_index)) - ; - else if (unformat (line_input, "vni %d", &vni)) - ; - else - { - errmsg ("parse error '%U'", format_unformat_error, line_input); - return -99; - } - } - - if (src_set == 0) - { - errmsg ("tunnel src address not specified"); - return -99; - } - if (dst_set == 0) - { - errmsg ("tunnel dst address not specified"); - return -99; - } - - if (grp_set && !ip46_address_is_multicast (&dst)) - { - errmsg ("tunnel group address not multicast"); - return -99; - } - if (grp_set && mcast_sw_if_index == ~0) - { - errmsg ("tunnel nonexistent multicast device"); - return -99; - } - if (grp_set == 0 && ip46_address_is_multicast (&dst)) - { - errmsg ("tunnel dst address must be unicast"); - return -99; - } - - - if (ipv4_set && ipv6_set) - { - errmsg ("both IPv4 and IPv6 addresses specified"); - return -99; - } - - if ((vni == 0) || (vni >> 24)) - { - errmsg ("vni not specified or out of range"); - return -99; - } - - M (GENEVE_ADD_DEL_TUNNEL, mp); - - if (ipv6_set) - { - clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6)); - clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6)); - } - else - { - clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4)); - clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4)); - } - mp->encap_vrf_id = ntohl (encap_vrf_id); - mp->decap_next_index = ntohl (decap_next_index); - mp->mcast_sw_if_index = ntohl (mcast_sw_if_index); - mp->vni = ntohl (vni); - mp->is_add = is_add; - - S (mp); - W (ret); - return ret; -} - -static void vl_api_geneve_tunnel_details_t_handler - (vl_api_geneve_tunnel_details_t * mp) -{ - vat_main_t *vam = &vat_main; - ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 }; - ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 }; - - if (mp->src_address.af == ADDRESS_IP6) - { - clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t)); - clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t)); - } - else - { - clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t)); - clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t)); - } - - print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d", - ntohl (mp->sw_if_index), - format_ip46_address, &src, IP46_TYPE_ANY, - format_ip46_address, &dst, IP46_TYPE_ANY, - ntohl (mp->encap_vrf_id), - ntohl (mp->decap_next_index), ntohl (mp->vni), - ntohl (mp->mcast_sw_if_index)); -} - -static void vl_api_geneve_tunnel_details_t_handler_json - (vl_api_geneve_tunnel_details_t * mp) -{ - vat_main_t *vam = &vat_main; - vat_json_node_t *node = NULL; - bool is_ipv6; - - if (VAT_JSON_ARRAY != vam->json_tree.type) - { - ASSERT (VAT_JSON_NONE == vam->json_tree.type); - vat_json_init_array (&vam->json_tree); - } - node = vat_json_array_add (&vam->json_tree); - - vat_json_init_object (node); - vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index)); - is_ipv6 = mp->src_address.af == ADDRESS_IP6; - if (is_ipv6) - { - struct in6_addr ip6; - - clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6)); - vat_json_object_add_ip6 (node, "src_address", ip6); - clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6)); - vat_json_object_add_ip6 (node, "dst_address", ip6); - } - else - { - struct in_addr ip4; - - clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4)); - vat_json_object_add_ip4 (node, "src_address", ip4); - clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4)); - vat_json_object_add_ip4 (node, "dst_address", ip4); - } - vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id)); - vat_json_object_add_uint (node, "decap_next_index", - ntohl (mp->decap_next_index)); - vat_json_object_add_uint (node, "vni", ntohl (mp->vni)); - vat_json_object_add_uint (node, "mcast_sw_if_index", - ntohl (mp->mcast_sw_if_index)); -} - -static int -api_geneve_tunnel_dump (vat_main_t * vam) -{ - unformat_input_t *i = vam->input; - vl_api_geneve_tunnel_dump_t *mp; - vl_api_control_ping_t *mp_ping; - u32 sw_if_index; - u8 sw_if_index_set = 0; - int ret; - - /* Parse args required to build the message */ - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) - { - if (unformat (i, "sw_if_index %d", &sw_if_index)) - sw_if_index_set = 1; - else - break; - } - - if (sw_if_index_set == 0) - { - sw_if_index = ~0; - } - - if (!vam->json_output) - { - print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s", - "sw_if_index", "local_address", "remote_address", - "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index"); - } - - /* Get list of geneve-tunnel interfaces */ - M (GENEVE_TUNNEL_DUMP, mp); - - mp->sw_if_index = htonl (sw_if_index); - - S (mp); - - /* Use a control ping for synchronization */ - M (CONTROL_PING, mp_ping); - S (mp_ping); - - W (ret); - return ret; -} - static int api_gre_tunnel_add_del (vat_main_t * vam) { @@ -20784,8 +20408,6 @@ _(sw_interface_set_vpath, \ " | sw_if_index enable | disable") \ _(sw_interface_set_vxlan_bypass, \ " | sw_if_index [ip4 | ip6] [enable | disable]") \ -_(sw_interface_set_geneve_bypass, \ - " | sw_if_index [ip4 | ip6] [enable | disable]") \ _(sw_interface_set_l2_xconnect, \ "rx | rx_sw_if_index tx | tx_sw_if_index \n" \ "enable | disable") \ @@ -20924,12 +20546,7 @@ _(vxlan_add_del_tunnel, \ "src { dst | group \n" \ "{ | mcast_sw_if_index } [instance ]}\n" \ "vni [encap-vrf-id ] [decap-next ] [del]") \ -_(geneve_add_del_tunnel, \ - "src { dst | group \n" \ - "{ | mcast_sw_if_index } }\n" \ - "vni [encap-vrf-id ] [decap-next ] [del]") \ _(vxlan_tunnel_dump, "[ | sw_if_index ]") \ -_(geneve_tunnel_dump, "[ | sw_if_index ]") \ _(gre_tunnel_add_del, \ "src dst [outer-fib-id ] [instance ]\n" \ "[teb | erspan ] [del]") \ diff --git a/src/vat/main.c b/src/vat/main.c index 8a7ed6331f6..aaedf6c450b 100644 --- a/src/vat/main.c +++ b/src/vat/main.c @@ -318,6 +318,26 @@ vat_find_plugin_path () vat_plugin_path = (char *) s; } +static void +load_features (void) +{ + vat_registered_features_t *f; + vat_main_t *vam = &vat_main; + clib_error_t *error; + + f = vam->feature_function_registrations; + + while (f) + { + error = f->function (vam); + if (error) + { + clib_warning ("INIT FAILED"); + } + f = f->next; + } +} + int main (int argc, char **argv) { @@ -422,6 +442,8 @@ main (int argc, char **argv) vec_validate (vam->inbuf, 4096); + load_features (); + vam->current_file = (u8 *) "plugin-init"; vat_plugin_init (vam); diff --git a/src/vat/vat.h b/src/vat/vat.h index 3e9476f0a66..32de90e4411 100644 --- a/src/vat/vat.h +++ b/src/vat/vat.h @@ -127,6 +127,8 @@ typedef struct u64 bytes; } ip6_nbr_counter_t; +struct vat_registered_features_t; + typedef struct { /* vpe input queue */ @@ -228,6 +230,8 @@ typedef struct elog_main_t elog_main; + struct vat_registered_features_t *feature_function_registrations; + /* Convenience */ vlib_main_t *vlib_main; } vat_main_t; @@ -267,6 +271,31 @@ void api_cli_output (void *, const char *fmt, ...); void fformat_append_cr (FILE *, const char *fmt, ...); #endif + +typedef clib_error_t *(vat_feature_function_t) (vat_main_t * vam); +typedef struct vat_registered_features_t +{ + vat_feature_function_t *function; + struct vat_registered_features_t *next; +} vat_registered_features_t; + + +#define VAT_REGISTER_FEATURE_FUNCTION(x) \ + vat_registered_features_t _vat_feature_function_##x; \ +static void __vlib_add_config_function_##x (void) \ + __attribute__((__constructor__)) ; \ +static void __vlib_add_config_function_##x (void) \ +{ \ + vat_main_t * vam = &vat_main; \ + _vat_feature_function_##x.next = vam->feature_function_registrations; \ + vam->feature_function_registrations = &_vat_feature_function_##x; \ +} \ + vat_registered_features_t _vat_feature_function_##x = \ + { \ + .function = x, \ + } + + #endif /* __included_vat_h__ */ /* -- cgit 1.2.3-korg