Skip MAC rotation on active WiFi interfaces to prevent ENETDOWN

When wlan0 is the primary data interface (WiFi-only deployment), changing
its MAC via SIOCSIFHWADDR drops the AP association and puts all AF_PACKET
sockets into ENETDOWN permanently until wpa_supplicant re-associates.

- _apply_profile: skip set_mac if _eth_iface is a WiFi interface
- _apply_profile: skip WiFi set_mac if _wifi_iface == _eth_iface (same card)
- stop: mirror the same skip logic for MAC restoration

DHCP hostname + TCP stack tuning still applied for blending on WiFi-only nodes.
This commit is contained in:
Cobra
2026-04-07 12:48:56 -04:00
parent 7f58f1cab3
commit e15e077be8
+27 -12
View File
@@ -117,11 +117,15 @@ class MacManager(BaseModule):
if not self._running: if not self._running:
return return
# Restore original MACs on clean exit # Restore original MACs on clean exit — skip WiFi interfaces to avoid
# dropping the active association.
wifi_ifaces = set(get_wifi_interfaces())
try: try:
if self._eth_iface and self._original_eth_mac: if self._eth_iface and self._original_eth_mac and self._eth_iface not in wifi_ifaces:
set_mac(self._eth_iface, self._original_eth_mac) set_mac(self._eth_iface, self._original_eth_mac)
if self._wifi_iface and self._original_wifi_mac: if (self._wifi_iface and self._original_wifi_mac
and self._wifi_iface != self._eth_iface
and self._wifi_iface not in wifi_ifaces):
set_mac(self._wifi_iface, self._original_wifi_mac) set_mac(self._wifi_iface, self._original_wifi_mac)
except Exception as exc: except Exception as exc:
logger.warning("Failed to restore original MAC: %s", exc) logger.warning("Failed to restore original MAC: %s", exc)
@@ -258,16 +262,27 @@ class MacManager(BaseModule):
new_mac = f"{oui}:{suffix}" new_mac = f"{oui}:{suffix}"
profile["applied_mac"] = new_mac profile["applied_mac"] = new_mac
# Set MAC on Ethernet wifi_ifaces = set(get_wifi_interfaces())
if self._eth_iface:
try:
set_mac(self._eth_iface, new_mac)
logger.debug("Set %s MAC to %s", self._eth_iface, new_mac)
except Exception as exc:
logger.error("Failed to set MAC on %s: %s", self._eth_iface, exc)
# Set MAC on WiFi (different suffix for uniqueness) # Set MAC on Ethernet — skip if it's also a WiFi interface (changing MAC
if self._wifi_iface: # on an associated WiFi interface drops the connection and causes ENETDOWN
# on all AF_PACKET sockets bound to it).
if self._eth_iface:
if self._eth_iface in wifi_ifaces:
logger.info(
"Skipping MAC change on %s — active WiFi interface, would break association",
self._eth_iface,
)
else:
try:
set_mac(self._eth_iface, new_mac)
logger.debug("Set %s MAC to %s", self._eth_iface, new_mac)
except Exception as exc:
logger.error("Failed to set MAC on %s: %s", self._eth_iface, exc)
# Set MAC on WiFi only if it's a separate interface from the primary eth
# (e.g., a dedicated monitor card). Same interface = already handled above.
if self._wifi_iface and self._wifi_iface != self._eth_iface:
wifi_suffix = ":".join(f"{random.randint(0, 255):02x}" for _ in range(3)) wifi_suffix = ":".join(f"{random.randint(0, 255):02x}" for _ in range(3))
wifi_mac = f"{oui}:{wifi_suffix}" wifi_mac = f"{oui}:{wifi_suffix}"
try: try: