arp - Linux ARP
カーネルモジュール
このカーネルプロトコルモジュールは、
RFC 826
で定義されている Address
Resolution Protocol を
実装したものである。
ARP
は、ダイレクトに接続されたネットワーク上で、
第 2
層のハードウェアアドレスをIPv4
プロトコルアドレスに
変換するために用いられる。ユーザーは設定の場合を除いて
通常直接このモジュールに関ることはない。
これはカーネル内部の他のプロトコルにサービスを提供するものである。
ユーザープロセスは、
packet(7)
ソケットを用いれば ARP
パケットを受信することができる。
ARP
キャッシュをユーザー空間で管理することもできる。
これには
netlink(7)
を用いる。 ARP
テーブルも制御可能で、これには任意の
AF_INET ソケットに
ioctl(2)
を用いる。
ARP
モジュールはハードウェアアドレスからプロトコルアドレスへの
マッピングのキャッシュを管理する。キャッシュの大きさには制限が
あるので、古いエントリーや利用されないエントリーはガベージコレクト
される。 permanent (保存)
マークがつけられたエントリーは、
決してガベージコレクタによって消去されない。
ioctl
を用いればキャッシュを直接操作することもできる。
また後述の
/proc
インターフェースによりキャッシュの振る舞いを調整できる。
存在しているマッピングに対して、
正のフィードバックが一定時間ない
(後述の
/proc
インターフェースを見よ)
と、
近傍キャッシュエントリー
(neighbor cache entry) は 古くなった
(stale) とみなされる。
正のフィードバックは高位のレイヤーからも取得できる
(例えば TCP ACK
が成功した場合など)。
他のプロトコルは、
sendmsg(2) に
MSG_CONFIRM
フラグを用いることによって、
フォワードプログレス
(forward progress)
をシグナルできる。
フォワードプログレスがなければ、
ARP
は再びプローブを試みる。
まずローカルな arp
デーモンに問合わせを行い、
更新された MAC
アドレスを取得しようとする。
このリクエストに
app_solicit
回失敗すると、古い MAC
アドレスがわかっている場合は、
unicast のプローブが
ucaset_solicit
回送られる。これにも失敗すると、新しい
ARP リクエスト
をネットワークにブロードキャストする。
リクエストは、データが送信キューにある場合のみ送られる。
Linux
は、あるアドレスへのリクエストを受信・フォワードし、
受信したインターフェースで代理
arp
が有効になっている場合には、
自動的にそのアドレスを
nonpermanent な代理 arp
エントリーに追加する。
そのターゲットに reject route
があった場合には、
代理 arp
エントリーは一切追加されない。
すべての
AF_INET
ソケットでは、 3 つの
ioctl が使用できる。
これらは
struct arpreq
へのポインターを引数に取る。
struct arpreq {
struct sockaddr arp_pa; /* protocol address */
struct sockaddr arp_ha; /* hardware address */
int arp_flags; /* flags */
struct sockaddr arp_netmask; /* netmask of protocol address */
char arp_dev[16];
};
SIOCSARP,
SIOCDARP,
SIOCGARP
は、それぞれ ARP
マッピングを設定・削除・取得する。
ARP
マップの設定と削除は特権が必要な操作であり、
CAP_NET_ADMIN
権限を持つプロセスか、実行ユーザー
ID が 0 のプロセス
でなければ実行できない。
arp_pa は
AF_INET
アドレスでなければならず、
arp_ha は
arp_dev
で設定されたデバイスと同じタイプでなければならない。
arp_dev
はデバイスの名前を示す、ゼロで終端された文字列である。
arp_flags |
|
フラグ |
意味 |
ATF_COM |
参照完了 |
ATF_PERM |
エントリーを peramanent
にする |
ATF_PUBL |
エントリーを publish
する |
ATF_USETRAILERS |
trailer が必要 |
ATF_NETMASK |
netmask を用いる |
ATF_DONTPUB |
回答しない |
ATF_NETMASK
フラグがセットされているときには、
arp_netmask
が有効でなければならない。
Linux 2.2
は代理ネットワーク ARP
エントリーをサポートしていないので、
これは 0xffffffff
にセットしておくか、あるいは
現存の代理 arp
エントリーを削除したい場合には
0
にしておく必要がある。
ATF_USETRAILERS は obsolete
なので、用いるべきでない。
ARP
では、グローバルなパラメーターやインターフェースごとのパラメーターを
/proc
インターフェースを通して設定することができる。
これらのインターフェースには、
proc/sys/net/ipv4/neigh/*/*
ファイルの読み書きによりアクセスできる。
システムにあるそれぞれのインターフェースには、
それぞれ対応するディレクトリが
/proc/sys/net/ipv4/neigh/
以下にある。 "default"
ディレクトリに対して設定をすると、
それ以降生成されるデバイス全てに対してその設定が用いられる。
特に指定がなければ、時間に関る
sysctl
の単位は秒である。
-
anycast_delay (Linux 2.2 以降)
- IPv6
の近傍要請メッセージ
(neighbor soliciation message)
に応答するまでの最大遅延時間
(jiffy 単位)。 anycast
のサポートはまだ実装されていない。
デフォルトは 1 秒。
-
app_solicit (Linux 2.2 以降)
- ユーザー空間の
ARP デーモンに netlink
を用いて探索させる最大回数。
これを越えるとマルチキャストによる探索に移行する
( mcast_solicit を見よ)。
-
base_reachable_time (Linux 2.2
以降)
- 近傍のホストがみつかると、そのエントリーは
base_reachable_time/2 から
3*base_reachable_time/2
の間のランダムな値の時間、有効であるとみなされる。
エントリーの有効性は、高位のプロトコルからポジティブなフィードバックを
受け取ると延長される。デフォルトは
30 秒。
このファイルは現在は非推奨であり、代わりに
base_reachable_time_ms
を使うこと。
-
base_reachable_time_ms (Linux 2.6.12
以降)
-
base_reachable_time
と同じだが、時間をミリ秒単位で測る。
デフォルトは 30000
ミリ秒である。
-
delay_first_probe_time (Linux 2.2
以降)
- 近傍ホストのエントリーが古くなったと判断された後に
最初に探索を行うまでの遅延時間。デフォルトは
5 秒。
-
gc_interval (Linux 2.2 以降)
- ガベージコレクタを近傍ホストエントリーに対して実行させる頻度。
デフォルトは 30 秒。
-
gc_stale_time (Linux 2.2 以降)
- 古くなった近傍ホストエントリーに対してチェックを行う頻度。
近傍ホストエントリーが古くなったとみなされると、そのエントリーに
データを送る前には再度解決が行われる。
デフォルトは 60 秒。
-
gc_thresh1 (Linux 2.2 以降)
- ARP
キャッシュに保存するエントリー数の最小値。
この数より少ないエントリーしかキャッシュになければ、
ガベージコレクタは実行されない。
デフォルトは 128。
-
gc_thresh2 (Linux 2.2 以降)
- ARP
キャッシュに保存されるエントリー数のソフトな最大値。
キャッシュのエントリーがこの数を
5
秒間越えつづけると、
ガベージコレクタが実行される。
デフォルトは 512。
-
gc_thresh3 (Linux 2.2 以降)
- ARP
キャッシュに保存されるエントリー数のハードな最大値。
キャッシュのエントリーがこの数を越えると、
ガベージコレクタはただちに実行される。
デフォルトは 1024。
-
locktime (Linux 2.2 以降)
- ARP
エントリーをキャッシュに保存する時間の最小値
(jiffy 単位)。
可能性のあるマッピングが一つ以上ある
(たいていはネットワーク設定のミス)
場合に、 ARP
キャッシュのスラッシングが起きることを防ぐ。
デフォルトは 1 秒。
-
mcast_solicit (Linux 2.2 以降)
- エントリーを
unreachable
マークする前に、
アドレスをマルチキャスト/ブロードキャストで解決しようとする
試行回数の最大値。
デフォルトは 3。
-
proxy_delay (Linux 2.2 以降)
- 既知の代理 ARP
アドレスに対して ARP
リクエストを受信した場合に、
応答前に最大 proxy_delay jiffy
まで遅延する。これは場合によって生じる
ネットワークフラッディング
(network flooding)
を避けるために用いる。
デフォルトは 0.8 秒。
-
proxy_qlen (Linux 2.2 以降)
- 代理 ARP
アドレスに対してキューイングできる最大のパケット数。
デフォルトは 64。
-
retrans_time (Linux 2.2 以降)
- リクエストを再度送るまでの遅延時間
(jiffy 単位)。
デフォルトは 1 秒。
このファイルは現在は非推奨であり、代わりに
retrans_time_ms
を使うこと。
-
retrans_time_ms (Linux 2.6.12 以降)
- リクエストを再度送るまでの遅延時間
(ミリ秒単位)。
デフォルトは 1000
ミリ秒。
-
ucast_solicit (Linux 2.2 以降)
- ARP
デーモンへの問い合わせを行う前に行う
unicast 探索の最大試行数 (
app_solicit
を見よ)。デフォルトは
3。
-
unres_qlen (Linux 2.2 以降)
- 解決されていないアドレスに対して、
他のネットワーク層からキューイングできる最大パケット数。
デフォルトは 3。
Linux 2.0 で、
struct arpreq に
arp_dev
メンバーが含まれるように変更があった。また同時に
ioctl
番号も変更された。古い
ioctl は Linux 2.2
で用いることができなくなった。
ネットワークに対する代理
arp エントリー (netmask が 0xffffffff
でない) は、 Linux 2.2
で用いることができなくなった。
これはカーネルによって設定される、別のインターフェースにおける
到達可能なすべてのホストに対する自動代理
arp
によって置き換えられた
(そのインターフェースでフォワーディングと代理
arp
が有効になっている場合)。
neigh/*
の各インターフェースは
Linux 2.2
以前には存在しない。
いくつかのタイマー設定は
jiffy で指定されるが、 jiffy
はアーキテクチャーやカーネルのバージョンに依存する。
time(7) を参照のこと。
ユーザー空間からポジティブなフィードバックを送る方法が存在しない。
つまり接続指向 (connection-oriented)
のプロトコルをユーザー空間で
実装すると、余計な ARP
トラフィックの原因となる。
なぜなら ndisc
は定期的に MAC
アドレスを再探索するからである。
同様の問題はいくつかのカーネルプロトコル
(NFS over UDP など)
にも存在する。
この man ページでは IPv4
特有の機能と IPv4 とIPv6
で共通の機能を一緒に説明している。
capabilities(7),
ip(7),
arpd(8)
RFC 826: ARP の説明。 RFC 2461: IPv6
neighbor discovery
の説明と利用されている基礎アルゴリズム。
Linux 2.2 以降では IPv4 ARP
は可能な場合は IPv6
アルゴリズムを使っている。
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。