link fix
This commit is contained in:
@@ -552,58 +552,87 @@ class BridgeLinkStateWatcher:
|
||||
if source_profile is None or target_profile is None or source_profile == target_profile:
|
||||
return None
|
||||
|
||||
cmd = [_ETHTOOL_BIN, "-s", target_ifname]
|
||||
change_summary: Optional[str] = None
|
||||
commands: list[tuple[list[str], str]] = []
|
||||
if source_profile.autoneg is True:
|
||||
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 that effective mode while keeping autoneg enabled
|
||||
# on the sibling so its far-end peer can still negotiate successfully.
|
||||
cmd.extend(
|
||||
commands.append(
|
||||
(
|
||||
[
|
||||
_ETHTOOL_BIN,
|
||||
"-s",
|
||||
target_ifname,
|
||||
"speed",
|
||||
str(source_profile.speed_mbps),
|
||||
"duplex",
|
||||
source_profile.duplex,
|
||||
"autoneg",
|
||||
"on",
|
||||
],
|
||||
(
|
||||
f"{target_ifname} link={source_profile.speed_mbps}Mb/"
|
||||
f"{source_profile.duplex}/autoneg-on"
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
commands.append(([_ETHTOOL_BIN, "-s", target_ifname, "autoneg", "on"], 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:
|
||||
# Do not force autoneg off on sibling ports. The far-end peer on that segment may
|
||||
# still rely on autoneg, and forcing a fixed mode here can leave the link down.
|
||||
commands.append(
|
||||
(
|
||||
[
|
||||
_ETHTOOL_BIN,
|
||||
"-s",
|
||||
target_ifname,
|
||||
"speed",
|
||||
str(source_profile.speed_mbps),
|
||||
"duplex",
|
||||
source_profile.duplex,
|
||||
"autoneg",
|
||||
"on",
|
||||
]
|
||||
],
|
||||
(
|
||||
f"{target_ifname} link={source_profile.speed_mbps}Mb/"
|
||||
f"{source_profile.duplex}/autoneg-on-safe"
|
||||
),
|
||||
)
|
||||
change_summary = (
|
||||
f"{target_ifname} link={source_profile.speed_mbps}Mb/"
|
||||
f"{source_profile.duplex}/autoneg-on"
|
||||
)
|
||||
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(
|
||||
[
|
||||
"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}/autoneg-off"
|
||||
commands.append(
|
||||
(
|
||||
[_ETHTOOL_BIN, "-s", target_ifname, "autoneg", "on"],
|
||||
f"{target_ifname} link=autoneg-on-safe",
|
||||
)
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
||||
try:
|
||||
subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
except (FileNotFoundError, subprocess.CalledProcessError) as exc:
|
||||
logger.debug(
|
||||
"Failed to synchronize ethtool profile from %s to %s on bridge=%s: %s",
|
||||
source_ifname,
|
||||
target_ifname,
|
||||
self.bridge_name,
|
||||
exc,
|
||||
)
|
||||
last_error: Optional[Exception] = None
|
||||
for cmd, summary in commands:
|
||||
try:
|
||||
subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
change_summary = summary
|
||||
break
|
||||
except (FileNotFoundError, subprocess.CalledProcessError) as exc:
|
||||
last_error = exc
|
||||
logger.debug(
|
||||
"Failed to synchronize ethtool profile from %s to %s on bridge=%s with %s: %s",
|
||||
source_ifname,
|
||||
target_ifname,
|
||||
self.bridge_name,
|
||||
cmd,
|
||||
exc,
|
||||
)
|
||||
|
||||
if change_summary is None:
|
||||
if last_error is not None:
|
||||
self._set_last_action(
|
||||
f"failed to sync link profile from {source_ifname} to {target_ifname}: {last_error}"
|
||||
)
|
||||
return None
|
||||
|
||||
self._mark_managed_change(target_ifname)
|
||||
|
||||
Reference in New Issue
Block a user