@@ -20,7 +20,7 @@ use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
2020use crate :: devices:: virtio:: gen:: virtio_net:: {
2121 virtio_net_hdr_v1, VIRTIO_NET_F_CSUM , VIRTIO_NET_F_GUEST_CSUM , VIRTIO_NET_F_GUEST_TSO4 ,
2222 VIRTIO_NET_F_GUEST_TSO6 , VIRTIO_NET_F_GUEST_UFO , VIRTIO_NET_F_HOST_TSO4 ,
23- VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC ,
23+ VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC , VIRTIO_NET_F_MRG_RXBUF ,
2424} ;
2525use crate :: devices:: virtio:: gen:: virtio_ring:: VIRTIO_RING_F_EVENT_IDX ;
2626use crate :: devices:: virtio:: iovec:: IoVecBuffer ;
@@ -150,6 +150,7 @@ impl Net {
150150 | 1 << VIRTIO_NET_F_HOST_TSO6
151151 | 1 << VIRTIO_NET_F_HOST_UFO
152152 | 1 << VIRTIO_F_VERSION_1
153+ | 1 << VIRTIO_NET_F_MRG_RXBUF
153154 | 1 << VIRTIO_RING_F_EVENT_IDX ;
154155
155156 let mut config_space = ConfigSpace :: default ( ) ;
@@ -646,7 +647,11 @@ impl Net {
646647 }
647648
648649 fn read_tap ( & mut self ) -> std:: io:: Result < usize > {
649- self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
650+ if self . has_feature ( u64:: from ( VIRTIO_NET_F_MRG_RXBUF ) ) {
651+ self . tap . read_iovec ( self . rx_buffer . all_chains_mut_slice ( ) )
652+ } else {
653+ self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
654+ }
650655 }
651656
652657 /// Process a single RX queue event.
@@ -858,7 +863,7 @@ pub mod tests {
858863 use crate :: devices:: virtio:: net:: device:: {
859864 frame_bytes_from_buf, frame_bytes_from_buf_mut, frame_hdr_len, init_vnet_hdr, vnet_hdr_len,
860865 } ;
861- use crate :: devices:: virtio:: net:: rx_buffer:: ChainInfo ;
866+ use crate :: devices:: virtio:: net:: rx_buffer:: { header_set_num_buffers , ChainInfo } ;
862867 use crate :: devices:: virtio:: net:: test_utils:: test:: TestHelper ;
863868 use crate :: devices:: virtio:: net:: test_utils:: {
864869 default_net, if_index, inject_tap_tx_frame, set_mac, NetEvent , NetQueue ,
@@ -925,6 +930,7 @@ pub mod tests {
925930 | 1 << VIRTIO_NET_F_HOST_TSO6
926931 | 1 << VIRTIO_NET_F_HOST_UFO
927932 | 1 << VIRTIO_F_VERSION_1
933+ | 1 << VIRTIO_NET_F_MRG_RXBUF
928934 | 1 << VIRTIO_RING_F_EVENT_IDX ;
929935
930936 assert_eq ! (
@@ -1046,10 +1052,9 @@ pub mod tests {
10461052 assert_eq ! ( th. rxq. used. idx. get( ) , 0 ) ;
10471053 }
10481054
1049- #[ test]
1050- fn test_rx_read_only_descriptor ( ) {
1051- let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1052- let mut th = TestHelper :: get_default ( & mem) ;
1055+ fn rx_read_only_descriptor ( mut th : TestHelper ) {
1056+ // let mem = single_region_mem(2 * MAX_BUFFER_SIZE);
1057+ // let mut th = TestHelper::get_default(&mem);
10531058 th. activate_net ( ) ;
10541059
10551060 th. add_desc_chain (
@@ -1068,9 +1073,22 @@ pub mod tests {
10681073 }
10691074
10701075 #[ test]
1071- fn test_rx_partial_write ( ) {
1076+ fn test_rx_read_only_descriptor ( ) {
1077+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1078+ let th = TestHelper :: get_default ( & mem) ;
1079+ rx_read_only_descriptor ( th) ;
1080+ }
1081+
1082+ #[ test]
1083+ fn test_rx_read_only_descriptor_mrg_buf ( ) {
10721084 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
10731085 let mut th = TestHelper :: get_default ( & mem) ;
1086+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1087+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1088+ rx_read_only_descriptor ( th) ;
1089+ }
1090+
1091+ fn rx_partial_write ( mut th : TestHelper ) {
10741092 th. activate_net ( ) ;
10751093
10761094 // The descriptor chain is created so that the last descriptor doesn't fit in the
@@ -1092,9 +1110,22 @@ pub mod tests {
10921110 }
10931111
10941112 #[ test]
1095- fn test_rx_retry ( ) {
1113+ fn test_rx_partial_write ( ) {
1114+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1115+ let th = TestHelper :: get_default ( & mem) ;
1116+ rx_partial_write ( th) ;
1117+ }
1118+
1119+ #[ test]
1120+ fn test_rx_partial_write_mrg_buf ( ) {
10961121 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
10971122 let mut th = TestHelper :: get_default ( & mem) ;
1123+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1124+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1125+ rx_partial_write ( th) ;
1126+ }
1127+
1128+ fn rx_retry ( mut th : TestHelper ) {
10981129 th. activate_net ( ) ;
10991130
11001131 // Even though too short descriptor chains are also
@@ -1144,9 +1175,22 @@ pub mod tests {
11441175 }
11451176
11461177 #[ test]
1147- fn test_rx_complex_desc_chain ( ) {
1178+ fn test_rx_retry ( ) {
1179+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1180+ let th = TestHelper :: get_default ( & mem) ;
1181+ rx_retry ( th) ;
1182+ }
1183+
1184+ #[ test]
1185+ fn test_rx_retry_mrg_buf ( ) {
11481186 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11491187 let mut th = TestHelper :: get_default ( & mem) ;
1188+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1189+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1190+ rx_retry ( th) ;
1191+ }
1192+
1193+ fn rx_complex_desc_chain ( mut th : TestHelper ) {
11501194 th. activate_net ( ) ;
11511195
11521196 // Create a valid Rx avail descriptor chain with multiple descriptors.
@@ -1183,9 +1227,22 @@ pub mod tests {
11831227 }
11841228
11851229 #[ test]
1186- fn test_rx_multiple_frames ( ) {
1230+ fn test_rx_complex_desc_chain ( ) {
1231+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1232+ let th = TestHelper :: get_default ( & mem) ;
1233+ rx_complex_desc_chain ( th) ;
1234+ }
1235+
1236+ #[ test]
1237+ fn test_rx_complex_desc_chain_mrg_buf ( ) {
11871238 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11881239 let mut th = TestHelper :: get_default ( & mem) ;
1240+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1241+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1242+ rx_complex_desc_chain ( th) ;
1243+ }
1244+
1245+ fn rx_multiple_frames ( mut th : TestHelper ) {
11891246 th. activate_net ( ) ;
11901247
11911248 // Create 2 valid Rx avail descriptor chains. Each one has enough space to fit the
@@ -1226,6 +1283,70 @@ pub mod tests {
12261283 th. rxq . dtable [ 3 ] . check_data ( & [ 0 ; 500 ] ) ;
12271284 }
12281285
1286+ #[ test]
1287+ fn test_rx_multiple_frames ( ) {
1288+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1289+ let th = TestHelper :: get_default ( & mem) ;
1290+ rx_multiple_frames ( th) ;
1291+ }
1292+
1293+ #[ test]
1294+ fn test_rx_multiple_frames_mrg_buf ( ) {
1295+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1296+ let mut th = TestHelper :: get_default ( & mem) ;
1297+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1298+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1299+ rx_multiple_frames ( th) ;
1300+ }
1301+
1302+ #[ test]
1303+ fn test_rx_multiple_frames_mrg ( ) {
1304+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1305+ let mut th = TestHelper :: get_default ( & mem) ;
1306+
1307+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1308+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1309+
1310+ th. activate_net ( ) ;
1311+
1312+ // Create 2 valid avail descriptor chains. We will send
1313+ // one packet that shuld be split amound these 2 chains.
1314+ th. add_desc_chain (
1315+ NetQueue :: Rx ,
1316+ 0 ,
1317+ & [ ( 0 , 100 , VIRTQ_DESC_F_WRITE ) , ( 1 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1318+ ) ;
1319+ th. add_desc_chain (
1320+ NetQueue :: Rx ,
1321+ 1000 ,
1322+ & [ ( 2 , 100 , VIRTQ_DESC_F_WRITE ) , ( 3 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1323+ ) ;
1324+ // Inject frame into tap and run epoll.
1325+ let mut frame = inject_tap_tx_frame ( & th. net ( ) , 400 ) ;
1326+ // SAFETY: frame is big enough and has correct alingment.
1327+ unsafe {
1328+ header_set_num_buffers ( frame. as_mut_ptr ( ) . cast ( ) , 2 ) ;
1329+ }
1330+ check_metric_after_block ! (
1331+ th. net( ) . metrics. rx_packets_count,
1332+ 1 ,
1333+ th. event_manager. run_with_timeout( 100 ) . unwrap( )
1334+ ) ;
1335+
1336+ // Check that the frame wasn't deferred.
1337+ assert ! ( th. net( ) . deferred_rx_bytes. is_none( ) ) ;
1338+ // Check that the used queue has advanced.
1339+ assert_eq ! ( th. rxq. used. idx. get( ) , 2 ) ;
1340+ assert ! ( & th. net( ) . irq_trigger. has_pending_irq( IrqType :: Vring ) ) ;
1341+ // Check that the frame was written successfully into both descriptor chains.
1342+ th. rxq . check_used_elem ( 0 , 0 , 200 ) ;
1343+ th. rxq . check_used_elem ( 1 , 2 , 200 ) ;
1344+ th. rxq . dtable [ 0 ] . check_data ( & frame[ 0 ..100 ] ) ;
1345+ th. rxq . dtable [ 1 ] . check_data ( & frame[ 100 ..200 ] ) ;
1346+ th. rxq . dtable [ 2 ] . check_data ( & frame[ 200 ..300 ] ) ;
1347+ th. rxq . dtable [ 3 ] . check_data ( & frame[ 300 ..400 ] ) ;
1348+ }
1349+
12291350 #[ test]
12301351 fn test_tx_missing_queue_signal ( ) {
12311352 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
@@ -1520,6 +1641,7 @@ pub mod tests {
15201641 net. rx_buffer . chain_infos . push_back ( ChainInfo {
15211642 head_index : 0 ,
15221643 chain_len : 1 ,
1644+ chain_capacity : 128 ,
15231645 } ) ;
15241646
15251647 let src_mac = MacAddr :: from_str ( "11:11:11:11:11:11" ) . unwrap ( ) ;
0 commit comments