Provided by: manpages-ja_0.5.0.0.20161015+dfsg-1_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_CRYPTO (Linux 3.2 以降)
カーネル暗号 API で登録された暗号に関する情報を要求したり、 カーネル暗号 API の設定を行ったりする
ための 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 に関する情報
libnl に関する情報
RFC 3549 "Linux Netlink as an IP Services Protocol"
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告
に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
Linux 2015-01-10 NETLINK(7)