登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux ARP 邻居状态异常怎样读取和刷新

来源:17golang原创

时间:2026-10-18 02:21:21 442浏览 收藏

Linux 上遇到“同一网段偶尔不通”或“网关地址看起来不对”时,先不要直接重启网络服务。IPv4 的 ARP 结果可以从邻居表读取:用 ip -4 neigh show 看全量记录,用 ip neigh show dev eth0 nud failed 缩小到某块网卡上的失败项;确认目标后,再用 ip neigh flush to 192.0.2.1 dev eth0 或按状态刷新动态条目。stale 只是需要重新确认的旧记录,不等于失败;真正需要优先处理的是持续出现的 incomplete 或 failed。

本文只讨论 Linux 的 ARP 邻居表读取与刷新,不修改路由、不重启网卡,也不把命令示例当成本机运行结果。相关官方资料:https://man7.org/linux/man-pages/man8/ip-neighbour.8.html;Linux 内核邻居管理规范:https://docs.kernel.org/networking/netlink_spec/rt-neigh.html。

先把 ARP 现象还原成邻居表状态

ip neigh 管理的是协议地址到链路层地址的邻居绑定。IPv4 邻居表通常就是大家口中的 ARP 表:左侧是目标 IPv4 地址,中间可以看到网卡和 MAC 地址,末尾的 NUD 状态描述内核当前如何看待这条绑定。这里的“异常”首先要落到一条具体记录和一个状态上,而不是只凭 ping 的一次结果判断。

# 只读取 IPv4 邻居表,避免把 IPv6 NDP 记录混在一起。
ip -4 neigh show

# 只看 eth0 上仍处于失败状态的邻居项。
ip neigh show dev eth0 nud failed

# 只看还没有完成地址解析的项,便于区分暂时等待和最终失败。
ip neigh show dev eth0 nud incomplete

输出中的网卡很重要。同一个目标地址如果从不同接口可达,邻居记录不能脱离接口阅读;在网络命名空间、容器或 VRF 中排查时,也要确认命令是在持有该接口的环境里执行。一次空结果只说明当前筛选条件没有匹配项,不等于整台机器没有 ARP 问题。

'IPv4
图1:结构说明图。目标 IPv4、eth0、MAC、邻居表和 NUD 状态属于同一条静态绑定关系,不是运行截图或执行时序。

不要把 stale 直接当成故障

NUD 状态是判断邻居异常的第一层线索,但不同状态的处理力度不一样。reachable 表示在可达性计时器范围内有效;stale 表示记录仍可用但需要在后续通信中重新确认;delay 和 probe 表示正在进入或执行探测;incomplete 表示地址解析尚未完成;failed 表示探测未成功并最终失败。

permanent 是管理员维护的永久项,noarp 表示不再进行常规验证的有效项。它们和动态邻居的生命周期不同,不能因为看到一条“旧”记录就一并刷新。none 是内核内部或创建/删除过程中的伪状态,普通展示默认不会把它当成常规邻居来列出。

状态更接近的含义排查动作
reachable当前认为可达继续检查路由、端口或应用,不要仅凭它判定业务正常
stale记录可用但需要再次确认先观察是否在通信后转为可达,避免盲目清空
incomplete解析尚未完成确认接口、二层网络和目标是否存在
failed探测已失败确认范围后刷新,随后继续查二层连通性
permanent/noarp特殊生命周期的静态或免探测项除非明确知道来源,不要纳入批量刷新

因此,看到 stale 时优先关注它是否在真实通信后仍长期不变;看到 failed 时再考虑清掉动态记录,让后续通信重新触发解析。刷新只能清理内核保存的邻居绑定,不能修复错误的 VLAN、交换机端口、网线、ARP 抑制或对端主机状态。

用 ip neigh get 确认目标和接口

批量操作前,先针对一个目标地址和一个接口查询。这样可以避免把默认路由选出的接口误认为你正在排查的接口,也能把“没有这条记录”和“记录处于 failed”区分开。

# 针对指定接口查询一个 IPv4 邻居,不把其它网卡结果混入判断。
ip neigh get 192.0.2.1 dev eth0

