名 前
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) に 書 い
て あ る 。
NLM_F_ATOMIC を 使 う 場 合 は 、 CAP_NET_ADMIN 権 限 を 持 つ か 実 効 ユ ー ザ ー ID が 0 で な け れ ば な ら な い 点 に 注 意 す る こ と 。
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)
ftp://ftp.inr.ac.ru/ip-routing/iproute2*">libnetlink
に 関 す る 情 報
http://people.suug.ch/~tgr/libnl/">libnl に
関 す る 情 報
RFC 3549 "Linux Netlink as an IP Services Protocol"
こ の 文 書 に つ い て
こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。