【问题标题】:Configuring ARP age timeout [closed]配置 ARP 年龄超时 [关闭]
【发布时间】:2013-02-28 14:27:44
【问题描述】:

我正在尝试配置 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

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

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

【问题讨论】:

    标签: linux linux-kernel arp


    【解决方案1】:

    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 routing table 的参考。有很多复杂的垃圾收集东西,但需要注意的重要一点是,路由缓存的垃圾收集器每 5 分钟才会使条目过期(/proc/sys/net/ipv4/route/gc_timeout秒)在很多内核上。这意味着必须将邻居条目标记为过时(可能需要 30 秒,具体取决于 base_reachable_time),然后在路由缓存停止引用该条目之前必须经过 5 分钟(如果您是幸运),然后是 gc_stale_timegc_interval 的某种组合,然后才真正清理干净(因此,总的来说,大约需要 5-10 分钟)。

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

    【讨论】:

    • 这一切都很有趣,但我敢问:为什么没有办法手动强制清理缓存?我知道这会使系统性能不佳,但是通过手动清理,您已经为此做好了准备。相反,我知道清除 arp 缓存 (sudo ip -s -s neigh flush all) 的唯一方法会将条目标记为无效,但不会将它们从缓存中删除。这是非常违反直觉的。 IMO,应该有一个标志告诉系统“真正清理缓存,我负责从现在开始发生的任何问题”。
    • arp -d <ip_address 将删除特定条目
    【解决方案2】:
    ip link set arp off dev eth0; ip link set arp on dev eth0
    

    【讨论】:

    • 如果您打算关闭,然后向上接口 - 并且它是您连接到主机的接口,那么请确保在按 Enter 之前将命令链接到同一行! (更好的是,从屏幕会话中执行...)
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这是我设置的:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-20
        • 2017-08-28
        • 2013-07-24
        • 2014-12-15
        • 2012-12-19
        • 2015-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多