kazmax - Linux で自宅サーバー

arp - 約束事その他の説明 - Linux コマンド集 一覧表

  1. 名前
  2. 説明
  3. IOCTL
  4. SYSCTL
  5. バグ
  6. バージョン
  7. 関連項目

名前

arp - Linux ARP カーネルモジュール

説明

このカーネルプロトコルモジュールは、 RFC826 で定義されている Address Resolution Protocol を 実装したものである。 ARP は、ダイレクトに接続されたネットワーク上で、 第 2 層のハードウェアアドレスをIPv4 プロトコルアドレスに 変換するために用いられる。ユーザーは設定の場合を除いて 通常直接このモジュールに関ることはない。 これはカーネル内部の他のプロトコルにサービスを提供するものである。

ユーザープロセスは、   packet (7) ソケットを用いれば ARP パケットを受信することができる。 ARP キャッシュをユーザー空間で管理することもできる。 これには   netlink (7) を用いる。 ARP テーブルも制御可能で、これには任意の PF_INET ソケットに   ioctl (2) を用いる。

ARP モジュールはハードウェアアドレスからプロトコルアドレスへの マッピングのキャッシュを管理する。キャッシュの大きさには制限が あるので、古いエントリや利用されないエントリはガベージコレクト される。 permanent (保存) マークがつけられたエントリは、 決してガベージコレクタによって消去されない。 ioctl を用いればキャッシュを直接操作することもできる。 また以下に定義しているような sysctl を用いれば キャッシュの振る舞いを変更できる。

存在しているマッピングに対して、 正のフィードバックが一定時間ない (以下の sysctl を見よ) と、 近傍キャッシュエントリ (neighbour cache entry) は 古くなった (stale) とみなされる。 正のフィードバックは高位のレイヤーからも取得できる (例えば TCP ACK が成功した場合など)。 他のプロトコルは、 sendmsg (2)に MSG_CONFIRM フラグを用いることによって、 フォワードプログレス (forward progress) をシグナルできる。 フォワードプログレスがなければ、 ARP は再びプローブを試みる。 まずローカルな arp デーモンに問合わせを行い、 更新された MAC アドレスを取得しようとする。 このリクエストに app_solicit 回失敗すると、古い MAC アドレスがわかっている場合は、 unicast のプローブが ucaset_solicit 回送られる。これにも失敗すると、新しい ARP リクエスト をネットワークにブロードキャストする。 リクエストは、データが送信キューになければ送られない。

Linux は、あるアドレスへのリクエストを受信・フォワードし、 受信したインターフェースで代理 arp が有効になっている場合には、 自動的にそのアドレスを non-permanent な代理 arp エントリに追加する。 そのターゲットに reject route があった場合には、 代理 arp エントリは一切追加されない。

IOCTL

すべての PF_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_paAF_INET ソケットでなければならず、 arp_haarp_dev で設定されたデバイスと同じタイプでなければならない。 arp_dev はデバイスの名前を示す、ゼロで終端された文字列である。

arp_flags
フラグ意味
ATF_COM参照完了
ATF_PERMエントリを peramanent にする
ATF_PUBLエントリを publish する
ATF_USETRAILERStrailer が必要
ATF_NETMASKnetmask を用いる
ATF_DONTPUB回答しない

ATF_NETMASK フラグがセットされているときには、 arp_netmask が有効でなければならない。 Linux 2.2 は代理ネットワーク ARP エントリをサポートしていないので、 これは 0xffffffff にセットしておくか、あるいは 現存の代理 arp エントリを削除したい場合には 0 にしておく必要がある。 ATF_USETRAILERS は obsolete なので、用いるべきでない。

SYSCTL

