什么时候STALE ARP条目在从未使用时变成FAILED?

root@openwrt:~# ip -s -s -4 neigh show dev lan 10.64.42.121 lladdr b8:20:00:00:00:00 used 6387/6341/6313 probes 1 STALE 10.64.42.157 lladdr b8:20:00:00:00:00 used 24/813/19 probes 1 STALE 10.64.42.12 used 29066/30229/29063 probes 6 FAILED 10.64.42.1 lladdr e8:00:00:00:00:00 ref 1 used 10/5/5 probes 1 REACHABLE root@openwrt:~# cat /proc/sys/net/ipv4/neigh/default/gc_interval 30 root@openwrt:~# cat /proc/sys/net/ipv4/neigh/default/gc_stale_time 60 root@openwrt:~# cat /proc/sys/net/ipv4/neigh/lan/gc_stale_time 60 

局域网中的主机(b8:20:00:00:00:00)IP地址为10.64.42.121。 这个IP现在是无效的,同一个主机的IP现在是10.64.42.157(新的DHCP租约)。

我试图找出旧的ARP高速caching条目何时将状态更改为FAILED( 提供没有人尝试联系IP )。

最后一次入口已被确认为6341s前(1h45前)。 这是大于60年代。 为什么这个条目仍处于STALE状态,何时会变成FAILED状态(或被删除)(如果没有人尝试使用该条目)?

gc_stale_time是调整从ARP表中gc_stale_time STALE项的正确参数。 但还有更多:

ARP垃圾收集在周期性的neigh_periodic_work函数中运行。 间隔可以通过/ proc / sysvariablesgc_interval

然后它将检查ARP表中是否至less有gc_thresh1条目 。 这将避免消耗额外的CPU周期,如果表太小而不能在内存方面看到真正的好处。

在你的情况,我怀疑gc_thresh1是你想要调整的variables。 降低它会迫使GC更频繁地运行。 尽pipe如此,这可能会对性能产生负面影响。

注意: gc_thresh3是一个硬阈值。 这个表永远不会比这个值保留更多的条目。 小心调整它。

Linux内核中的邻居caching并不那么简单。

邻居caching条目实际上完全脱离了caching或仅仅被标记为陈旧/无效。 在base_reachable_time / 2和3 * base_reachable_time / 2之间的某个点上,该条目仍然在caching中,但会被标记为STALE状态。 你应该可以通过“ip -s neighbor show”查看状态。

当处于STALE状态,如上所示,如果我ping 10.64.42.121,它将立即发送数据包到b8:20:00:00:00:00。 第二秒左右,它通常会发送一个ARP请求给谁有10.64.42.121为了更新它的caching回到REACHABLE状态。 但是,为了使事情更加混乱,内核有时会根据来自更高级别协议的正面反馈更改超时值。 这意味着,如果我ping 10.64.42.121并且它回复,那么内核可能不会打扰发送ARP请求,因为它假定pong意味着它的ARPcaching条目是有效的。 如果条目处于STALE状态,那么它也将被它偶然发现的未经请求的ARP回复更新。

现在,大多数情况下,进入STALE状态是所有你需要担心的。 为什么您需要将条目从caching中完全删除? 内核花费了很大的精力,不仅仅是改变caching条目的状态,而不是实际去除caching条目,并且一直将它们添加到caching中。

如果你真的坚持认为它不仅会被标记为STALE,而且实际上会从邻居caching使用的hashmap中被移除,你必须要提防几件事情。 首先,如果条目没有被使用,并且陈旧了gc_stale_time秒,它应该有资格被删除。 如果gc_stale_time传递并标记为可以删除的条目,则在垃圾收集器运行时(通常在gc_interval秒后)将被删除。

现在的问题是, 如果被引用邻居条目不会被删除 。 您将遇到的主要问题是来自ipv4路由表的参考。 有很多复杂的垃圾收集的东西,但重要的是要注意的是,路由caching的垃圾收集器只有每隔5分钟( / proc / sys / net / ipv4 / route / gc_timeout秒)在很多内核。 这意味着邻居条目必须被标记为陈旧(也许30秒,取决于base_reachable_time ),那么在路由caching停止引用入口(如果你幸运的话)之前5分钟将不得不经过,然后是一些组合gc_stale_timegc_interval在实际清理之前通过(总的来说,5-10分钟之间的任何时间都会通过)。

总结:你可以尝试减less/ proc / sys / net / ipv4 / route / gc_timeout到一个更短的值,但是有很多variables,很难控制它们。 通过不过早地删除caching中的条目(而是将它们标记为STALE或甚至失败),有很多努力使得事情performance良好。