Provided by: manpages-ja_0.5.0.0.20221215+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 (Linux 2.6.13 から 2.16.17 まで)
              単線 (1-wire) のサブシステムからのメッセージ。

       NETLINK_USERSOCK
              ユーザーモードソケットプロトコルのために予約されている。

       NETLINK_FIREWALL (Linux 3.4 以前)
              Transport IPv4 packets from netfilter to  user  space.   Used  by  ip_queue  kernel
              module.   After  a  long  period  of  being declared obsolete (in favor of the more
              advanced nfnetlink_queue feature), NETLINK_FIREWALL was removed in Linux 3.5.

       NETLINK_SOCK_DIAG (Linux 3.3 以降)
              Query information about sockets of various protocol families from the  kernel  (see
              sock_diag(7)).

       NETLINK_INET_DIAG (Linux 2.6.14 以降)
              An obsolete synonym for NETLINK_SOCK_DIAG.

       NETLINK_NFLOG (Linux 3.16 以前)
              Netfilter/iptables ULOG.

       NETLINK_XFRM
              IPsec.

       NETLINK_SELINUX (Linux 2.6.4 以降)
              SELinux のイベント通知。

       NETLINK_ISCSI (Linux 2.6.15 以降)
              Open-iSCSI.

       NETLINK_AUDIT (Linux 2.6.6 以降)
              監査 (audit) を行う。

       NETLINK_FIB_LOOKUP (Linux 2.6.13 以降)
              ユーザー空間から FIB ルックアップにアクセスする。

       NETLINK_CONNECTOR (Linux 2.6.14 以降)
              カーネルコネクタ。より詳しい情報は              Linux              カーネルソースの
              Documentation/driver-api/connector.rst        (カーネル        5.2         以前では
              /Documentation/connector/connector.*) を参照すること。

       NETLINK_NETFILTER (Linux 2.6.14 以降)
              netfilter サブシステム。

       NETLINK_SCSITRANSPORT (Linux 2.6.19 以降)
              SCSI Transports.

       NETLINK_RDMA (Linux 3.0 以降)
              Infiniband RDMA.

       NETLINK_IP6_FW (Linux 3.4 以前)
              IPv6 パケットを netfilter からユーザー空間へ転送する。 ip6_queue カーネルモジュール
              で使用される。

       NETLINK_DNRTMSG
              DECnet ルーティングメッセージ。

       NETLINK_KOBJECT_UEVENT (Linux 2.6.10 以降)
              ユーザー空間へのカーネルメッセージ

       NETLINK_GENERIC (Linux 2.6.15 以降)
              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  グループで
       は他のユーザーがメッセージを受信することができる。  他のユーザーがメッセージを送信できるグ
       ループは存在しない。

   ソケットオプション
       To set or get a netlink socket option, call getsockopt(2)  to read  or  setsockopt(2)   to
       write  the  option  with  the  option level argument set to SOL_NETLINK.  Unless otherwise
       noted, optval is a pointer to an int.

       NETLINK_PKTINFO (Linux 2.6.14 以降)
              Enable nl_pktinfo control  messages  for  received  packets  to  get  the  extended
              destination group number.

       NETLINK_ADD_MEMBERSHIP, NETLINK_DROP_MEMBERSHIP (Linux 2.6.14 以降)
              Join/leave a group specified by optval.

       NETLINK_LIST_MEMBERSHIPS (Linux 4.2 以降)
              Retrieve  all  groups  a  socket  is a member of.  optval is a pointer to __u32 and
              optlen is the size of the array.  The array is filled with the full membership  set
              of the socket, and the required array size is returned in optlen.

       NETLINK_BROADCAST_ERROR (Linux 2.6.30 以降)
              When  not  set,  netlink_broadcast()  only reports ESRCH errors and silently ignore
              ENOBUFS errors.

       NETLINK_NO_ENOBUFS (Linux 2.6.30 以降)
              This flag can be used by unicast and broadcast listeners to avoid receiving ENOBUFS
              errors.

       NETLINK_LISTEN_ALL_NSID (Linux 4.2 以降)
              When  set,  this  socket  will  receive  netlink  notifications  from  all  network
              namespaces that have an nsid assigned into the network namespace where  the  socket
              has been opened.  The nsid is sent to user space via an ancillary data.

       NETLINK_CAP_ACK (Linux 4.2 以降)
              The  kernel  may fail to allocate the necessary room for the acknowledgment message
              back to user space.  This option trims off the  payload  of  the  original  netlink
              message.   The netlink message header is still included, so the user can guess from
              the sequence number which message triggered the acknowledgment.

バージョン

       netlink へのソケットインターフェースは Linux 2.2 で初めて登場した。

       Linux 2.0 は、もっと原始的なデバイスベースの netlink  インターフェースを  サポートしていた
       (これも互換性のために今でも使用できる)。    古いインターフェースに関してはここでは記述しな
       い。

注意

       低レベルのカーネルインターフェースより、 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;
           /* 8192 to avoid message truncation on platforms with
              page size > 4096 */
           struct nlmsghdr buf[8192/sizeof(struct nlmsghdr)];
           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), sock_diag(7)

       libnetlink に関する情報 ⟨ftp://ftp.inr.ac.ru/ip-routing/iproute2*⟩

       libnl に関する情報 ⟨http://www.infradead.org/~tgr/libnl/⟩

       RFC 3549 "Linux Netlink as an IP Services Protocol"

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。