diff --git a/backend/src/utilities/bridge_link_state_manager.py b/backend/src/utilities/bridge_link_state_manager.py index 0698f40..184ea4c 100644 --- a/backend/src/utilities/bridge_link_state_manager.py +++ b/backend/src/utilities/bridge_link_state_manager.py @@ -553,8 +553,30 @@ class BridgeLinkStateWatcher: return None cmd = [_ETHTOOL_BIN, "-s", target_ifname] + change_summary: Optional[str] = None if source_profile.autoneg is True: - cmd.extend(["autoneg", "on"]) + if source_profile.speed_mbps is not None and source_profile.duplex is not None: + # A remote peer can pull this port down to a lower negotiated speed while autoneg + # stays enabled locally. Mirror the effective link mode on sibling ports so they + # present the same downstream behavior even though the peer's exact advertisement + # bitmap is not visible from this host. + cmd.extend( + [ + "speed", + str(source_profile.speed_mbps), + "duplex", + source_profile.duplex, + "autoneg", + "off", + ] + ) + change_summary = ( + f"{target_ifname} link={source_profile.speed_mbps}Mb/" + f"{source_profile.duplex}/forced-from-autoneg-peer" + ) + else: + cmd.extend(["autoneg", "on"]) + change_summary = f"{target_ifname} link=autoneg-on" elif source_profile.autoneg is False and source_profile.speed_mbps is not None and source_profile.duplex is not None: cmd.extend( [ @@ -566,6 +588,10 @@ class BridgeLinkStateWatcher: "off", ] ) + change_summary = ( + f"{target_ifname} link={source_profile.speed_mbps}Mb/" + f"{source_profile.duplex}/autoneg-off" + ) else: return None @@ -589,11 +615,7 @@ class BridgeLinkStateWatcher: self.bridge_name, source_profile, ) - return ( - f"{target_ifname} link=" - f"{source_profile.speed_mbps or 'unknown'}Mb/{source_profile.duplex or 'unknown'}/" - f"{'autoneg-on' if source_profile.autoneg else 'autoneg-off'}" - ) + return change_summary def _suppress_other_members(self, states: dict[str, MemberLinkState], failing_members: list[str]) -> None: desired_suppressed = set(states) - set(failing_members)