virtio-devices: net: Set tap offload features based on those negotiated

Configure the tap offload features to match those that the guest has
acknowledged. The function for converting virtio to tap features came
from crosvm:
4786cee521/devices/src/virtio/net.rs (115)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-04-26 16:19:53 +01:00 committed by Sebastien Boeuf
parent f8803e4639
commit f213083386
2 changed files with 32 additions and 3 deletions

View File

@ -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,

View File

@ -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
}