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
LAN(b8:20:00:00:00:00)内のホストのIPアドレスは10.64.42.121でした。このIPは無効になり、この同じホストのIPは10.64.42.157(新しいDHCPリース)になります。
古いarpキャッシュエントリの状態がいつFAILEDに変わるかを調べようとします(だれもIPに接続しようとしない場合)。
エントリが最後に確認されたのは6341秒前(1時間45分前)です。これは60秒を超えています。なぜこのエントリがまだSTALE状態であり、いつFAILED状態に変わる(または削除される)か(誰もいない場合)これまでにエントリを使用しようとします)?
gc_stale_time
は、TweakがARPテーブルからSTALEエントリを削除するための正しいパラメータです。しかし、もっとあります:
ARPガベージコレクションは、定期的な neigh_periodic_work
関数で実行されます。間隔は、/ proc/sys変数gc_interval
を介して調整できます。
次に、 ARPテーブルに少なくともgc_thresh1
エントリ があることを確認します。これにより、テーブルが小さすぎてメモリの点で実際のメリットが見られない場合に、余分なCPUサイクルを消費することがなくなります。
あなたの場合、私はgc_thresh1
が調整したい変数であると思います。それを下げると、GCがより頻繁に実行されるようになります。ただし、実行間隔によっては、パフォーマンスに悪影響を与える可能性があります。
注:gc_thresh3
はハードしきい値です。テーブルは、この値を超えるエントリを保持することはありません。慎重に調整してください。
Linuxカーネルのネイバーキャッシュはそれほど単純ではありません。
ネイバーキャッシュエントリが実際に完全にキャッシュから脱落するか、古くなった/無効であるとマークされているだけの場合、微妙な違いがあります。 base_reachable_time/ 2と3 *base_reachable_time/ 2の間のある時点で、エントリはまだキャッシュにありますが、 STALEの状態でマークされている。 「ip -s neighbor show」で状態を表示できるはずです。
上記のようにSTALE状態のときに10.64.42.121にpingを送信すると、パケットはすぐにb8:20:00:00:00:00に送信されます。 2番目以降に、キャッシュを更新してREACHABLE状態に戻すために、通常10.64.42.121を持っているユーザーにARP要求を送信します。しかし、問題をさらに混乱させるために、カーネルは、より高いレベルのプロトコルからの肯定的なフィードバックに基づいて、タイムアウト値を変更することがあります。つまり、10.64.42.121に対してpingを実行して応答すると、カーネルはARP要求の送信を邪魔しない可能性があります。これは、ポンがARPキャッシュエントリが有効であることを意味すると想定しているためです。エントリがSTALE状態にある場合、たまたま確認した一方的なARP応答によって更新されます。
今、ほとんどの場合、心配する必要があるのはSTALE状態のエントリだけです。エントリをキャッシュから完全に削除する必要があるのはなぜですか?カーネルは、実際にキャッシュエントリを常に削除して追加するのではなく、キャッシュエントリの状態を変更するだけでメモリをスラッシュしないように多くの努力をしています。
STALEとしてマークされるだけでなく、ネイバーキャッシュによって使用されるハッシュマップから実際に削除されることを本当に強く主張する場合は、いくつかのことに注意する必要があります。まず、エントリが使用されておらず、gc_stale_time秒間古くなっている場合、削除する資格があります。 gc_stale_timeが渡され、エントリを削除してもよいとマークした場合、ガベージコレクターの実行時に削除されます(通常gc_intervalの後で)。秒)。
近隣エントリが参照されている場合、それが削除されないことが問題です。問題が発生する主なものは、 ipv4ルーティングテーブル からの参照です。複雑なガベージコレクションの要素はたくさんありますが、ルートキャッシュのガベージコレクタは5分(/ proc/sys/net/ipv4/route/gc_timeout 秒)多くのカーネルで。これは、ネイバーエントリを古いものとしてマークする必要があることを意味します(base_reachable_timeによっては30秒程度)。その後、ルートキャッシュがエントリの参照を停止するまでに5分かかる必要があります。 (運がよければ)、その後にgc_stale_timeとgc_intervalのいくつかの組み合わせが続き、実際にクリーンアップされます(そう、全体として、5〜10分程度の時間が経過します)。
概要:/ proc/sys/net/ipv4/route/gc_timeoutをより短い値に減らすことを試みることができますが、多くの変数があり、それらすべてを制御することは困難です。キャッシュ内のエントリを早めに削除しないようにして、パフォーマンスを向上させるために多くの労力が費やされています(代わりに、それらをSTALEまたはFAILEDとしてマークするだけです)。
関数neigh_periodic_work
には、以下のコードがあります。
if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
goto out;
out:
/* Cycle through all hash buckets every BASE_REACHABLE_TIME/2 ticks.
* ARP entry timeouts range from 1/2 BASE_REACHABLE_TIME to 3/2
* BASE_REACHABLE_TIME.
*/
schedule_delayed_work(&tbl->gc_work,
NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME) >> 1);
write_unlock_bh(&tbl->lock);
ネイバーの数がgc_thresh1未満の場合、goto outを実行すると、gcのタスクが遅延するため、STALEおよびFAILEDネイバーテーブルを削除できません。/proc/sys/net/ipv4/neigh/default/gc_thresh1
の値を変更できます。カーネルのデフォルトは128 3.10.0-327.36.3
Kernel.orgのドキュメントは、
route/max_size - INTEGER
Maximum number of routes allowed in the kernel. Increase
this when using large numbers of interfaces and/or routes.
From linux kernel 3.6 onwards, this is deprecated for ipv4
as route cache is no longer used.
/proc/sys/net/ipv4/route/gc_timeout
はネイテーブルとは意味がかなり異なり、ルートキャッシングはip4で使用されなくなりました。 sysctl net.ipv4.route.gc_thresh
を実行すると、-1
に設定されていることがわかります。