那一包“离奇”:局域网 ARP 冲突丢包排障记
有些丢包,本以为是物理信号或驱动层面的玄学博弈。
比如我这台机械革命蛟龙 16S 笔记本,搭载 AMD Ryzen 7 7840H 和 Intel AX210 网卡,运行着 Arch Linux 系统。
今晚在朋友家连上无线网,打算干点活。顺手在终端里 ping 了一下路由器网关 192.168.1.1,跳出来的统计结果却让我瞬间皱起了眉头:
1 | --- 192.168.1.1 ping 统计 --- |
丢包率高达 14%。在无线连接下,这种规律性的、不高不低的丢包极其致命,会让网页加载频繁卡住,SSH 会话时不时挂起。
然而,拉出一根网线直连光猫,丢包率瞬间归零。
更诡异的是,旁边朋友那台装了 Intel AX201 网卡的 Windows 笔记本,同样连着 Wi-Fi,却稳如泰山,物理包一个不落。
这已经不是光猫上行宽带的问题了。这是无线局域网内的妖风。
阶段一:错怪了的 160MHz 与被“遗忘”的 BIOS 补丁
既然丢包只发生在 Wi-Fi 连接下,我首先怀疑的是 Intel AX210 网卡驱动(iwlwifi)与这台联通光猫(SSID 为 CU_u27S_5G)在 Wi-Fi 6 (802.11ax) 160MHz 超宽频 下的兼容性问题。在 Linux 社区里,AX210 网卡由于 160MHz 下的通道唤醒或 DFS 雷达波干涉引发的丢包和队列卡死(tx queue hang)案例屡见不鲜。
我甚至去翻了机械革命这台机器 2023 年底的最后一次 BIOS 更新归档(BIOS_N1.24MRO14_EC_1.31.zip),里面的更新日志里明确写着一条:
Disable wlan ASPM 以优化搭配 ax200 网卡的稳定性
这说明厂商确实注意到了 PCIe 链路的主动状态电源管理(ASPM)在休眠唤醒时会导致无线网卡不稳定。然而,这个 BIOS 补丁是个“缝合怪”——它在固件中只匹配了 Intel AX200 的设备 ID (8086:2723)。而我的电脑装的是 Intel AX210 (8086:2725)。
因为设备 ID 没对上,BIOS 的自动屏蔽规则对我这张网卡完全失效,导致我的 PCIe 链路依然强行开启着 ASPM,在低功耗 L1 状态和工作 L0 状态之间反复横跳。
可是,这个解释很快就被事实击碎了:
我用这台电脑连自己黑龙江家里的 OpenWRT 路由器,或者连宁波家里的移动光猫,同样都是 Wi-Fi 6 160MHz 频宽,却连一个包都不丢。
驱动和频宽都是无辜的。
阶段二:系统日志中的“同室操戈”
排除物理频宽后,我拉出了 NetworkManager 的系统日志。在连接 Wi-Fi 后的第 80 秒,日志里静静地躺着一条平时极其罕见的警告:
1 | NetworkManager[1016]: <info> device (wlp4s0): conflict detected for IP address 192.168.1.6 with host 6A:5F:05:4A:40:BF |
IP 地址冲突。
我的 Linux 笔记本拿到了 192.168.1.6 这个 IP 地址,但局域网里有另一个物理地址为 6a:5f:05:4a:40:bf 的设备,也在向全网宣示自己拥有 192.168.1.6。
在现代无线网络中,为了防范隐私追踪,客户端(如手机、MacBook)默认都会启用“私有 Wi-Fi 地址”机制,即每次连接时生成一个虚假的随机 MAC 地址。这个 6a:5f:05... 的第一字节第二十六进制位为 a(二进制最低两位为 10),证实了它确实是一个本地管理的随机化 MAC 地址,无法通过 OUI 厂商数据库查询其物理归属。
但难不倒我。我使用 Avahi(基于 mDNS 组播的局域网解析工具)在终端里直接反查这两个 IP:
1 | $ avahi-resolve -a 192.168.1.5 |
大白于天下。
这个正在和我疯狂抢夺 192.168.1.6 的局域网死敌,居然就是我放在双肩包里、已经盖上盖子“休眠”了的 MacBook Air!
阶段三:硬核科普:休眠的 Mac 为何会疯狂抢 IP?
局域网内这两台机器“同室操戈”的背后,是一套“苹果黑科技”撞上“运营商弱智光猫”的经典名场面。
1. 苹果的“休眠不掉线”与睡眠代理(Sleep Proxy)
苹果为了实现“寻找我的 Mac”(Find My)、局域网唤醒(WOL)以及即使盖上盖子也能接收隔空投送(AirDrop),在 macOS 中强制引入了 Bonjour 睡眠代理服务(RFC 6281)。
当 MacBook 进入睡眠状态时,它并不会彻底从无线网络中消失。它的无线芯片会保持极低功耗的联络,或者将其 IP 地址和主机名暂时“托管”给局域网内的睡眠代理设备(如 Apple TV 或 HomePod)。只要局域网内有关于它的 ARP 询问,Mac 或其代理设备就会立刻苏醒并回应:“我依然占着这个 IP,别动我的位置。”
由于我的 MacBook 开启了 MAC 地址随机化,且因为虚拟网卡(如随航/AirDrop 专用的 awdl0 接口)的桥接,它在光猫的 DHCP 租约池里残留并占用了 .5 和 .6 两个地址。
2. 联通光猫的“盲人”分配
正常情况下,DHCP 服务器在将一个 IP(如 192.168.1.6)分配给新连入的设备前,必须先在局域网内发送一个 ARP 探测包(ARP Probe)确认此地址是否有人在使用。
但这台运营商送的联通光猫固件为了省开销,直接省略了这一步。当我的 Linux 笔记本请求 IP 时,光猫看着自己的租约表,觉得 .6 似乎空闲,就盲发给了我的 Linux 笔记本。
3. 局域网内的“互抽耳光”:免费 ARP 与 ARP 抖动
既然两个设备都自认为是 192.168.1.6,局域网的冲突就爆发了。
当 MacBook 后台有通信活动或处于半唤醒时,它会向全网广播一个 “免费 ARP”(Gratuitous ARP) 包:
“所有人注意,我是 192.168.1.6,我的物理地址是 6A:5F:05:4A:40:BF,以后把发给
.6的数据包交给我!”
光猫和局域网交换机收到后,立刻更新 ARP 映射表,把发给 .6 的数据包转给 Mac。此时,我的 Linux 笔记本收不到数据了(表现为丢包),系统检测到 IP 被篡改,开始发送防御 ARP(ARP Defense)把路由所有权夺回来。
两台机器在局域网内高频地互发 ARP 争夺控制权。表现在应用层,就是我测试得到的 14.1876% 的规律性偶发丢包。而我朋友的 AX201 笔记本分到的是清干净的 192.168.1.5,没有人抢,自然稳如泰山。
阶段四:去伪存真,根本性修复实践
既然找到了病灶,解决起来就非常清晰了。我从三个层面给出了治标与治本的终极配置方案:
1. 治标:手动分配高位静态 IP
既然光猫的 DHCP 分配池一片混乱,最直接的做法就是手动避让。我直接把 Linux 笔记本的 Wi-Fi 连接属性从“自动(DHCP)”修改为“手动(Static)”,并指定了一个远离默认分配池的高位地址:
1 | # 绑定 192.168.1.200 |
为了验证效果,我编写了一个高频 Ping 监控脚本,在后台不间断地向网关发送 ICMP 请求,一旦检测到任何 1 个丢包就记录发包总数并立即退出。
在长达 300 秒(连续发送 300 个包) 的长测中,后台监控 Job 始终稳定运行,丢包率成功归零。
2. 治本:关闭可信局域网的“私有 MAC 地址”
为了从源头上阻止 MacBook 制造 DHCP 租约混乱,我在 MacBook 的无线连接设置中,针对朋友家和自己家的 Wi-Fi,关闭了“私有无线地址”(随机 MAC),变更为“使用设备 MAC”。
设备的物理 MAC 终身固定后,路由器的 DHCP 表永远保持 1 对 1 的稳定绑定,再也不会出现租约到期未释放、IP 错配给新设备的惨剧。
3. 防御:配置 Linux 客户端的冲突防御(ACD)
为了防止日后在其他陌生局域网(如酒店、咖啡厅等同样使用低端路由器的公共场所)再次遇到此类隐蔽的 IP 冲突,我直接在 Linux 的 NetworkManager 中配置了严格的 ACD(地址冲突检测,RFC 5227) 机制。
创建全局配置文件 /etc/NetworkManager/conf.d/30-acd.conf:
1 | [connection] |
保存并使用 sudo nmcli general reload 载入配置。这样,NetworkManager 在获取 IP 前会先发 ARP 探测 2 秒。如果发现冲突,它会直接拒绝配置该地址,并要求 DHCP 分配新 IP,从系统层面杜绝了“肉搏抢 IP”的可能。
4. 电源管理优化:清除 TLP 对 AX210 的干扰
在排查过程中,我还发现系统激活了 tlp 服务。在 Linux 下,TLP 会在笔记本拔掉电源切换至电池供电时,自动将 Wi-Fi 强制切换为低功耗省电模式(Power Save)。
这对于 Intel AX210 这类高性能网卡而言,在 Linux 驱动下极易引起偶发性的延迟暴增。我直接停用了 TLP,并启用了在 Arch Linux 下与现代 AMD CPU 的 amd-pstate-epp 调频驱动配合更完美的 power-profiles-daemon:
1 | sudo systemctl disable --now tlp |
结语
在 300 秒长测的最后一个数据包安全送达后,后台的监控进程默默退出了。
折腾完这一切,屏幕右上角的网络指示标终于恢复了平静。局域网的路由表归于秩序,MacBook 在背包里静静长眠,Linux 笔记本则在 192.168.1.200 上丝滑地吞吐着数据。
在复杂的网络排障中,物理层和驱动层往往会吸引我们大部分的注意力。然而,当那些“兼容性问题”怎么也解释不通时,不妨退一步,拉开系统日志去看看那些最基础的局域网协议层。
很多时候,困扰你许久的妖风,不过是两台机器在一场愚蠢的 IP 争夺战中,互相扔下的无形板砖。