37

我正在尝试配置 ARP 年龄超时。我想我应该设置/proc/sys/net/ipv4/neigh/default/base_reachable_time_ms为所需的超时。但是,尽管我将其设置为 30000 毫秒(30 秒),但从 ARP 缓存中删除一个条目仍需要将近 10 分钟。在阅读了几篇文章后,我发现还有一些设置会影响超时:

/proc/sys/net/ipv4/neigh/default/gc_interval
/proc/sys/net/ipv4/neigh/default/gc_stale_time
/proc/sys/net/ipv4/route/gc_interval
/proc/sys/net/ipv4/route/gc_timeout

我不确定要为这些编程什么。在 Linux中gc_timeout默认为 5 分钟。我将其更改为 30 秒,但我仍然没有看到该条目在base_reachable_time/2or中被删除3*base_reachable_time/2

如何设置 ARP 缓存的过期时间?

4

4 回答 4

99

Linux 内核中的邻居缓存并不像人们想象的那么简单。我将尝试解释它的一些怪癖。

邻居缓存条目实际上完全从缓存中掉出来或只是被标记为陈旧/无效之间存在细微的差异。在base_reachable_time /2 和 3* base_reachable_time /2 之间的某个时间点,该条目仍将在缓存中,但它会被标记为 STALE 状态。您应该可以使用“ip -s neighbor show”查看状态,

pherricoxide@midigaurd:~$ ip -s neighbor list
192.168.42.1 dev eth0 lladdr 00:25:90:7d:7e:cd ref 2 used 184/184/139 probes 4 STALE
192.168.10.2 dev eth0 lladdr 00:1c:23:cf:0b:6a ref 3 used 33/28/0 probes 1 REACHABLE
192.168.10.1 dev eth0 lladdr 00:17:c5:d8:90:a4 ref 219 used 275/4/121 probes 1 REACHABLE

当处于 STALE 状态时,如果我 ping 192.168.42.1,它将立即将数据包发送到 00:25:90:7d:7e:cd。大约一秒钟后,它通常会向拥有 192.168.42.1 的人发送 ARP 请求,以便将其缓存更新回 REACHABLE 状态。但是,为了让事情更加混乱,内核有时会根据来自更高级别协议的积极反馈来更改超时值。这意味着如果我 ping 192.168.42.1 并且它回复了,那么内核可能不会打扰发送 ARP 请求,因为它假设 pong 意味着它的 ARP 缓存条目是有效的。如果条目处于 STALE 状态,它也将被它碰巧看到的未经请求的 ARP 回复更新。

现在,对于大多数情况,您只需要担心处于 STALE 状态的条目。为什么需要将条目从缓存中完全删除?内核通过仅仅改变缓存条目的状态而不是实际删除它们并将它们添加到缓存中来付出很多努力来不破坏内存。

如果你真的坚持它不仅会被标记为 STALE,而且实际上会从邻居缓存使用的 hashmap 中删除,那么你必须注意一些事情。首先,如果条目没有被使用并且在gc_stale_time秒内是陈旧的,它应该有资格被删除。如果gc_stale_time已通过并将条目标记为可以删除,则它将在垃圾收集器运行时删除(通常在gc_interval秒之后)。

现在的问题是,如果邻居条目被引用,它不会被删除。您将遇到的主要问题是来自ipv4 路由表的引用。有很多复杂的垃圾收集东西,但需要注意的重要一点是,路由缓存的垃圾收集器仅在很多内核上每 5 分钟( /proc/sys/net/ipv4/route/gc_timeout秒)使条目过期. 这意味着必须将邻居条目标记为过时(可能需要 30 秒,具体取决于base_reachable_time),然后在路由缓存停止引用该条目之前必须经过 5 分钟(如果幸运的话),然后是某种组合gc_stale_time和_gc_interval在它实际被清理之前通过(因此,总的来说,5-10 分钟之间的某个地方会过去)。

总结:您可以尝试将/proc/sys/net/ipv4/route/gc_timeout 减小到更短的值,但是变量很多,很难全部控制。通过不过早地删除缓存中的条目(而只是将它们标记为 STALE 甚至 FAILED),我们付出了很多努力来使事情表现良好。

于 2013-03-19T21:47:06.873 回答
3
ip link set arp off dev eth0; ip link set arp on dev eth0
于 2016-04-21T23:03:36.107 回答
0

这是我设置的:

sudo -s then enter:

echo 30 > /proc/sys/net/ipv4/neigh/default/gc_stale_time
echo 175 > /proc/sys/net/ipv4/route/gc_timeout
echo 20000 > /proc/sys/net/ipv4/neigh/default/base_reachable_time_ms
echo 30 > /proc/sys/net/ipv4/route/gc_interval
于 2021-03-03T02:20:15.943 回答
0

彻底清除 arp 缓存的最简单方法是关闭接口,然后再启动。显然,这有更多的含义,例如,可能会中断正在进行的 TCP 连接,暂时无法访问等。但这似乎是真正从最新内核中的 arp 缓存中删除条目的唯一方法:(

于 2015-10-23T08:26:24.100 回答