@@ -19,7 +19,7 @@ use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
1919use crate :: devices:: virtio:: gen:: virtio_net:: {
2020 virtio_net_hdr_v1, VIRTIO_NET_F_CSUM , VIRTIO_NET_F_GUEST_CSUM , VIRTIO_NET_F_GUEST_TSO4 ,
2121 VIRTIO_NET_F_GUEST_TSO6 , VIRTIO_NET_F_GUEST_UFO , VIRTIO_NET_F_HOST_TSO4 ,
22- VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC ,
22+ VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC , VIRTIO_NET_F_MRG_RXBUF ,
2323} ;
2424use crate :: devices:: virtio:: gen:: virtio_ring:: VIRTIO_RING_F_EVENT_IDX ;
2525use crate :: devices:: virtio:: iovec:: IoVecBuffer ;
@@ -149,6 +149,7 @@ impl Net {
149149 | 1 << VIRTIO_NET_F_HOST_TSO6
150150 | 1 << VIRTIO_NET_F_HOST_UFO
151151 | 1 << VIRTIO_F_VERSION_1
152+ | 1 << VIRTIO_NET_F_MRG_RXBUF
152153 | 1 << VIRTIO_RING_F_EVENT_IDX ;
153154
154155 let mut config_space = ConfigSpace :: default ( ) ;
@@ -659,7 +660,11 @@ impl Net {
659660 }
660661
661662 fn read_tap ( & mut self ) -> std:: io:: Result < usize > {
662- self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
663+ if self . has_feature ( u64:: from ( VIRTIO_NET_F_MRG_RXBUF ) ) {
664+ self . tap . read_iovec ( self . rx_buffer . all_chains_mut_slice ( ) )
665+ } else {
666+ self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
667+ }
663668 }
664669
665670 /// Process a single RX queue event.
@@ -891,8 +896,8 @@ pub mod tests {
891896 use crate :: devices:: virtio:: net:: rx_buffer:: ChainInfo ;
892897 use crate :: devices:: virtio:: net:: test_utils:: test:: TestHelper ;
893898 use crate :: devices:: virtio:: net:: test_utils:: {
894- default_net, if_index, inject_tap_tx_frame, set_mac , NetEvent , NetQueue ,
895- TapTrafficSimulator ,
899+ default_net, if_index, inject_tap_tx_frame, mock_frame_set_num_buffers , set_mac , NetEvent ,
900+ NetQueue , TapTrafficSimulator ,
896901 } ;
897902 use crate :: devices:: virtio:: net:: NET_QUEUE_SIZES ;
898903 use crate :: devices:: virtio:: queue:: VIRTQ_DESC_F_WRITE ;
@@ -1077,10 +1082,9 @@ pub mod tests {
10771082 assert_eq ! ( th. rxq. used. idx. get( ) , 0 ) ;
10781083 }
10791084
1080- #[ test]
1081- fn test_rx_read_only_descriptor ( ) {
1082- let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1083- let mut th = TestHelper :: get_default ( & mem) ;
1085+ fn rx_read_only_descriptor ( mut th : TestHelper ) {
1086+ // let mem = single_region_mem(2 * MAX_BUFFER_SIZE);
1087+ // let mut th = TestHelper::get_default(&mem);
10841088 th. activate_net ( ) ;
10851089
10861090 th. add_desc_chain (
@@ -1099,9 +1103,22 @@ pub mod tests {
10991103 }
11001104
11011105 #[ test]
1102- fn test_rx_partial_write ( ) {
1106+ fn test_rx_read_only_descriptor ( ) {
1107+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1108+ let th = TestHelper :: get_default ( & mem) ;
1109+ rx_read_only_descriptor ( th) ;
1110+ }
1111+
1112+ #[ test]
1113+ fn test_rx_read_only_descriptor_mrg_buf ( ) {
11031114 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11041115 let mut th = TestHelper :: get_default ( & mem) ;
1116+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1117+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1118+ rx_read_only_descriptor ( th) ;
1119+ }
1120+
1121+ fn rx_partial_write ( mut th : TestHelper ) {
11051122 th. activate_net ( ) ;
11061123
11071124 // The descriptor chain is created so that the last descriptor doesn't fit in the
@@ -1123,9 +1140,22 @@ pub mod tests {
11231140 }
11241141
11251142 #[ test]
1126- fn test_rx_retry ( ) {
1143+ fn test_rx_partial_write ( ) {
1144+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1145+ let th = TestHelper :: get_default ( & mem) ;
1146+ rx_partial_write ( th) ;
1147+ }
1148+
1149+ #[ test]
1150+ fn test_rx_partial_write_mrg_buf ( ) {
11271151 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11281152 let mut th = TestHelper :: get_default ( & mem) ;
1153+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1154+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1155+ rx_partial_write ( th) ;
1156+ }
1157+
1158+ fn rx_retry ( mut th : TestHelper ) {
11291159 th. activate_net ( ) ;
11301160
11311161 // Even though too short descriptor chains are also
@@ -1175,9 +1205,22 @@ pub mod tests {
11751205 }
11761206
11771207 #[ test]
1178- fn test_rx_complex_desc_chain ( ) {
1208+ fn test_rx_retry ( ) {
1209+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1210+ let th = TestHelper :: get_default ( & mem) ;
1211+ rx_retry ( th) ;
1212+ }
1213+
1214+ #[ test]
1215+ fn test_rx_retry_mrg_buf ( ) {
11791216 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11801217 let mut th = TestHelper :: get_default ( & mem) ;
1218+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1219+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1220+ rx_retry ( th) ;
1221+ }
1222+
1223+ fn rx_complex_desc_chain ( mut th : TestHelper ) {
11811224 th. activate_net ( ) ;
11821225
11831226 // Create a valid Rx avail descriptor chain with multiple descriptors.
@@ -1214,9 +1257,22 @@ pub mod tests {
12141257 }
12151258
12161259 #[ test]
1217- fn test_rx_multiple_frames ( ) {
1260+ fn test_rx_complex_desc_chain ( ) {
1261+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1262+ let th = TestHelper :: get_default ( & mem) ;
1263+ rx_complex_desc_chain ( th) ;
1264+ }
1265+
1266+ #[ test]
1267+ fn test_rx_complex_desc_chain_mrg_buf ( ) {
12181268 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
12191269 let mut th = TestHelper :: get_default ( & mem) ;
1270+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1271+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1272+ rx_complex_desc_chain ( th) ;
1273+ }
1274+
1275+ fn rx_multiple_frames ( mut th : TestHelper ) {
12201276 th. activate_net ( ) ;
12211277
12221278 // Create 2 valid Rx avail descriptor chains. Each one has enough space to fit the
@@ -1257,6 +1313,67 @@ pub mod tests {
12571313 th. rxq . dtable [ 3 ] . check_data ( & [ 0 ; 500 ] ) ;
12581314 }
12591315
1316+ #[ test]
1317+ fn test_rx_multiple_frames ( ) {
1318+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1319+ let th = TestHelper :: get_default ( & mem) ;
1320+ rx_multiple_frames ( th) ;
1321+ }
1322+
1323+ #[ test]
1324+ fn test_rx_multiple_frames_mrg_buf ( ) {
1325+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1326+ let mut th = TestHelper :: get_default ( & mem) ;
1327+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1328+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1329+ rx_multiple_frames ( th) ;
1330+ }
1331+
1332+ #[ test]
1333+ fn test_rx_multiple_frames_mrg ( ) {
1334+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1335+ let mut th = TestHelper :: get_default ( & mem) ;
1336+
1337+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1338+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1339+
1340+ th. activate_net ( ) ;
1341+
1342+ // Create 2 valid avail descriptor chains. We will send
1343+ // one packet that shuld be split amound these 2 chains.
1344+ th. add_desc_chain (
1345+ NetQueue :: Rx ,
1346+ 0 ,
1347+ & [ ( 0 , 100 , VIRTQ_DESC_F_WRITE ) , ( 1 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1348+ ) ;
1349+ th. add_desc_chain (
1350+ NetQueue :: Rx ,
1351+ 1000 ,
1352+ & [ ( 2 , 100 , VIRTQ_DESC_F_WRITE ) , ( 3 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1353+ ) ;
1354+ // Inject frame into tap and run epoll.
1355+ let mut frame = inject_tap_tx_frame ( & th. net ( ) , 400 ) ;
1356+ mock_frame_set_num_buffers ( & mut frame, 2 ) ;
1357+ check_metric_after_block ! (
1358+ th. net( ) . metrics. rx_packets_count,
1359+ 1 ,
1360+ th. event_manager. run_with_timeout( 100 ) . unwrap( )
1361+ ) ;
1362+
1363+ // Check that the frame wasn't deferred.
1364+ assert ! ( !th. net( ) . rx_deferred_frame) ;
1365+ // Check that the used queue has advanced.
1366+ assert_eq ! ( th. rxq. used. idx. get( ) , 2 ) ;
1367+ assert ! ( & th. net( ) . irq_trigger. has_pending_irq( IrqType :: Vring ) ) ;
1368+ // Check that the frame was written successfully into both descriptor chains.
1369+ th. rxq . check_used_elem ( 0 , 0 , 200 ) ;
1370+ th. rxq . check_used_elem ( 1 , 2 , 200 ) ;
1371+ th. rxq . dtable [ 0 ] . check_data ( & frame[ 0 ..100 ] ) ;
1372+ th. rxq . dtable [ 1 ] . check_data ( & frame[ 100 ..200 ] ) ;
1373+ th. rxq . dtable [ 2 ] . check_data ( & frame[ 200 ..300 ] ) ;
1374+ th. rxq . dtable [ 3 ] . check_data ( & frame[ 300 ..400 ] ) ;
1375+ }
1376+
12601377 #[ test]
12611378 fn test_tx_missing_queue_signal ( ) {
12621379 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
0 commit comments