ARP では、グローバルなパラメータやインターフェースごとのパラメータを sysctl を通して設定することができる。 これらの sysctl へアクセスするには、 proc/sys/net/ipv4/neigh/*/* ファイルを読み書きする方法と、インターフェースに対して   sysctl (2) を用いる方法がある。 システムにあるそれぞれのインターフェースには、 それぞれ対応するディレクトリが /proc/sys/net/ipv4/neigh/ 以下にある。 `default' ディレクトリに対して設定をすると、 それ以降生成されるデバイス全てに対してその設定が用いられる。 特に指定がなければ、 時間に関る sysctl の単位は秒である。

anycast_delay
IPv6 の近傍要請メッセージ (neighbour soliciation message) に応答するまでの最大遅延時間 (jiffy 単位)。 anycast のサポートはまだ実装されていない。 デフォルトは 1 秒。
app_solicit
ユーザー空間の ARP デーモンに netlink を用いて探索させる最大回数。 これを越えるとマルチキャストによる探索に移行する ( mcast_solicit を見よ)。
base_reachable_time
近傍のホストがみつかると、そのエントリは base_reachable_time /2 から 3* base_reachable_time /2の間のランダムな値の時間、有効であるとみなされる。 エントリの有効性は、高位のプロトコルからポジティブなフィードバックを 受け取ると延長される。デフォルトは 30 秒。
delay_first_probe_time
近傍ホストのエントリが古くなったと判断された後に 最初に探索を行うまでの遅延時間。デフォルトは 5 秒。
gc_interval
ガベージ・コレクタを近傍ホストエントリに対して実行させる頻度。 デフォルトは 30 秒。
gc_stale_time
古くなった近傍ホストエントリに対してチェックを行う頻度。 近傍ホストエントリが古くなったとみなされると、そのエントリに データを送る前には再度解決が行われる。 デフォルトは 60 秒。
gc_thresh1
ARP キャッシュに保存するエントリ数の最小値。 この数より少ないエントリしかキャッシュになければ、 ガベージ・コレクタは実行されない。 デフォルトは 128。
gc_thresh2
ARP キャッシュに保存されるエントリ数のソフトな最大値。 キャッシュのエントリがこの数を 5 秒間越えつづけると、 ガベージ・コレクタが実行される。 デフォルトは 512。
gc_thresh3
ARP キャッシュに保存されるエントリ数のハードな最大値。 キャッシュのエントリがこの数を越えると、 ガベージ・コレクタはただちに実行される。 デフォルトは 1024。
locktime
ARP エントリをキャッシュに保存する時間の最小値 (jiffy 単位)。 可能性のあるマッピングが一つ以上ある (たいていはネットワーク設定のミス) 場合に、 ARP キャッシュのスラッシングが起きることを防ぐ。 デフォルトは 1 秒。
mcast_solicit
エントリを unreachable マークする前に、 アドレスをマルチキャスト/ブロードキャストで解決しようとする 試行回数の最大値。 デフォルトは 3。
proxy_delay
既知の代理 ARP アドレスに対して ARP リクエストを受信した場合に、 応答前に最大 proxy_delay jiffy まで遅延する。これは場合によって生じる ネットワーク・フラッディング (network flooding) を避けるために用いる。 デフォルトは 0.8 秒。
proxy_qlen
代理 ARP アドレスに対してキューイングできる最大のパケット数。 デフォルトは 64。
retrans_time
リクエストを再度送るまでの遅延時間 (jiffy 単位)。 デフォルトは 1 秒。
ucast_solicit
ARP デーモンへの問い合わせを行う前に行う unicast 探索の最大試行数 (app_solicitを見よ)。デフォルトは 3。
unres_qlen
解決されていないアドレスに対して、 他のネットワーク層からキューイングできる最大パケット数。 デフォルトは 3。

バグ

タイマー設定に、アーキテクチャ依存な jiffy を用いているものがある。 Alpha では jiffy は 1/1024 秒であり、その他の多くのアーキテクチャでは 1/100 秒である。

ユーザー空間からポジティブなフィードバックを送る方法が存在しない。 つまり接続指向 (connection oriented) のプロトコルをユーザー空間で 実装すると、余計な ARP トラフィックの原因となる。 なぜなら ndisc は定期的に MAC アドレスを再探索するからである。 同様の問題はいくつかのカーネルプロトコル (NFS over UDP など) にも存在する。

この man ページでは IPv4 特有の機能と IPv4・IPv6 で共有される機能とがごっちゃになっている。

バージョン

Linux 2.0 で、 struct arpreqarp_dev メンバーが含まれるように変更があった。また同時に ioctl 番号も変更された。古い ioctl は Linux 2.2 で用いることができなくなった。
ネットワークに対する代理 arp エントリ (netmask が 0xffffffff でない) は、 Linux 2.2 で用いることができなくなった。 これはカーネルによって設定される、別のインターフェースにおける 到達可能なすべてのホストに対する自動代理 arp によって置き換えられた (そのインターフェースでフォワーディングと代理 arp が有効になっている場合)。
各 neigh/* sysctl は Linux 2.2 以前には存在しない。

関連項目

  capabilities (7),   ip (7) 

RFC 826 : ARP に関する説明
RFC 2461 : IPv6 neighbour discovery に関する説明と、 利用されている基礎アルゴリズム

Linux 2.2 以降の IPv4 ARP は、 可能な場合は IPv6 のアルゴリズムを用いる。