From 97d54ed43eb69f6ea731c02305ebe0ca0b1a5cc4 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Mon, 10 Jun 2019 11:20:15 +0200 Subject: [PATCH] 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 --- MAINTAINERS | 9 ++++++++ src/vat/api_format.c | 20 ++++++++++++++++- 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 + src/vpp/api/custom_dump.c | 4 ++++ 11 files changed, 110 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index cd8bf49afbc..eeaca9b03f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -78,6 +78,15 @@ I: devices M: Damjan Marion F: src/vnet/devices/ +VNET TAP Drivers +I: tap +M: Damjan Marion +M: Steven Luong +M: Mohsin Kazmi +F: src/vnet/devices/tap/ +F: src/vnet/devices/virtio/node.c +F: src/vnet/devices/virtio/device.c + VNET Feature Arcs I: feature M: Dave Barach diff --git a/src/vat/api_format.c b/src/vat/api_format.c index d9a9d223804..f107246774c 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -7429,6 +7429,7 @@ api_tap_create_v2 (vat_main_t * vam) { unformat_input_t *i = vam->input; vl_api_tap_create_v2_t *mp; +#define TAP_FLAG_GSO (1 << 0) u8 mac_address[6]; u8 random_mac = 1; u32 id = ~0; @@ -7445,6 +7446,9 @@ api_tap_create_v2 (vat_main_t * vam) ip6_address_t host_ip6_gw; u8 host_ip6_gw_set = 0; u32 host_ip6_prefix_len = 0; + u8 host_mtu_set = 0; + u32 host_mtu_size = 0; + u32 tap_flags = 0; int ret; u32 rx_ring_sz = 0, tx_ring_sz = 0; @@ -7484,6 +7488,12 @@ api_tap_create_v2 (vat_main_t * vam) ; else if (unformat (i, "tx-ring-size %d", &tx_ring_sz)) ; + else if (unformat (i, "host-mtu-size %d", &host_mtu_size)) + host_mtu_set = 1; + else if (unformat (i, "no-gso")) + tap_flags &= ~TAP_FLAG_GSO; + else if (unformat (i, "gso")) + tap_flags |= TAP_FLAG_GSO; else break; } @@ -7533,6 +7543,11 @@ api_tap_create_v2 (vat_main_t * vam) errmsg ("tx ring size must be 32768 or lower. "); return -99; } + if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355)) + { + errmsg ("host MTU size must be in between 64 and 65355. "); + return -99; + } /* Construct the API message */ M (TAP_CREATE_V2, mp); @@ -7546,6 +7561,9 @@ api_tap_create_v2 (vat_main_t * vam) mp->host_ip6_addr_set = host_ip6_prefix_len != 0; mp->rx_ring_sz = ntohs (rx_ring_sz); mp->tx_ring_sz = ntohs (tx_ring_sz); + mp->host_mtu_set = host_mtu_set; + mp->host_mtu_size = ntohl (host_mtu_size); + mp->tap_flags = ntohl (tap_flags); if (random_mac == 0) clib_memcpy (mp->mac_address, mac_address, 6); @@ -21843,7 +21861,7 @@ _(l2_flags, \ _(bridge_flags, \ "bd_id [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \ _(tap_create_v2, \ - "id [hw-addr ] [host-ns ] [rx-ring-size [tx-ring-size ]") \ + "id [hw-addr ] [host-ns ] [rx-ring-size [tx-ring-size ] [host-mtu-size ] [gso | no-gso]") \ _(tap_delete_v2, \ " | sw_if_index ") \ _(sw_interface_tap_v2_dump, "") \ 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; diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index 94a868e0353..524ad368c89 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -579,6 +579,10 @@ static void *vl_api_tap_create_v2_t_print s = format (s, "tx-ring-size %u ", ntohs (mp->tx_ring_sz)); if (mp->rx_ring_sz) s = format (s, "rx-ring-size %u ", ntohs (mp->rx_ring_sz)); + if (mp->host_mtu_set) + s = format (s, "host-mtu-size %u ", ntohl (mp->host_mtu_size)); + if (ntohl (mp->tap_flags) & 0x1) + s = format (s, "gso-enabled"); FINISH; } -- 2.16.6