Provided by: manpages-ja_0.5.0.0.20140515+dfsg-2_all
名前
netlink - カーネルとユーザー空間の通信 (AF_NETLINK)
書式
#include <asm/types.h> #include <sys/socket.h> #include <linux/netlink.h> netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);
説明
netlink はカーネルモジュールとユーザー空間のプロセス間で 情報をやりとりするために用いられ る。 netlink は、ユーザープロセスに対しては 標準的なソケットベースのインターフェースを、 カーネルモジュールにはカーネルの内部 API を提供する。 カーネル内部のインターフェースについ てはこの man ページでは記述しない。 また、netlink キャラクタデバイスを用いた obsolete な netlink インターフェースもあるが、これもこの文書では解説しない。 これは過去互換性のためだ けに用意されている。 netlink はデータグラム指向のサービスである。 socket_type には SOCK_RAW と SOCK_DGRAM の両 方とも指定可能である。 しかし netlink プロトコルはデータグラムと raw ソケットの区別をしな い。 netlink_family は、通信するカーネルモジュールや netlink グループの選択に用いる。 現在割り 当てられている netlink ファミリーは以下の通り。 NETLINK_ROUTE ルーティングとリンクの更新を受信する。 (IPv4 と IPv6 両方の) ルーティングテーブル・ IP アドレス・リンクパラメータ・近傍設定 (neighbor setup)・ キューイングルール (queueing dicipline)・トラフィッククラス・ パケットのクラス分類の修正に用いることが できるだろう (rtnetlink(7) を見よ)。 NETLINK_W1 単線 (1-wire) のサブシステムからのメッセージ。 NETLINK_USERSOCK ユーザーモードソケットプロトコルのために予約されている。 NETLINK_FIREWALL IPv4 パケットを netfilter からユーザー空間へ転送する。 ip_queue カーネルモジュール で使用される。 NETLINK_INET_DIAG INET ソケットをモニタリングする。 NETLINK_NFLOG Netfilter/iptables ULOG. NETLINK_XFRM IPsec. NETLINK_SELINUX SELinux のイベント通知。 NETLINK_ISCSI Open-iSCSI. NETLINK_AUDIT 監査 (audit) を行う。 NETLINK_FIB_LOOKUP ユーザー空間から FIB ルックアップにアクセスする。 NETLINK_CONNECTOR カーネルコネクタ。より詳しい情報は Linux カーネルソースの Documentation/connector/* を参照すること。 NETLINK_NETFILTER netfilter サブシステム。 NETLINK_IP6_FW IPv6 パケットを netfilter からユーザー空間へ転送する。 ip6_queue カーネルモジュール で使用される。 NETLINK_DNRTMSG DECnet ルーティングメッセージ。 NETLINK_KOBJECT_UEVENT ユーザー空間へのカーネルメッセージ NETLINK_GENERIC netlink を簡単に使用するための一般的な netlink ファミリー。 netlink メッセージはバイトストリームからなり、 一つ以上の nlmsghdr ヘッダと、それに対応す るペイロード (payload) が含まれる。 バイトストリームには、標準の NLMSG_* マクロによっての みアクセスすべきである。 より詳しい情報は netlink(3) を見よ。 マルチパートメッセージ (一つ以上の nlmsghdr ヘッダと、それに対応するペイロードが 一つバイ トストリームに含まれる) においては、 先頭のヘッダ・後続のヘッダには NLM_F_MULTI フラグが セットされる。ただし最後のヘッダだけは例外で、 NLMSG_DONE タイプとなる。 それぞれの nlmsghdr の後にはペイロードが続く。 struct nlmsghdr { __u32 nlmsg_len; /* ヘッダを含むメッセージの長さ */ __u16 nlmsg_type; /* メッセージの内容のタイプ */ __u16 nlmsg_flags; /* 追加フラグ */ __u32 nlmsg_seq; /* シーケンス番号 */ __u32 nlmsg_pid; /* 送信者のポート ID */ }; nlmsg_type は標準のメッセージタイプのどれか一つである: NLMSG_NOOP メッセージは無視される。 NLMSG_ERROR メッセージはエラーを示し、ペイロードには nlmsgerr 構造体が入る。 NLMSG_DONE メッセージはマルチパートメッセージの終了を伝える。 struct nlmsgerr { int error; /* 負または 0 の errno は応答を表す */ struct nlmsghdr msg; /* エラーを起こしたメッセージのヘッダ */ }; ある netlink ファミリーで指定できるメッセージタイプは、 通常もっと多い。これらに関しては適 切な man ページを見てほしい。 たとえば NETLINK_ROUTE に関しては rtnetlink(7) に書いてあ る。 nlmsg_flags の標準フラグビット ───────────────────────────────────────────────────────────────── NLM_F_REQUEST 要求メッセージ全てでセットされなければならない。 NLM_F_MULTI このメッセージはマルチパートメッセージの一部であ る。 マルチパートメッセージは NLMSG_DONE で終端 する。 NLM_F_ACK 成功した場合の応答を要求する。 NLM_F_ECHO この要求をエコーする。 GET 要求における追加フラグビット ────────────────────────────────────────────────────────────── NLM_F_ROOT 単一のエントリではなくテーブル全体を返す。 NLM_F_MATCH メッセージの内容で渡された基準 (criteria) に マッチする全てのエントリを返す。 まだ実装され ていない。 NLM_F_ATOMIC テーブルのアトミックなスナップショットを返す。 NLM_F_DUMP 便利なマクロ。 (NLM_F_ROOT|NLM_F_MATCH) と等価. NLM_F_ATOMIC を使う場合は、 CAP_NET_ADMIN 権限を持つか実効ユーザー ID が 0 でなければなら ない点に注意すること。 NEW 要求における追加フラグビット ───────────────────────────────────────────────────────── NLM_F_REPLACE 現存のオブジェクトを置換する。 NLM_F_EXCL すでにオブジェクトがあったら置換しない。 NLM_F_CREATE まだオブジェクトがなければ作成する。 NLM_F_APPEND オブジェクトリストの最後に追加する。 nlmsg_seq と nlmsg_pid はメッセージの追跡に使用される。 nlmsg_pid はメッセージの送信元を表 す。 メッセージが netlink ソケットで送信されている場合、 nlmsg_pid とプロセスの PID は 1:1 の関係ではない点に注意すること。 より詳しい情報は、 「アドレスのフォーマット」 のセクショ ンを参照すること。 nlmsg_seq と nlmsg_pid は netlink のコアには見えない (opaque)。 netlink は信頼性の高いプロトコルではない。 netlink はメッセージを行き先に届けるために最善 を尽くすが、 メモリが足りなかったりエラーが起こったりすると メッセージを取りこぼすこともあ る。 信頼性の高い転送を行いたいときは、 送信者は受信者に応答を要求することもできる。 これ には NLM_F_ACK フラグをセットする。 応答は NLMSG_ERROR パケットのエラーフィールドを 0 にし たものになる。 アプリケーションは自分自身のメッセージを受けたときには、 応答を生成しなけれ ばならない。 カーネルは失敗したパケットに対して、 NLMSG_ERROR メッセージを送ろうとする。 ユーザープロセスはこの慣習にも従う必要がある。 しかし、どのような場合でもカーネルからユーザーへの 信頼性の高い転送は不可能である。 ソケッ トバッファが満杯の場合、カーネルは netlink メッセージを送信できない。 メッセージは取りこぼ されて、カーネルとユーザー空間プロセスは、 カーネルの状態についての同じビューを持つことが できなくなる。 これが起こったこと (recvmsg(2) によって ENOBUFS エラーが返される) を検知し て再び同期させるのは、 アプリケーションの責任である。 アドレスのフォーマット sockaddr_nl 構造体はユーザー空間やカーネル空間で netlink クライアントを記述する。 sockaddr_nl はユニキャスト (単一の接続先にだけ送られる) にもできるし、 netlink マルチキャ ストグループ (nl_groups が 0 でない場合) にも送ることができる。 struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* 0 である */ pid_t nl_pid; /* ポート ID */ __u32 nl_groups; /* マルチキャストグループマスク */ }; nl_pid は netlink ソケットのユニキャストアドレスである。 行き先がカーネルの場合は、常に 0 である。 ユーザー空間プロセスの場合、通常は nl_pid は行き先のソケットを所有しているプロセ スの PID である。 ただし、 nl_pid はプロセスではなく netlink ソケットを同定する。 プロセス が複数の netlink ソケットを所有する場合、 nl_pid は最大でも一つのソケットのプロセス ID と しか等しくならない。 nl_pid を netlink ソケットに割り当てる方法は 2 つある。 アプリケー ションが bind(2) を呼ぶ前に nl_pid を設定する場合、 nl_pid が一意であることを確認するのは アプリケーションの責任となる。 アプリケーションが nl_pid を 0 に設定した場合、カーネルがこ の値を割り当てる。 カーネルはプロセスが最初にオープンした netlink ソケットに対してプロセス ID を割り当て、 それ以降にプロセスが作成した全ての netlink ソケットにも一意な nl_pid を割 り当てる。 nl_groups はビットマスクで、すべてのビットが netlink グループ番号を表す。 それぞれの netlink ファミリーは 32 のマルチキャストグループのセットを持つ。 それぞれの netlink ファミ リーは 32 のマルチキャストグループの セットを持つ。 bind(2) がソケットに対して呼ばれると、 sockaddr_nl の nl_groups フィールドには listen したいグループのビットマスクがセットされ る。 デフォルトの値は 0 で、マルチキャストを一切受信しない。 sendmsg(2) や connect(2) に よって、あるソケットからメッセージを マルチキャストしたいときは、 nl_groups に送信したいグ ループのビットマスク をセットすればよい。 netlink マルチキャストグループに送信したり、これ を listen したりできるのは、 実効ユーザー ID が 0 のプロセスか、 CAP_NET_ADMIN 権限を持つ プロセスのみである。 Linux 2.6.13 以降では、メッセージを複数のグループへのブロードキャスト することはできない。 マルチキャストグループ向けメッセージを受信した場合、これ対する応答は 送り主の PID とマルチキャストグループとに送り返すべきである。 さらに、Linux のカーネルサブ システムによっては、 他のユーザもメッセージの送受信ができる場合がある。 Linux 3.0 の時点で は、 NETLINK_KOBJECT_UEVENT, NETLINK_GENERIC, NETLINK_ROUTE, NETLINK_SELINUX グループでは 他のユーザがメッセージを受信することができる。 他のユーザがメッセージを送信できるグループ は存在しない。
バージョン
netlink へのソケットインターフェースは Linux 2.2 の新機能である。 Linux 2.0 は、もっと原始的なデバイスベースの netlink インターフェースを サポートしていた (これも互換性のために今でも使用できる)。 古いインターフェースに関してはここでは記述しな い。 NETLINK_SELINUX は Linux 2.6.4 で登場した。 NETLINK_AUDIT は Linux 2.6.6 で登場した。 NETLINK_KOBJECT_UEVENT は Linux 2.6.10 で登場した。 NETLINK_W1, NETLINK_FIB_LOOKUP は Linux 2.6.13 で登場した。 NETLINK_INET_DIAG, NETLINK_CONNECTOR, NETLINK_NETFILTER は Linux 2.6.14 で登場した。 NETLINK_GENERIC, NETLINK_ISCSI は Linux 2.6.15 で登場した。
注意
低レベルのカーネルインターフェースより、 libnetlink または libnl を通して netlink を利用す るほうが良いことが多い。
バグ
この man ページは完成していない。
例
以下の例では、 RTMGRP_LINK (ネットワークインターフェースの create/delete/up/down イベント) と RTMGRP_IPV4_IFADDR (IPv4 アドレスの add/delete イベント) マルチキャストグループを listen する NETLINK_ROUTE netlink を作成している。 struct sockaddr_nl sa; memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); bind(fd, (struct sockaddr *) &sa, sizeof(sa)); 次の例では、netlink メッセージをカーネル (pid 0) に送る方法を示している。 応答を追跡する際 の信頼性を高めるために、アプリケーションが メッセージのシーケンス番号を正しく処理しなけれ ばならない点に注意すること。 struct nlmsghdr *nh; /* 送信する nlmsghdr とペイロード */ struct sockaddr_nl sa; struct iovec iov = { nh, nh->nlmsg_len }; struct msghdr msg; msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; nh->nlmsg_pid = 0; nh->nlmsg_seq = ++sequence_number; /* NLM_F_ACK を設定することで、カーネルに応答を要求する */ nh->nlmsg_flags |= NLM_F_ACK; sendmsg(fd, &msg, 0); 最後は、netlink メッセージの読み込みの例である。 int len; char buf[4096]; struct iovec iov = { buf, sizeof(buf) }; struct sockaddr_nl sa; struct msghdr msg; struct nlmsghdr *nh; msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; len = recvmsg(fd, &msg, 0); for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len); nh = NLMSG_NEXT (nh, len)) { /* マルチパートメッセージの終わり */ if (nh->nlmsg_type == NLMSG_DONE) return; if (nh->nlmsg_type == NLMSG_ERROR) /* 何らかのエラー処理を行う */ ... /* ペイロードの解析を続ける */ ... }
関連項目
cmsg(3), netlink(3), capabilities(7), rtnetlink(7) libnetlink に関する情報 ⟨ftp://ftp.inr.ac.ru/ip-routing/iproute2*⟩ libnl に関する情報 ⟨http://people.suug.ch/~tgr/libnl/⟩ RFC 3549 "Linux Netlink as an IP Services Protocol"
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。