From 97d54ed43eb69f6ea731c02305ebe0ca0b1a5cc4 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Mon, 10 Jun 2019 11:20:15 +0200 Subject: tap: add support to configure tap interface host MTU size This patch adds support to configure host mtu size using api, cli or startup.conf. Type: feature Change-Id: I8ab087d82dbe7dedc498825c1a3ea3fcb2cce030 Signed-off-by: Mohsin Kazmi --- src/vnet/devices/netlink.h | 1 + src/vnet/devices/tap/cli.c | 7 +++++- src/vnet/devices/tap/tap.c | 47 ++++++++++++++++++++++++++++++++++++++++ src/vnet/devices/tap/tap.h | 6 +++++ src/vnet/devices/tap/tapv2.api | 8 ++++++- src/vnet/devices/tap/tapv2_api.c | 7 ++++++ src/vnet/devices/virtio/virtio.c | 3 +++ src/vnet/devices/virtio/virtio.h | 1 + 8 files changed, 78 insertions(+), 2 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/devices/netlink.h b/src/vnet/devices/netlink.h index 0d3e0d23ac6..4c765685091 100644 --- a/src/vnet/devices/netlink.h +++ b/src/vnet/devices/netlink.h @@ -22,6 +22,7 @@ clib_error_t *vnet_netlink_set_link_netns (int ifindex, int netns_fd, clib_error_t *vnet_netlink_set_link_master (int ifindex, char *master_ifname); clib_error_t *vnet_netlink_set_link_addr (int ifindex, u8 * addr); clib_error_t *vnet_netlink_set_link_state (int ifindex, int up); +clib_error_t *vnet_netlink_set_link_mtu (int ifindex, int mtu); clib_error_t *vnet_netlink_add_ip4_addr (int ifindex, void *addr, int pfx_len); clib_error_t *vnet_netlink_add_ip6_addr (int ifindex, void *addr, diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c index 084fb908dc9..c74d24a12a9 100644 --- a/src/vnet/devices/tap/cli.c +++ b/src/vnet/devices/tap/cli.c @@ -76,6 +76,10 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input, ; else if (unformat (line_input, "tx-ring-size %d", &args.tx_ring_sz)) ; + else + if (unformat + (line_input, "host-mtu-size %d", &args.host_mtu_size)) + args.host_mtu_set = 1; else if (unformat (line_input, "no-gso")) args.tap_flags &= ~TAP_FLAG_GSO; else if (unformat (line_input, "gso")) @@ -114,7 +118,8 @@ VLIB_CLI_COMMAND (tap_create_command, static) = { "[rx-ring-size ] [tx-ring-size ] [host-ns ] " "[host-bridge ] [host-ip4-addr ] " "[host-ip6-addr ] [host-ip4-gw ] " - "[host-ip6-gw ] [host-if-name ] [no-gso|gso]", + "[host-ip6-gw ] [host-mac-addr ] " + "[host-if-name ] [host-mtu-size ] [no-gso|gso]", .function = tap_create_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 35f1f2a3451..8dc798a3cb3 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -361,6 +361,29 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } } + if (args->host_mtu_set) + { + args->error = + vnet_netlink_set_link_mtu (vif->ifindex, args->host_mtu_size); + if (args->error) + { + args->rv = VNET_API_ERROR_NETLINK_ERROR; + goto error; + } + } + else if (tm->host_mtu_size != 0) + { + args->error = + vnet_netlink_set_link_mtu (vif->ifindex, tm->host_mtu_size); + if (args->error) + { + args->rv = VNET_API_ERROR_NETLINK_ERROR; + goto error; + } + args->host_mtu_set = 1; + args->host_mtu_size = tm->host_mtu_size; + } + /* Set vhost memory table */ i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region); vhost_mem = clib_mem_alloc (i); @@ -396,6 +419,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) args->host_namespace = 0; vif->host_bridge = args->host_bridge; args->host_bridge = 0; + vif->host_mtu_size = args->host_mtu_size; clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6); vif->host_ip4_prefix_len = args->host_ip4_prefix_len; vif->host_ip6_prefix_len = args->host_ip6_prefix_len; @@ -627,6 +651,7 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) if (vif->host_ip6_prefix_len) clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16); tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len; + tapid->host_mtu_size = vif->host_mtu_size; ); /* *INDENT-ON* */ @@ -635,6 +660,26 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) return 0; } +static clib_error_t * +tap_mtu_config (vlib_main_t * vm, unformat_input_t * input) +{ + tap_main_t *tm = &tap_main; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "host-mtu %d", &tm->host_mtu_size)) + ; + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + } + + return 0; +} + +/* tap { host-mtu } configuration. */ +VLIB_CONFIG_FUNCTION (tap_mtu_config, "tap"); + static clib_error_t * tap_init (vlib_main_t * vm) { @@ -644,6 +689,8 @@ tap_init (vlib_main_t * vm) tm->log_default = vlib_log_register_class ("tap", 0); vlib_log_debug (tm->log_default, "initialized"); + tm->host_mtu_size = 0; + return error; } diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h index 745f9fca304..45ff1d9910e 100644 --- a/src/vnet/devices/tap/tap.h +++ b/src/vnet/devices/tap/tap.h @@ -43,6 +43,8 @@ typedef struct u8 host_ip6_prefix_len; ip6_address_t host_ip6_gw; u8 host_ip6_gw_set; + u8 host_mtu_set; + u32 host_mtu_size; /* return */ u32 sw_if_index; int rv; @@ -66,6 +68,7 @@ typedef struct u8 host_ip4_prefix_len; u8 host_ip6_addr[16]; u8 host_ip6_prefix_len; + u32 host_mtu_size; } tap_interface_details_t; typedef struct @@ -75,6 +78,9 @@ typedef struct /* bit-map of in-use IDs */ uword *tap_ids; + + /* host mtu size, configurable through startup.conf */ + int host_mtu_size; } tap_main_t; void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args); diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api index fb90483efbe..2d4d5c3497d 100644 --- a/src/vnet/devices/tap/tapv2.api +++ b/src/vnet/devices/tap/tapv2.api @@ -19,7 +19,7 @@ the Linux kernel TAP device driver */ -option version = "2.0.0"; +option version = "2.1.0"; /** \brief Initialize a new tap interface with the given paramters @param client_index - opaque cookie to identify the sender @@ -47,6 +47,8 @@ option version = "2.0.0"; @param host_ip4_gw - host IPv4 default gateway @param host_ip6_gw_set - host IPv6 default gateway should be set @param host_ip6_gw - host IPv6 default gateway + @param host_mtu_set - host MTU should be set + @param host_mtu_size - host MTU size @param tap_flags - flags for the TAP interface creation */ define tap_create_v2 @@ -76,6 +78,8 @@ define tap_create_v2 u8 host_ip4_gw[4]; u8 host_ip6_gw_set; u8 host_ip6_gw[16]; + u8 host_mtu_set; + u32 host_mtu_size; u8 tag[64]; u32 tap_flags; }; @@ -125,6 +129,7 @@ define sw_interface_tap_v2_dump @param host_ip4_prefix_len - host IPv4 ip address prefix length; 0 if unset @param host_ip6_addr - host IPv6 ip address @param host_ip6_prefix_len - host IPv6 ip address prefix length; 0 if unset + @param host_mtu_size - host mtu size */ define sw_interface_tap_v2_details { @@ -142,6 +147,7 @@ define sw_interface_tap_v2_details u8 host_ip4_prefix_len; u8 host_ip6_addr[16]; u8 host_ip6_prefix_len; + u32 host_mtu_size; u32 tap_flags; }; diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c index 40ff22eaeaa..2471d0084e1 100644 --- a/src/vnet/devices/tap/tapv2_api.c +++ b/src/vnet/devices/tap/tapv2_api.c @@ -109,6 +109,12 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp) ap->host_ip6_gw_set = 1; } + if (mp->host_mtu_set) + { + ap->host_mtu_size = ntohl (mp->host_mtu_size); + ap->host_mtu_set = 1; + } + ap->tap_flags = ntohl (mp->tap_flags); tap_create_if (vm, ap); @@ -190,6 +196,7 @@ tap_send_sw_interface_details (vpe_api_main_t * am, clib_memcpy (mp->host_bridge, tap_if->host_bridge, MIN (ARRAY_LEN (mp->host_bridge) - 1, strlen ((const char *) tap_if->host_bridge))); + mp->host_mtu_size = htonl (tap_if->host_mtu_size); if (tap_if->host_ip4_prefix_len) clib_memcpy (&mp->host_ip4_addr, &tap_if->host_ip4_addr, 4); mp->host_ip4_prefix_len = tap_if->host_ip4_prefix_len; diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index a3fd05dbb55..9e2067bd521 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -317,6 +317,9 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) vlib_cli_output (vm, " name \"%s\"", vif->host_if_name); if (vif->net_ns) vlib_cli_output (vm, " host-ns \"%s\"", vif->net_ns); + if (vif->host_mtu_size) + vlib_cli_output (vm, " host-mtu-size \"%d\"", + vif->host_mtu_size); vlib_cli_output (vm, " fd %d", vif->fd); vlib_cli_output (vm, " tap-fd %d", vif->tap_fd); vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled); diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h index 55b6271b337..52b57e9d95f 100644 --- a/src/vnet/devices/virtio/virtio.h +++ b/src/vnet/devices/virtio/virtio.h @@ -178,6 +178,7 @@ typedef struct u8 host_ip4_prefix_len; ip6_address_t host_ip6_addr; u8 host_ip6_prefix_len; + u32 host_mtu_size; u32 tap_file_index; int gso_enabled; int ifindex; -- cgit 1.2.3-korg