diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index b95fd77a4..631826a7d 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -6,8 +6,8 @@ // found in the THIRD-PARTY file. use super::net_util::{ - build_net_config_space, build_net_config_space_with_mq, CtrlVirtio, NetCtrlEpollHandler, - VirtioNetConfig, + build_net_config_space, build_net_config_space_with_mq, virtio_features_to_tap_offload, + CtrlVirtio, NetCtrlEpollHandler, VirtioNetConfig, }; use super::Error as DeviceError; use super::{ @@ -586,10 +586,17 @@ impl VirtioDevice for Net { .transpose() .map_err(ActivateError::CreateRateLimiter)?; + let tap = taps.remove(0); + tap.set_offload(virtio_features_to_tap_offload(self.common.acked_features)) + .map_err(|e| { + error!("Error programming tap offload: {:?}", e); + ActivateError::BadActivate + })?; + let mut handler = NetEpollHandler { net: NetQueuePair { mem: Some(mem.clone()), - tap: taps.remove(0), + tap, rx, tx, epoll_fd: None, diff --git a/virtio-devices/src/net_util.rs b/virtio-devices/src/net_util.rs index 2ae263737..47716610d 100644 --- a/virtio-devices/src/net_util.rs +++ b/virtio-devices/src/net_util.rs @@ -7,6 +7,7 @@ use super::{ EPOLL_HELPER_EVENT_LAST, }; use net_util::MacAddr; +use std::os::raw::c_uint; use std::os::unix::io::{AsRawFd, RawFd}; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier}; @@ -208,3 +209,24 @@ pub fn build_net_config_space_with_mq( *avail_features |= 1 << VIRTIO_NET_F_MQ; } } + +pub fn virtio_features_to_tap_offload(features: u64) -> c_uint { + let mut tap_offloads: c_uint = 0; + if features & (1 << VIRTIO_NET_F_GUEST_CSUM) != 0 { + tap_offloads |= net_gen::TUN_F_CSUM; + } + if features & (1 << VIRTIO_NET_F_GUEST_TSO4) != 0 { + tap_offloads |= net_gen::TUN_F_TSO4; + } + if features & (1 << VIRTIO_NET_F_GUEST_TSO6) != 0 { + tap_offloads |= net_gen::TUN_F_TSO6; + } + if features & (1 << VIRTIO_NET_F_GUEST_ECN) != 0 { + tap_offloads |= net_gen::TUN_F_TSO_ECN; + } + if features & (1 << VIRTIO_NET_F_GUEST_UFO) != 0 { + tap_offloads |= net_gen::TUN_F_UFO; + } + + tap_offloads +}