# 只列出 eth0 上所有状态,便于对照地址、MAC 和 NUD 字段。
ip neigh show dev eth0 nud all

# 只列出一个目标地址,确认刷新前的精确对象。
ip neigh show to 192.0.2.1 dev eth0 nud all

示例地址 192.0.2.1 只表示文档中的目标占位符,实际操作时替换成你有权限管理的真实地址;eth0 也要替换成实际接口名。不要把文档地址复制到生产环境,也不要用“默认网关一定是某个地址”的假设代替当前路由和接口信息。

如果目标没有记录,可能是主机尚未尝试访问该邻居,也可能是接口、命名空间或地址选择不对;如果记录是 incomplete,说明解析还没完成;如果是 failed,说明内核已经把探测失败记录下来。三者都不能单独证明远端主机一定宕机。

刷新时优先选择最小范围

确认目标后,再用 flush 删除符合条件的邻居项。刷新是删除内核邻居记录,不是“强制让网络恢复”的万能修复。优先按目标地址和网卡限定;只有明确要处理一块接口上的失败项时,才按 nud failed 批量处理。

# 只刷新 eth0 上指定 IPv4 地址的邻居记录。
sudo ip neigh flush to 192.0.2.1 dev eth0

# 只刷新 eth0 上已经失败的动态邻居项。
sudo ip neigh flush dev eth0 nud failed

# 用统计信息记录删除轮次和数量,仍然限定在指定接口。
sudo ip neigh flush dev eth0 nud failed -statistics

ip neigh flush 的筛选参数和 show 相同,可以组合目标前缀、设备和 NUD 状态。没有参数时不会执行刷新;默认也不会把 permanent 和 noarp 当作普通动态项清掉。即便如此,生产操作仍应明确写出 dev 和目标范围,避免依赖默认筛选。

'ip
图2:结构说明图。筛选条件与动态邻居项、permanent 保护边界的关系,用于理解刷新范围,不代表真实执行结果。

刷新后,后续通信可能重新产生邻居解析请求;如果新的记录很快再次变成 failed,问题通常仍在二层路径、接口配置、对端响应或网络隔离,而不是邻居表缓存本身。不要为了“让表变干净”反复刷新,这会掩盖持续故障并增加判断噪声。

空结果和反复失败怎样继续判断

可以把读取结果和下一步动作整理成一张小表。它的作用是约束问题边界:邻居表只能回答地址解析和邻居状态,不能代替路由、端口、应用或链路质量检查。

观察到的现象先确认什么不要直接推出什么
没有目标记录目标地址、接口、命名空间和是否产生过访问不能直接推出远端不可达
incomplete二层广播范围、接口状态和目标是否在线不能直接推出 ARP 被永久阻断
failed刷新范围和二层路径,再观察是否重复失败不能只靠再次 flush 修复故障
stale通信后是否重新确认、是否持续出现不能直接当成失效记录
permanent条目来源和配置责任人不能按动态缓存批量删除

如果排查的是 IPv6,要使用 ip -6 neigh,那是邻居发现协议的记录,不能把 IPv4 ARP 的结论原样套过去。若只看不到进程或接口信息,先确认权限和所在环境;不要为了读取一条邻居状态而扩大到不必要的管理权限。

刷新 stale 会不会导致网络中断?

刷新会删除匹配的邻居记录,后续通信需要重新解析。单条动态记录的刷新范围较小,但它不保证重新解析一定成功;对关键网关或大范围接口操作前,应先确认目标、接口和回退安排。

为什么 flush 后又出现 failed?

这说明新的解析或探测仍未成功。继续确认接口、二层网络、VLAN、对端响应和网络命名空间;反复删除记录只能重置缓存,不能代替修复路径问题。

能不能直接清空整张 ARP 表?

不建议把全表刷新作为第一动作。先用地址、接口和 nud failed 缩小范围,并保护明确配置的 permanent 或 noarp 条目。

记住一条实用顺序:先用 ip -4 neigh show 看记录,再用 ip neigh get 地址 dev 网卡 定位单项,最后用带范围的 ip neigh flush 刷新动态异常。状态决定排查方向,地址和网卡决定操作边界;两者明确后,ARP 邻居异常就不会被误判成单纯的“缓存脏了”。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>