@@ -56,6 +56,11 @@ const TX_RATE_LIMITER_EVENT: DeviceEventT = 4;
5656// Number of DeviceEventT events supported by this implementation.
5757pub const NET_EVENTS_COUNT : usize = 5 ;
5858
59+ // This is not a true DeviceEvent, as we explicitly invoke the handler with this value as a
60+ // parameter when the VMM handles as PATCH rate limiters request. Thus, there's not epoll event
61+ // associated with it.
62+ const PATCH_RATE_LIMITERS : DeviceEventT = 5 ;
63+
5964#[ derive( Debug ) ]
6065pub enum Error {
6166 /// Open tap device failed.
@@ -504,7 +509,7 @@ impl EpollHandler for NetEpollHandler {
504509 & mut self ,
505510 device_event : DeviceEventT ,
506511 _: u32 ,
507- _ : EpollHandlerPayload ,
512+ payload : EpollHandlerPayload ,
508513 ) -> result:: Result < ( ) , DeviceError > {
509514 match device_event {
510515 RX_QUEUE_EVENT => {
@@ -600,6 +605,17 @@ impl EpollHandler for NetEpollHandler {
600605 }
601606 }
602607 }
608+ PATCH_RATE_LIMITERS => {
609+ if let EpollHandlerPayload :: PatchRateLimiters ( rx_bytes, rx_ops, tx_bytes, tx_ops) =
610+ payload
611+ {
612+ self . rx . rate_limiter . update_buckets ( rx_bytes, rx_ops) ;
613+ self . tx . rate_limiter . update_buckets ( tx_bytes, tx_ops) ;
614+ Ok ( ( ) )
615+ } else {
616+ Err ( DeviceError :: PayloadExpected )
617+ }
618+ }
603619 other => Err ( DeviceError :: UnknownEvent {
604620 device : "net" ,
605621 event : other,
@@ -951,6 +967,7 @@ mod tests {
951967 use virtio:: queue:: tests:: * ;
952968
953969 use dumbo:: pdu:: { arp, ethernet} ;
970+ use rate_limiter:: TokenBucket ;
954971
955972 /// Will read $metric, run the code in $block, then assert metric has increased by $delta.
956973 macro_rules! check_metric_after_block {
@@ -1484,14 +1501,13 @@ mod tests {
14841501 fn test_invalid_event_handler ( ) {
14851502 let mem = GuestMemory :: new ( & [ ( GuestAddress ( 0 ) , 0x10000 ) ] ) . unwrap ( ) ;
14861503 let ( mut h, _txq, _rxq) = default_test_netepollhandler ( & mem, TestMutators :: default ( ) ) ;
1487- let r = h. handle_event (
1488- NET_EVENTS_COUNT as DeviceEventT ,
1489- 0 ,
1490- EpollHandlerPayload :: Empty ,
1491- ) ;
1504+
1505+ let bad_event = 1000 ;
1506+
1507+ let r = h. handle_event ( bad_event as DeviceEventT , 0 , EpollHandlerPayload :: Empty ) ;
14921508 match r {
14931509 Err ( DeviceError :: UnknownEvent { event, device } ) => {
1494- assert_eq ! ( event, NET_EVENTS_COUNT as DeviceEventT ) ;
1510+ assert_eq ! ( event, bad_event as DeviceEventT ) ;
14951511 assert_eq ! ( device, "net" ) ;
14961512 }
14971513 _ => panic ! ( "invalid" ) ,
@@ -1910,4 +1926,41 @@ mod tests {
19101926 }
19111927 }
19121928 }
1929+
1930+ #[ test]
1931+ fn test_patch_rate_limiters ( ) {
1932+ let mem = GuestMemory :: new ( & [ ( GuestAddress ( 0 ) , 0x10000 ) ] ) . unwrap ( ) ;
1933+ let ( mut h, _, _) = default_test_netepollhandler ( & mem, TestMutators :: default ( ) ) ;
1934+
1935+ h. set_rx_rate_limiter ( RateLimiter :: new ( 10 , None , 10 , 2 , None , 2 ) . unwrap ( ) ) ;
1936+ h. set_tx_rate_limiter ( RateLimiter :: new ( 10 , None , 10 , 2 , None , 2 ) . unwrap ( ) ) ;
1937+
1938+ let rx_bytes = TokenBucket :: new ( 1000 , Some ( 1001 ) , 1002 ) ;
1939+ let rx_ops = TokenBucket :: new ( 1003 , Some ( 1004 ) , 1005 ) ;
1940+ let tx_bytes = TokenBucket :: new ( 1006 , Some ( 1007 ) , 1008 ) ;
1941+ let tx_ops = TokenBucket :: new ( 1009 , Some ( 1010 ) , 1011 ) ;
1942+
1943+ h. handle_event (
1944+ PATCH_RATE_LIMITERS ,
1945+ 0 ,
1946+ EpollHandlerPayload :: PatchRateLimiters (
1947+ Some ( rx_bytes. clone ( ) ) ,
1948+ Some ( rx_ops. clone ( ) ) ,
1949+ Some ( tx_bytes. clone ( ) ) ,
1950+ Some ( tx_ops. clone ( ) ) ,
1951+ ) ,
1952+ )
1953+ . unwrap ( ) ;
1954+
1955+ let compare_buckets = |a : & TokenBucket , b : & TokenBucket | {
1956+ assert_eq ! ( a. capacity( ) , b. capacity( ) ) ;
1957+ assert_eq ! ( a. one_time_burst( ) , b. one_time_burst( ) ) ;
1958+ assert_eq ! ( a. refill_time_ms( ) , b. refill_time_ms( ) ) ;
1959+ } ;
1960+
1961+ compare_buckets ( h. get_rx_rate_limiter ( ) . bandwidth ( ) . unwrap ( ) , & rx_bytes) ;
1962+ compare_buckets ( h. get_rx_rate_limiter ( ) . ops ( ) . unwrap ( ) , & rx_ops) ;
1963+ compare_buckets ( h. get_tx_rate_limiter ( ) . bandwidth ( ) . unwrap ( ) , & tx_bytes) ;
1964+ compare_buckets ( h. get_tx_rate_limiter ( ) . ops ( ) . unwrap ( ) , & tx_ops) ;
1965+ }
19131966}
0 commit comments