@@ -23,8 +23,9 @@ use vm_memory::GuestMemoryError;
23
23
use crate :: devices:: virtio:: device:: { DeviceState , IrqTrigger , IrqType , VirtioDevice } ;
24
24
use crate :: devices:: virtio:: gen:: virtio_blk:: VIRTIO_F_VERSION_1 ;
25
25
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 ,
28
29
VIRTIO_NET_F_MAC ,
29
30
} ;
30
31
use crate :: devices:: virtio:: gen:: virtio_ring:: VIRTIO_RING_F_EVENT_IDX ;
@@ -162,7 +163,10 @@ impl Net {
162
163
| 1 << VIRTIO_NET_F_HOST_UFO
163
164
| 1 << VIRTIO_F_VERSION_1
164
165
| 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 ;
166
170
167
171
let mut config_space = ConfigSpace :: default ( ) ;
168
172
if let Some ( mac) = guest_mac {
@@ -642,16 +646,42 @@ impl Net {
642
646
}
643
647
}
644
648
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
+ } ;
647
656
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
+ ) ;
653
683
654
- return answer ;
684
+ tap_features
655
685
}
656
686
657
687
/// Updates the parameters for the rate limiters
@@ -869,18 +899,10 @@ impl VirtioDevice for Net {
869
899
}
870
900
}
871
901
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 ) ?;
884
906
885
907
if self . activate_evt . write ( 1 ) . is_err ( ) {
886
908
error ! ( "Net: Cannot write to activate_evt" ) ;
@@ -1002,7 +1024,10 @@ pub mod tests {
1002
1024
| 1 << VIRTIO_NET_F_HOST_UFO
1003
1025
| 1 << VIRTIO_F_VERSION_1
1004
1026
| 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 ;
1006
1031
1007
1032
assert_eq ! (
1008
1033
net. avail_features_by_page( 0 ) ,
@@ -1024,68 +1049,31 @@ pub mod tests {
1024
1049
// We can't get offload features, that were set up to a TAP device by ioctl,
1025
1050
// hence that we have to validate, that we sort out unsupported features correctly
1026
1051
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 ;
1056
1056
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 ;
1059
1059
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) ;
1062
1061
1063
- assert_eq ! ( supported_flags, tap_features ) ;
1062
+ assert_eq ! ( supported_flags, expected_tap_features ) ;
1064
1063
}
1065
1064
1066
1065
#[ 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 ) ,
1072
1072
] ;
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) ;
1080
1076
}
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) ;
1089
1077
}
1090
1078
1091
1079
#[ test]
0 commit comments