在我的 Arch Linux 的最后几次启动中,我注意到我无法访问网络。我使用netctl
配置文件为我的适配器提供静态 IPv4 地址,该地址本身工作正常。
于是我查看了日志,错误是:
接口“enp0s25”上的重复地址检测花费的时间太长
netctl
然后使用 code 退出1
,使网络处于未配置状态。
重复地址检测是 IPv6 的一项功能,netctl
当配置文件包含以下行时使用它:
IPv6=stateless
应该会自动配置 IPv6。有人打开一个关于这个的问题在 Github 项目上,作者netctl
声称:
[...] 如果 DAD 花费超过 3 秒(默认值),则说明您的网络可能非常复杂或缓慢,或者配置错误。
和:
听起来您的网络中的某些内容配置不正确。 [...]
但是,我的网络究竟出了什么问题?这是一个非常简单的基础设施,只有我的 ISP 的调制解调器/路由器组合,上面有 2 台 PC、少量无线设备和一些数字电视机顶盒。我家的网络质量总体来说非常好,问题是几周前才开始出现的。
当前的解决方法是禁用 DAD 或增加超时,这两种方法我都不喜欢。
答案1
DAD 本质上很慢,因为它必须在没有反馈的情况下工作。
DAD 的工作方式是,在接口上激活地址之前,会发送邻居发现请求,询问具有该 IP 地址的主机的 MAC 地址。
如果地址重复,已有该地址的主机将会响应,并且 DAD 将很快失败。
但是,当地址配置正确时,就不会出现重复,因此请求不会得到答复。
由于发件人无法知道回复的速度有多快,因此必须等待。 DAD 完成的速度取决于发送方配置为等待回复的时间。
值得注意的是,它仅取决于请求发送方的配置,而不取决于网络其余部分的配置方式。任何认为复杂的网络会减慢 DAD 速度的人可能还没有理解它是如何工作的。
可以将机器配置为发送多个请求,中间有延迟,并且仅在经过一定秒数而没有回复后才分配地址。这样的配置显然会减慢DAD的速度。
将 IP 地址分配给接口的系统调用不会阻止等待 DAD 完成。但是,如果您在 DAD 完成之前继续尝试将套接字绑定到该地址,则会失败。这可能会导致竞争条件,导致服务在引导期间无法启动。您看到的错误消息可能是由一段代码生成的,该代码旨在等待 DAD 完成以避免此类竞争条件。此类代码中很容易引入的一个错误是让它继续等待 DAD 完成,而实际上 DAD 由于地址重复而已经失败。
在某些情况下,处理 DAD 引起的问题的最佳方法是简单地禁用 DAD。但是,您当然应该首先验证您实际上没有重复的地址。如果您确实有重复的地址,那么启用、禁用或重新配置 DAD 并不能解决您的问题。
如果您的系统应该是某个 IP 地址的唯一合法用户,并且某个其他节点正在响应该 IP 的 ND 请求,那么您面临的问题是 ND 欺骗,这是您需要解决的第一个问题。
但是,如果您的情况是动态配置 IP 地址并且 IP 地址可以由多个节点中的任何一个合法声明,那么使用 DAD 可以帮助避免冲突,因此不应禁用。