@@ -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 ;
@@ -955,6 +960,7 @@ pub mod tests {
955960 | 1 << VIRTIO_NET_F_HOST_TSO6
956961 | 1 << VIRTIO_NET_F_HOST_UFO
957962 | 1 << VIRTIO_F_VERSION_1
963+ | 1 << VIRTIO_NET_F_MRG_RXBUF
958964 | 1 << VIRTIO_RING_F_EVENT_IDX ;
959965
960966 assert_eq ! (
@@ -1076,10 +1082,9 @@ pub mod tests {
10761082 assert_eq ! ( th. rxq. used. idx. get( ) , 0 ) ;
10771083 }
10781084
1079- #[ test]
1080- fn test_rx_read_only_descriptor ( ) {
1081- let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1082- 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);
10831088 th. activate_net ( ) ;
10841089
10851090 th. add_desc_chain (
@@ -1098,9 +1103,22 @@ pub mod tests {
10981103 }
10991104
11001105 #[ test]
1101- 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 ( ) {
11021114 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11031115 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 ) {
11041122 th. activate_net ( ) ;
11051123
11061124 // The descriptor chain is created so that the last descriptor doesn't fit in the
@@ -1122,9 +1140,22 @@ pub mod tests {
11221140 }
11231141
11241142 #[ test]
1125- 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 ( ) {
11261151 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11271152 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 ) {
11281159 th. activate_net ( ) ;
11291160
11301161 // Even though too short descriptor chains are also
@@ -1174,9 +1205,22 @@ pub mod tests {
11741205 }
11751206
11761207 #[ test]
1177- 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 ( ) {
11781216 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
11791217 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 ) {
11801224 th. activate_net ( ) ;
11811225
11821226 // Create a valid Rx avail descriptor chain with multiple descriptors.
@@ -1213,9 +1257,22 @@ pub mod tests {
12131257 }
12141258
12151259 #[ test]
1216- 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 ( ) {
12171268 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
12181269 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 ) {
12191276 th. activate_net ( ) ;
12201277
12211278 // Create 2 valid Rx avail descriptor chains. Each one has enough space to fit the
@@ -1256,6 +1313,67 @@ pub mod tests {
12561313 th. rxq . dtable [ 3 ] . check_data ( & [ 0 ; 500 ] ) ;
12571314 }
12581315
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+
12591377 #[ test]
12601378 fn test_tx_missing_queue_signal ( ) {
12611379 let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
@@ -1550,6 +1668,7 @@ pub mod tests {
15501668 net. rx_buffer . chain_infos . push_back ( ChainInfo {
15511669 head_index : 0 ,
15521670 chain_len : 1 ,
1671+ chain_capacity : 128 ,
15531672 } ) ;
15541673
15551674 let src_mac = MacAddr :: from_str ( "11:11:11:11:11:11" ) . unwrap ( ) ;
0 commit comments