@@ -17,13 +17,14 @@ use dumbo::{EthernetFrame, MacAddr, MAC_ADDR_LEN};
1717use libc:: EAGAIN ;
1818use logger:: { Metric , METRICS } ;
1919use rate_limiter:: { BucketUpdate , RateLimiter , TokenType } ;
20- #[ cfg( not( test) ) ]
21- use std:: io:: Read ;
20+
2221use std:: io:: Write ;
22+ #[ cfg( not( test) ) ]
23+ use std:: io:: { self , Read } ;
2324use std:: sync:: atomic:: AtomicUsize ;
2425use std:: sync:: atomic:: Ordering ;
2526use std:: sync:: Arc ;
26- use std:: { cmp, io , mem, result} ;
27+ use std:: { cmp, mem, result} ;
2728use utils:: eventfd:: EventFd ;
2829use utils:: net:: Tap ;
2930use virtio_gen:: virtio_net:: {
@@ -39,12 +40,20 @@ fn vnet_hdr_len() -> usize {
3940
4041// Frames being sent/received through the network device model have a VNET header. This
4142// function returns a slice which holds the L2 frame bytes without this header.
42- fn frame_bytes_from_buf ( buf : & [ u8 ] ) -> & [ u8 ] {
43- & buf[ vnet_hdr_len ( ) ..]
43+ fn frame_bytes_from_buf ( buf : & [ u8 ] ) -> Result < & [ u8 ] > {
44+ if buf. len ( ) < vnet_hdr_len ( ) {
45+ Err ( Error :: VnetHeaderMissing )
46+ } else {
47+ Ok ( & buf[ vnet_hdr_len ( ) ..] )
48+ }
4449}
4550
46- fn frame_bytes_from_buf_mut ( buf : & mut [ u8 ] ) -> & mut [ u8 ] {
47- & mut buf[ vnet_hdr_len ( ) ..]
51+ fn frame_bytes_from_buf_mut ( buf : & mut [ u8 ] ) -> Result < & mut [ u8 ] > {
52+ if buf. len ( ) < vnet_hdr_len ( ) {
53+ Err ( Error :: VnetHeaderMissing )
54+ } else {
55+ Ok ( & mut buf[ vnet_hdr_len ( ) ..] )
56+ }
4857}
4958
5059// This initializes to all 0 the VNET hdr part of a buf.
@@ -332,34 +341,40 @@ impl Net {
332341 frame_buf : & [ u8 ] ,
333342 tap : & mut Tap ,
334343 guest_mac : Option < MacAddr > ,
335- ) -> bool {
344+ ) -> Result < bool > {
345+ let checked_frame = |frame_buf| {
346+ frame_bytes_from_buf ( frame_buf) . map_err ( |e| {
347+ error ! ( "VNET header missing in the TX frame." ) ;
348+ METRICS . net . tx_malformed_frames . inc ( ) ;
349+ e
350+ } )
351+ } ;
336352 if let Some ( ns) = mmds_ns {
337- if ns. detour_frame ( frame_bytes_from_buf ( frame_buf) ) {
353+ if ns. detour_frame ( checked_frame ( frame_buf) ? ) {
338354 METRICS . mmds . rx_accepted . inc ( ) ;
339355
340356 // MMDS frames are not accounted by the rate limiter.
341357 rate_limiter. manual_replenish ( frame_buf. len ( ) as u64 , TokenType :: Bytes ) ;
342358 rate_limiter. manual_replenish ( 1 , TokenType :: Ops ) ;
343359
344360 // MMDS consumed the frame.
345- return true ;
361+ return Ok ( true ) ;
346362 }
347363 }
348364
349365 // This frame goes to the TAP.
350366
351367 // Check for guest MAC spoofing.
352368 if let Some ( mac) = guest_mac {
353- let _ = EthernetFrame :: from_bytes ( & frame_buf [ vnet_hdr_len ( ) .. ] ) . and_then ( |eth_frame| {
369+ let _ = EthernetFrame :: from_bytes ( checked_frame ( frame_buf ) ? ) . and_then ( |eth_frame| {
354370 if mac != eth_frame. src_mac ( ) {
355371 METRICS . net . tx_spoofed_mac_count . inc ( ) ;
356372 }
357373 Ok ( ( ) )
358374 } ) ;
359375 }
360376
361- let write_result = tap. write ( frame_buf) ;
362- match write_result {
377+ match tap. write ( frame_buf) {
363378 Ok ( _) => {
364379 METRICS . net . tx_bytes_count . add ( frame_buf. len ( ) ) ;
365380 METRICS . net . tx_packets_count . inc ( ) ;
@@ -370,13 +385,14 @@ impl Net {
370385 METRICS . net . tx_fails . inc ( ) ;
371386 }
372387 } ;
373- false
388+ Ok ( false )
374389 }
375390
376391 // We currently prioritize packets from the MMDS over regular network packets.
377- fn read_from_mmds_or_tap ( & mut self ) -> io :: Result < usize > {
392+ fn read_from_mmds_or_tap ( & mut self ) -> Result < usize > {
378393 if let Some ( ns) = self . mmds_ns . as_mut ( ) {
379- if let Some ( len) = ns. write_next_frame ( frame_bytes_from_buf_mut ( & mut self . rx_frame_buf ) )
394+ if let Some ( len) =
395+ ns. write_next_frame ( frame_bytes_from_buf_mut ( & mut self . rx_frame_buf ) ?)
380396 {
381397 let len = len. get ( ) ;
382398 METRICS . mmds . tx_frames . inc ( ) ;
@@ -386,7 +402,7 @@ impl Net {
386402 }
387403 }
388404
389- self . read_tap ( )
405+ self . read_tap ( ) . map_err ( Error :: IO )
390406 }
391407
392408 fn process_rx ( & mut self ) -> result:: Result < ( ) , DeviceError > {
@@ -401,7 +417,7 @@ impl Net {
401417 break ;
402418 }
403419 }
404- Err ( e ) => {
420+ Err ( Error :: IO ( e ) ) => {
405421 // The tap device is non-blocking, so any error aside from EAGAIN is
406422 // unexpected.
407423 match e. raw_os_error ( ) {
@@ -414,6 +430,9 @@ impl Net {
414430 } ;
415431 break ;
416432 }
433+ Err ( e) => {
434+ error ! ( "Spurious error in network RX: {:?}" , e) ;
435+ }
417436 }
418437 }
419438
@@ -523,14 +542,15 @@ impl Net {
523542 }
524543 }
525544
526- if Self :: write_to_mmds_or_tap (
545+ let frame_consumed_by_mmds = Self :: write_to_mmds_or_tap (
527546 self . mmds_ns . as_mut ( ) ,
528547 & mut self . tx_rate_limiter ,
529548 & self . tx_frame_buf [ ..read_count] ,
530549 & mut self . tap ,
531550 self . guest_mac ,
532- ) && !self . rx_deferred_frame
533- {
551+ )
552+ . unwrap_or_else ( |_| false ) ;
553+ if frame_consumed_by_mmds && !self . rx_deferred_frame {
534554 // MMDS consumed this frame/request, let's also try to process the response.
535555 process_rx_for_mmds = true ;
536556 }
@@ -893,6 +913,16 @@ pub(crate) mod tests {
893913
894914 #[ test]
895915 fn test_vnet_helpers ( ) {
916+ let mut frame_buf = vec ! [ 42u8 ; vnet_hdr_len( ) - 1 ] ;
917+ assert_eq ! (
918+ format!( "{:?}" , frame_bytes_from_buf( & frame_buf) ) ,
919+ "Err(VnetHeaderMissing)"
920+ ) ;
921+ assert_eq ! (
922+ format!( "{:?}" , frame_bytes_from_buf_mut( & mut frame_buf) ) ,
923+ "Err(VnetHeaderMissing)"
924+ ) ;
925+
896926 let mut frame_buf: [ u8 ; MAX_BUFFER_SIZE ] = [ 42u8 ; MAX_BUFFER_SIZE ] ;
897927
898928 let vnet_hdr_len_ = mem:: size_of :: < virtio_net_hdr_v1 > ( ) ;
@@ -903,10 +933,10 @@ pub(crate) mod tests {
903933 assert_eq ! ( zero_vnet_hdr, & frame_buf[ ..vnet_hdr_len_] ) ;
904934
905935 let payload = vec ! [ 42u8 ; MAX_BUFFER_SIZE - vnet_hdr_len_] ;
906- assert_eq ! ( payload, frame_bytes_from_buf( & frame_buf) ) ;
936+ assert_eq ! ( payload, frame_bytes_from_buf( & frame_buf) . unwrap ( ) ) ;
907937
908938 {
909- let payload = frame_bytes_from_buf_mut ( & mut frame_buf) ;
939+ let payload = frame_bytes_from_buf_mut ( & mut frame_buf) . unwrap ( ) ;
910940 payload[ 0 ] = 15 ;
911941 }
912942 assert_eq ! ( frame_buf[ vnet_hdr_len_] , 15 ) ;
@@ -996,6 +1026,7 @@ pub(crate) mod tests {
9961026 }
9971027
9981028 #[ test]
1029+ #[ allow( clippy:: cognitive_complexity) ]
9991030 fn test_event_processing ( ) {
10001031 let mut event_manager = EventManager :: new ( ) . unwrap ( ) ;
10011032 let mut net = Net :: default_net ( TestMutators :: default ( ) ) ;
@@ -1050,20 +1081,39 @@ pub(crate) mod tests {
10501081 net. rx_bytes_read = 0 ;
10511082 }
10521083
1053- // Now let's move on to the actual device events.
10541084 {
1055- // testing TX_QUEUE_EVENT
1085+ // Send an invalid frame (too small, VNET header missing).
10561086 txq. avail . idx . set ( 1 ) ;
10571087 txq. avail . ring [ 0 ] . set ( 0 ) ;
1058- txq. dtable [ 0 ] . set ( daddr, 0x1000 , 0 , 0 ) ;
1088+ txq. dtable [ 0 ] . set ( daddr, 1 , 0 , 0 ) ;
10591089
1090+ // Trigger the TX handler.
10601091 net. queue_evts [ TX_INDEX ] . write ( 1 ) . unwrap ( ) ;
10611092 let event = EpollEvent :: new ( EventSet :: IN , net. queue_evts [ TX_INDEX ] . as_raw_fd ( ) as u64 ) ;
1062- net. process ( & event, & mut event_manager) ;
1093+ check_metric_after_block ! (
1094+ & METRICS . net. tx_malformed_frames,
1095+ 1 ,
1096+ net. process( & event, & mut event_manager)
1097+ ) ;
1098+
10631099 // Make sure the data queue advanced.
10641100 assert_eq ! ( txq. used. idx. get( ) , 1 ) ;
10651101 }
10661102
1103+ // Now let's move on to the actual device events.
1104+ {
1105+ // testing TX_QUEUE_EVENT
1106+ txq. avail . idx . set ( 2 ) ;
1107+ txq. avail . ring [ 1 ] . set ( 1 ) ;
1108+ txq. dtable [ 1 ] . set ( daddr, 0x1000 , 0 , 0 ) ;
1109+
1110+ net. queue_evts [ TX_INDEX ] . write ( 1 ) . unwrap ( ) ;
1111+ let event = EpollEvent :: new ( EventSet :: IN , net. queue_evts [ TX_INDEX ] . as_raw_fd ( ) as u64 ) ;
1112+ net. process ( & event, & mut event_manager) ;
1113+ // Make sure the data queue advanced.
1114+ assert_eq ! ( txq. used. idx. get( ) , 2 ) ;
1115+ }
1116+
10671117 {
10681118 // testing RX_TAP_EVENT
10691119
@@ -1078,7 +1128,7 @@ pub(crate) mod tests {
10781128 let tap_event = EpollEvent :: new ( EventSet :: IN , net. tap . as_raw_fd ( ) as u64 ) ;
10791129 net. process ( & tap_event, & mut event_manager) ;
10801130 assert ! ( net. rx_deferred_frame) ;
1081- assert_eq ! ( net. interrupt_evt. read( ) . unwrap( ) , 3 ) ;
1131+ assert_eq ! ( net. interrupt_evt. read( ) . unwrap( ) , 4 ) ;
10821132 // The #cfg(test) enabled version of read_tap always returns 1234 bytes (or the len of
10831133 // the buffer, whichever is smaller).
10841134 assert_eq ! ( rxq. used. ring[ 0 ] . get( ) . len, 1234 ) ;
@@ -1162,7 +1212,7 @@ pub(crate) mod tests {
11621212 {
11631213 // Create an ethernet frame.
11641214 let eth_frame_i = EthernetFrame :: write_incomplete (
1165- frame_bytes_from_buf_mut ( & mut net. tx_frame_buf ) ,
1215+ frame_bytes_from_buf_mut ( & mut net. tx_frame_buf ) . unwrap ( ) ,
11661216 tha,
11671217 sha,
11681218 ETHERTYPE_ARP ,
@@ -1198,7 +1248,8 @@ pub(crate) mod tests {
11981248 & net. tx_frame_buf[ ..packet_len] ,
11991249 & mut net. tap,
12001250 Some ( sha) ,
1201- ) )
1251+ )
1252+ . unwrap( ) )
12021253 ) ;
12031254
12041255 // Validate that MMDS has a response and we can retrieve it.
@@ -1223,7 +1274,7 @@ pub(crate) mod tests {
12231274 {
12241275 // Create an ethernet frame.
12251276 let eth_frame_i = EthernetFrame :: write_incomplete (
1226- frame_bytes_from_buf_mut ( & mut net. tx_frame_buf ) ,
1277+ frame_bytes_from_buf_mut ( & mut net. tx_frame_buf ) . unwrap ( ) ,
12271278 dst_mac,
12281279 guest_mac,
12291280 ETHERTYPE_ARP ,
0 commit comments