Skip to content

Commit 87f2438

Browse files
committed
refactored build_tap_supported_features + add new virtio flags to get acked
Signed-off-by: zakironi <[email protected]>
1 parent ecf18b3 commit 87f2438

File tree

2 files changed

+69
-79
lines changed

2 files changed

+69
-79
lines changed

src/vmm/src/devices/virtio/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use std::any::Any;
1111
use std::io::Error as IOError;
1212

13+
use crate::devices::virtio::net::TapError;
14+
1315
pub mod balloon;
1416
pub mod block_common;
1517
pub mod device;
@@ -69,7 +71,7 @@ pub enum ActivateError {
6971
/// Vhost user: {0}
7072
VhostUser(vhost_user::VhostUserError),
7173
/// Setting tap interface offload flags failed
72-
TapSetOffload,
74+
TapSetOffload(TapError),
7375
}
7476

7577
/// Trait that helps in upcasting an object to Any

src/vmm/src/devices/virtio/net/device.rs

+66-78
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ use vm_memory::GuestMemoryError;
2323
use crate::devices::virtio::device::{DeviceState, IrqTrigger, IrqType, VirtioDevice};
2424
use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
2525
use crate::devices::virtio::gen::virtio_net::{
26-
virtio_net_hdr_v1, VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_TSO4,
27-
VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO,
26+
virtio_net_hdr_v1, VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_ECN,
27+
VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO,
28+
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6, VIRTIO_NET_F_HOST_UFO,
2829
VIRTIO_NET_F_MAC,
2930
};
3031
use crate::devices::virtio::gen::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
@@ -162,7 +163,10 @@ impl Net {
162163
| 1 << VIRTIO_NET_F_HOST_UFO
163164
| 1 << VIRTIO_F_VERSION_1
164165
| 1 << VIRTIO_RING_F_EVENT_IDX
165-
| 1 << VIRTIO_NET_F_GUEST_TSO6;
166+
| 1 << VIRTIO_NET_F_GUEST_TSO6
167+
| 1 << VIRTIO_NET_F_HOST_TSO6
168+
| 1 << VIRTIO_NET_F_GUEST_ECN
169+
| 1 << VIRTIO_NET_F_HOST_ECN;
166170

167171
let mut config_space = ConfigSpace::default();
168172
if let Some(mac) = guest_mac {
@@ -642,16 +646,42 @@ impl Net {
642646
}
643647
}
644648

645-
fn build_tap_supported_features(desired_flags: &[(u32, u32)], supported_features: u64) -> u32 {
646-
let mut answer: u32 = 0;
649+
fn build_tap_supported_features(virtio_supported_features: u64) -> u32 {
650+
let add_if_supported =
651+
|tap_features: &mut u32, virtio_features: u64, tap_flag: u32, virtio_flag: u32| {
652+
if virtio_features & (1 << virtio_flag) != 0 {
653+
*tap_features |= tap_flag;
654+
}
655+
};
647656

648-
for (tap_flag, net_flag) in desired_flags.iter() {
649-
if (supported_features & 1 << net_flag) != 0 {
650-
answer |= tap_flag;
651-
}
652-
}
657+
let mut tap_features: u32 = 0;
658+
659+
add_if_supported(
660+
&mut tap_features,
661+
virtio_supported_features,
662+
gen::TUN_F_CSUM,
663+
VIRTIO_NET_F_CSUM,
664+
);
665+
add_if_supported(
666+
&mut tap_features,
667+
virtio_supported_features,
668+
gen::TUN_F_UFO,
669+
VIRTIO_NET_F_GUEST_UFO,
670+
);
671+
add_if_supported(
672+
&mut tap_features,
673+
virtio_supported_features,
674+
gen::TUN_F_TSO4,
675+
VIRTIO_NET_F_GUEST_TSO4,
676+
);
677+
add_if_supported(
678+
&mut tap_features,
679+
virtio_supported_features,
680+
gen::TUN_F_TSO6,
681+
VIRTIO_NET_F_GUEST_TSO6,
682+
);
653683

654-
return answer;
684+
tap_features
655685
}
656686

657687
/// Updates the parameters for the rate limiters
@@ -869,18 +899,10 @@ impl VirtioDevice for Net {
869899
}
870900
}
871901

872-
let desired_flags = [
873-
(gen::TUN_F_CSUM, VIRTIO_NET_F_CSUM),
874-
(gen::TUN_F_UFO, VIRTIO_NET_F_GUEST_UFO),
875-
(gen::TUN_F_TSO4, VIRTIO_NET_F_GUEST_TSO4),
876-
(gen::TUN_F_TSO6, VIRTIO_NET_F_GUEST_TSO6),
877-
];
878-
879-
let supported_flags =
880-
Net::build_tap_supported_features(&desired_flags, self.acked_features());
881-
if self.tap.set_offload(supported_flags).is_err() {
882-
return Err(super::super::ActivateError::TapSetOffload);
883-
}
902+
let supported_flags: u32 = Net::build_tap_supported_features(self.acked_features);
903+
self.tap
904+
.set_offload(supported_flags)
905+
.map_err(super::super::ActivateError::TapSetOffload)?;
884906

885907
if self.activate_evt.write(1).is_err() {
886908
error!("Net: Cannot write to activate_evt");
@@ -1002,7 +1024,10 @@ pub mod tests {
10021024
| 1 << VIRTIO_NET_F_HOST_UFO
10031025
| 1 << VIRTIO_F_VERSION_1
10041026
| 1 << VIRTIO_RING_F_EVENT_IDX
1005-
| 1 << VIRTIO_NET_F_GUEST_TSO6;
1027+
| 1 << VIRTIO_NET_F_GUEST_TSO6
1028+
| 1 << VIRTIO_NET_F_HOST_TSO6
1029+
| 1 << VIRTIO_NET_F_GUEST_ECN
1030+
| 1 << VIRTIO_NET_F_HOST_ECN;
10061031

10071032
assert_eq!(
10081033
net.avail_features_by_page(0),
@@ -1024,68 +1049,31 @@ pub mod tests {
10241049
// We can't get offload features, that were set up to a TAP device by ioctl,
10251050
// hence that we have to validate, that we sort out unsupported features correctly
10261051
fn test_build_tap_supported_features_all() {
1027-
let desired_features = [
1028-
(gen::TUN_F_CSUM, VIRTIO_NET_F_CSUM),
1029-
(gen::TUN_F_UFO, VIRTIO_NET_F_GUEST_UFO),
1030-
(gen::TUN_F_TSO4, VIRTIO_NET_F_GUEST_TSO4),
1031-
(gen::TUN_F_TSO6, VIRTIO_NET_F_GUEST_TSO6),
1032-
];
1033-
1034-
let mut tap_features: u32 = 0;
1035-
let mut ack_features: u32 = 0;
1036-
1037-
for i in 0..desired_features.len() {
1038-
tap_features |= desired_features[i].0;
1039-
ack_features |= 1 << desired_features[i].1;
1040-
}
1041-
1042-
let supported_flags =
1043-
Net::build_tap_supported_features(&desired_features, ack_features as u64);
1044-
1045-
assert_eq!(supported_flags, tap_features);
1046-
}
1047-
1048-
#[test]
1049-
fn test_build_tap_supported_features_ack_les_than_want() {
1050-
let desired_features = [
1051-
(gen::TUN_F_CSUM, VIRTIO_NET_F_CSUM),
1052-
(gen::TUN_F_UFO, VIRTIO_NET_F_GUEST_UFO),
1053-
(gen::TUN_F_TSO4, VIRTIO_NET_F_GUEST_TSO4),
1054-
(gen::TUN_F_TSO6, VIRTIO_NET_F_GUEST_TSO6),
1055-
];
1052+
let supported_features = 1 << VIRTIO_NET_F_CSUM
1053+
| 1 << VIRTIO_NET_F_GUEST_UFO
1054+
| 1 << VIRTIO_NET_F_GUEST_TSO4
1055+
| 1 << VIRTIO_NET_F_GUEST_TSO6;
10561056

1057-
let tap_features: u32 = gen::TUN_F_CSUM | gen::TUN_F_UFO;
1058-
let ack_features: u32 = 1 << VIRTIO_NET_F_CSUM | 1 << VIRTIO_NET_F_GUEST_UFO;
1057+
let expected_tap_features =
1058+
gen::TUN_F_CSUM | gen::TUN_F_UFO | gen::TUN_F_TSO4 | gen::TUN_F_TSO6;
10591059

1060-
let supported_flags =
1061-
Net::build_tap_supported_features(&desired_features, ack_features as u64);
1060+
let supported_flags = Net::build_tap_supported_features(supported_features);
10621061

1063-
assert_eq!(supported_flags, tap_features);
1062+
assert_eq!(supported_flags, expected_tap_features);
10641063
}
10651064

10661065
#[test]
1067-
fn test_build_tap_supported_features_ack_more_than_want() {
1068-
let desired_features = [
1069-
(gen::TUN_F_CSUM, VIRTIO_NET_F_CSUM),
1070-
(gen::TUN_F_UFO, VIRTIO_NET_F_GUEST_UFO),
1071-
(gen::TUN_F_TSO4, VIRTIO_NET_F_GUEST_TSO4),
1066+
fn test_build_tap_supported_features_one_by_one() {
1067+
let features = [
1068+
(1 << VIRTIO_NET_F_CSUM, gen::TUN_F_CSUM),
1069+
(1 << VIRTIO_NET_F_GUEST_UFO, gen::TUN_F_UFO),
1070+
(1 << VIRTIO_NET_F_GUEST_TSO4, gen::TUN_F_TSO4),
1071+
(1 << VIRTIO_NET_F_GUEST_TSO6, gen::TUN_F_TSO6),
10721072
];
1073-
1074-
let mut tap_features: u32 = 0;
1075-
let mut ack_features: u32 = 0;
1076-
1077-
for i in 0..desired_features.len() {
1078-
tap_features |= desired_features[i].0;
1079-
ack_features |= 1 << desired_features[i].1;
1073+
for (virtio_flag, tap_flag) in features {
1074+
let supported_flags = Net::build_tap_supported_features(virtio_flag);
1075+
assert_eq!(supported_flags, tap_flag);
10801076
}
1081-
1082-
// extra supported feature
1083-
ack_features |= 1 << VIRTIO_NET_F_GUEST_TSO6;
1084-
1085-
let supported_flags =
1086-
Net::build_tap_supported_features(&desired_features, ack_features as u64);
1087-
1088-
assert_eq!(supported_flags, tap_features);
10891077
}
10901078

10911079
#[test]

0 commit comments

Comments
 (0)