ITよろづや

ITの参考になる情報を備忘録代わりに残していきます

Redhat linux,CentOS default arp cache table timeout or flush

Redhat linux,CentOSにおいて、arp cache、arp tableのtimeoutはどれくらいかということが以下に書かれています。

 

arp キャッシュで未使用の近傍 arp エントリーがフラッシュされるまでにどのぐらいかかりますか? - Red Hat Customer Portal

 

まず、IPv4arp フラッシュを制御するカーネルパラメーターがあります。

 

 net.ipv4.neigh.default.gc_interval = 30  
 net.ipv4.neigh.default.gc_stale_time = 60

 

ここが重要です。

 

これは、近傍 arp の生存時間はこの 2 つのパラメーターだけでなく、「ルートキャッシュ」にも依存しています。「ルートキャッシュ」の同じエントリーが削除された場合に限り、arp エントリーがフラッシュされます。

さらに、テストするスクリプトが作成されていますが、「ルートキャッシュ」の近傍エントリーがフラッシュした後に限り、近傍 arp エントリーをフラッシュできます。

したがって、問題となるのは、ルートキャッシュの近傍エントリーがフラッシュされるまでの時間です。

 

ブログやサイトによっては30秒、60秒という内容がありますが、上記が考慮されていないケースですね。

 

 

以下のカーネルパラメーターのいずれかで制御される可能性がありますと書かれています。

 

# sysctl -a | grep route | grep gc | grep ipv4  

 net.ipv4.route.gc_elasticity = 8  
 net.ipv4.route.gc_interval = 60  
 net.ipv4.route.gc_timeout = 300  
 net.ipv4.route.gc\_min\_interval_ms = 500  
 net.ipv4.route.gc\_min\_interval = 0  
 net.ipv4.route.gc_thresh = 32768

 

 

実際に、以下のサイトで質問がありますが、デフォルトのarpキャッシュについて書かれています。

linux - Default arp cache timeout - Server Fault

 

----

ARPエイジのタイムアウトを設定しようとしています。私は、/proc/sys/net/ipv4/neigh/default/base_reachable_time_ms を希望のタイムアウトに設定すべきだと考えています。しかし、これを30000ms(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/2または3*base_reachable_time/2以内にエントリが削除されることはありません。

ARPキャッシュの有効期限を設定するにはどうすればよいでしょうか。

----

 

回答内容の抜粋です。

 

----

Linuxカーネルのネイバーキャッシュは、思ったよりも単純ではありません。ここでは、その奇妙な点を説明してみます。

ネイバーキャッシュのエントリが実際にキャッシュから完全に削除されるのか、単に stale/invalid とマークされるのか、微妙な違いがあります。base_reachable_time/2から3*base_reachable_time/2の間のある時点で、エントリーはまだキャッシュに残っていますが、staleの状態でマークされています。この状態は「ip -s neighbor show」で見ることができるはずです。

 

上図のようにSTALE状態のとき、192.168.42.1にpingを打つと、すぐに00:25:90:7d:7e:cdにパケットを送信します。その約1秒後には、通常、キャッシュを更新して到達可能な状態に戻すために、192.168.42.1を持っている人にARPリクエストを送信します。しかし、さらに分かりにくいことに、カーネルは上位のプロトコルからの肯定的なフィードバックに基づいて、タイムアウトの値を変更することがあります。つまり、192.168.42.1にpingを打ち、それが返ってきた場合、カーネルはわざわざARPリクエストを送信しないかもしれないということです。エントリーがSTALE状態であれば、たまたま目にした未承諾のARPリプライによっても更新されてしまいます。

さて、ほとんどの場合、エントリーがSTALE状態であることを気にする必要はありません。なぜ、エントリーをキャッシュから完全に削除する必要があるのでしょうか?カーネルは、キャッシュエントリを実際に削除したり追加したりするのではなく、キャッシュエントリの状態を変更することで、メモリをスラッシングしないように多大な努力をしています。

STALEとマークされるだけでなく、ネイバーキャッシュで使われているハッシュマップから実際に削除されることを本当に強く主張するなら、いくつかの点に注意しなければなりません。まず、エントリーが使用されておらず、gc_stale_time秒の間staleであれば、削除の対象となります。gc_stale_timeが経過して、エントリーを削除してもよいとマークした場合、ガベージコレクタが実行されたとき(通常はgc_interval秒後)に削除されます。

ここで問題なのは、neighborエントリが参照されている場合、削除されないことです。主に問題となるのは、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とマークする)ことで、良好なパフォーマンスを実現するために多くの努力がなされています。

----

 

よくLinuxARPテーブルが10分前後と書かれているのはこのあたりの内容で理解できます。

 

Anker Soundcore 2 (12W Bluetooth 5 スピーカー 24時間連続再生)【完全ワイヤレスステレオ対応/強化された低音 / IPX7防水規格 / デュアルドライバー/マイク内蔵】(ブラック)