@@ -251,6 +251,20 @@ fn register_netdevice(dev: Arc<dyn Iface>) -> Result<(), SystemError> {
251251 return Ok ( ( ) ) ;
252252}
253253
254+ #[ derive( Debug ) ]
255+ struct ReceiveModeState {
256+ configured_flags : u32 ,
257+ packet_promiscuity : u32 ,
258+ packet_allmulti : u32 ,
259+ }
260+
261+ #[ derive( Debug , Clone , Copy ) ]
262+ pub struct LinkFlagsSnapshot {
263+ pub configured : InterfaceFlags ,
264+ pub promiscuity : u32 ,
265+ pub allmulti : u32 ,
266+ }
267+
254268pub struct IfaceCommon {
255269 iface_id : usize ,
256270 name : RwLock < String > ,
@@ -279,6 +293,8 @@ pub struct IfaceCommon {
279293 /// TCP listener/backlog 语义辅助(Linux-like 丢 SYN 等)。
280294 tcp_listener_backlog : crate :: net:: tcp_listener_backlog:: TcpListenerBacklog ,
281295 ipv4_multicast_refcnt : Mutex < Vec < ( smoltcp:: wire:: Ipv4Address , usize ) > > ,
296+ /// Serializes configured receive-mode flags with AF_PACKET references.
297+ receive_mode : Mutex < ReceiveModeState > ,
282298}
283299
284300impl fmt:: Debug for IfaceCommon {
@@ -323,6 +339,11 @@ impl IfaceCommon {
323339 tcp_close_defer : crate :: net:: tcp_close_defer:: TcpCloseDefer :: new ( ) ,
324340 tcp_listener_backlog : crate :: net:: tcp_listener_backlog:: TcpListenerBacklog :: new ( ) ,
325341 ipv4_multicast_refcnt : Mutex :: new ( Vec :: new ( ) ) ,
342+ receive_mode : Mutex :: new ( ReceiveModeState {
343+ configured_flags : flags. bits ( ) ,
344+ packet_promiscuity : 0 ,
345+ packet_allmulti : 0 ,
346+ } ) ,
326347 }
327348 }
328349
@@ -668,11 +689,46 @@ impl IfaceCommon {
668689 }
669690
670691 pub fn flags ( & self ) -> InterfaceFlags {
671- InterfaceFlags :: from_bits_truncate ( self . flags . load ( Ordering :: Relaxed ) )
692+ InterfaceFlags :: from_bits_truncate ( self . flags . load ( Ordering :: Acquire ) )
672693 }
673694
674- pub fn set_flags ( & self , flags : InterfaceFlags ) {
675- self . flags . store ( flags. bits ( ) , Ordering :: Relaxed ) ;
695+ pub fn update_configured_flags (
696+ & self ,
697+ requested : InterfaceFlags ,
698+ change_mask : InterfaceFlags ,
699+ ) -> Result < InterfaceFlags , SystemError > {
700+ let mut state = self . receive_mode . lock ( ) ;
701+ let configured = ( state. configured_flags & !change_mask. bits ( ) )
702+ | ( requested. bits ( ) & change_mask. bits ( ) ) ;
703+
704+ Self :: total_receive_mode_count (
705+ state. packet_promiscuity ,
706+ configured & InterfaceFlags :: PROMISC . bits ( ) != 0 ,
707+ ) ?;
708+ Self :: total_receive_mode_count (
709+ state. packet_allmulti ,
710+ configured & InterfaceFlags :: ALLMULTI . bits ( ) != 0 ,
711+ ) ?;
712+
713+ state. configured_flags = configured;
714+ self . publish_effective_flags ( & state) ;
715+ Ok ( InterfaceFlags :: from_bits_truncate ( configured) )
716+ }
717+
718+ pub fn link_flags_snapshot ( & self ) -> Result < LinkFlagsSnapshot , SystemError > {
719+ let state = self . receive_mode . lock ( ) ;
720+ let configured = InterfaceFlags :: from_bits_truncate ( state. configured_flags ) ;
721+ Ok ( LinkFlagsSnapshot {
722+ configured,
723+ promiscuity : Self :: total_receive_mode_count (
724+ state. packet_promiscuity ,
725+ configured. contains ( InterfaceFlags :: PROMISC ) ,
726+ ) ?,
727+ allmulti : Self :: total_receive_mode_count (
728+ state. packet_allmulti ,
729+ configured. contains ( InterfaceFlags :: ALLMULTI ) ,
730+ ) ?,
731+ } )
676732 }
677733
678734 pub fn type_ ( & self ) -> InterfaceType {
@@ -755,4 +811,55 @@ impl IfaceCommon {
755811 neighbors. retain ( |existing| existing. ip_addr != ip_addr) ;
756812 neighbors. len ( ) != before
757813 }
814+
815+ pub fn adjust_promiscuity ( & self , inc : i32 ) -> Result < ( ) , SystemError > {
816+ self . adjust_receive_mode ( InterfaceFlags :: PROMISC , inc)
817+ }
818+
819+ pub fn adjust_allmulti ( & self , inc : i32 ) -> Result < ( ) , SystemError > {
820+ self . adjust_receive_mode ( InterfaceFlags :: ALLMULTI , inc)
821+ }
822+
823+ fn adjust_receive_mode ( & self , flag : InterfaceFlags , inc : i32 ) -> Result < ( ) , SystemError > {
824+ let mut state = self . receive_mode . lock ( ) ;
825+ let old = if flag == InterfaceFlags :: PROMISC {
826+ state. packet_promiscuity
827+ } else if flag == InterfaceFlags :: ALLMULTI {
828+ state. packet_allmulti
829+ } else {
830+ return Err ( SystemError :: EINVAL ) ;
831+ } ;
832+ let new = match inc {
833+ 1 => old. checked_add ( 1 ) . ok_or ( SystemError :: EOVERFLOW ) ?,
834+ -1 => old. checked_sub ( 1 ) . ok_or ( SystemError :: EINVAL ) ?,
835+ _ => return Err ( SystemError :: EINVAL ) ,
836+ } ;
837+ let configured = state. configured_flags & flag. bits ( ) != 0 ;
838+ Self :: total_receive_mode_count ( new, configured) ?;
839+
840+ if flag == InterfaceFlags :: PROMISC {
841+ state. packet_promiscuity = new;
842+ } else {
843+ state. packet_allmulti = new;
844+ }
845+ self . publish_effective_flags ( & state) ;
846+ Ok ( ( ) )
847+ }
848+
849+ fn total_receive_mode_count ( packet : u32 , configured : bool ) -> Result < u32 , SystemError > {
850+ packet
851+ . checked_add ( u32:: from ( configured) )
852+ . ok_or ( SystemError :: EOVERFLOW )
853+ }
854+
855+ fn publish_effective_flags ( & self , state : & ReceiveModeState ) {
856+ let mut effective = state. configured_flags ;
857+ if state. packet_promiscuity != 0 {
858+ effective |= InterfaceFlags :: PROMISC . bits ( ) ;
859+ }
860+ if state. packet_allmulti != 0 {
861+ effective |= InterfaceFlags :: ALLMULTI . bits ( ) ;
862+ }
863+ self . flags . store ( effective, Ordering :: Release ) ;
864+ }
758865}
0 commit comments