法楽日記

デジタル散策記&マインド探訪記

FreeBSD 11.1R: 通信 domain の定義

システムコール socket() は、第1引数で通信 domain を指定します。

FreeBSD 11.1R のカーネルでは、各通信 domain に関する情報は domain 構造体で管理されています。各 domain 構造体は、カーネル起動時にチェーン状に繋がれます。チェーンの先頭は、sys/kern/uipc_domain.c で宣言されている domains という大域変数です。通信 domain 検索時には、domains から各通信 domain を辿って探していきます。

さて、FreeBSD 11.1R では下記の通信 domain が定義されています(下記の表では順に、family、変数名、ファイル名です)。

DOMAIN_SET() を用いて定義されているのは次の2つです。

AF_LOCAL : localdomain in sys/kern/uipc_usrreq.c
AF_NATM : natmdomain in sys/netnatm/natm_proto.c

VNET_DOMAIN_SET() を用いて定義されているのは次の5つです。

PF_ROUTE : routedomain in sys/net/rtsock.c
AF_NETGRAPH : ngdomain in sys/netgraph/ng_socket.c
AF_INET : inetdomain in sys/netinet/in_proto.c
AF_INET6 : inet6domain in sys/netinet6/in6_proto.c
PF_KEY : keydomain in sys/netipsec/keysock.c

ここで、マクロ DOMAIN_SET() と VNET_DOMAIN_SET() の違いは、VIMAGE に対応しているかどうか、です。VNET_DOMAIN_SET() を用いて定義された通信 domain は VIMAGE に対応していて、jail() により独立したネットワークスタックとして動作させることができるようです。

なお、マクロ DOMAIN_SET() と VNET_DOMAIN_SET() は sys/sys/domain.h で定義されています。その中で利用されている SYSINIT() は sys/sys/kernel.h で、DATA_SET() は sys/sys/linker_set.h で、それぞれ定義されています。

マクロ定義によると、DOMAIN_SET() を用いて定義された通信 domain は、カーネル起動時に domain_add() と domain_init() がこの順で呼び出されます。また、VNET_DOMAIN_SET() を用いて定義された通信 domain は、カーネル起動時に domain_add() と vnet_domain_init() がこの順で呼び出されます。これらの関数は sys/kern/uipc_domain.c で定義されています。