Provided by: manpages-ja_0.5.0.0.20210215+dfsg-1_all bug

名前

       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_RAWSOCK_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_seqnlmsg_pid はメッセージの追跡に使用される。 nlmsg_pid はメッセージの送信元を表
       す。 メッセージが netlink ソケットで送信されている場合、 nlmsg_pid とプロセスの PID は 1:1
       の関係ではない点に注意すること。  より詳しい情報は、 「アドレスのフォーマット」 のセクショ
       ンを参照すること。

       nlmsg_seqnlmsg_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_nlnl_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.79 の一部  である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。