ARP(7) | Linux Programmer's Manual | ARP(7) |
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 の単位は秒である。
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/ に書かれている。
2020-08-13 | Linux |