1.\" 2.\" Copyright (C) 2001 Chad David <davidc@acns.ab.ca>. All rights reserved. 3.\" Copyright (C) 2022 Gleb Smirnoff <glebius@FreeBSD.org> 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice(s), this list of conditions and the following disclaimer as 10.\" the first lines of this file unmodified other than the possible 11.\" addition of one or more copyright notices. 12.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" notice(s), this list of conditions and the following disclaimer in the 14.\" documentation and/or other materials provided with the distribution. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 17.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19.\" DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 20.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 26.\" DAMAGE. 27.\" 28.\" $FreeBSD$ 29.\" 30.Dd September 14, 2022 31.Dt DOMAIN 9 32.Os 33.Sh NAME 34.Nm domain , 35.Nm protosw 36.Nd "programming interface for kernel socket implementation" 37.Sh SYNOPSIS 38.In sys/param.h 39.In sys/kernel.h 40.In sys/protosw.h 41.In sys/domain.h 42.Ft void 43.Fn domain_add "struct domain *dom" 44.Ft void 45.Fn domain_remove "struct domain *dom" 46.Ft void 47.Fn DOMAIN_SET "domain" 48.Ft int 49.Fn protosw_register "struct domain *dom" "struct protosw *pr" 50.Ft int 51.Fn protosw_unregister "struct protosw *pr" 52.Sh DESCRIPTION 53The 54.Nm 55subsystem allows implementation of communication protocols that are exposed to 56the userland via the 57.Xr socket 2 58API. 59When an application performs a 60.Fn socket "domain" "type" "protocol" 61syscall, the kernel searches for a 62.Nm 63matching the 64.Ar domain 65argument, then within this domain, searches for a protocol 66matching 67.Ar type . 68If the third argument, 69.Ar protocol , 70is not 71.Dv 0 , 72that value must also match. 73The structure found must implement certain methods, so that 74.Xr socket 2 75API works for this particular kind of a socket. 76.Pp 77A minimal 78.Nm 79structure implementing a domain shall be initialized with sparse C99 80initializer and has public fields as follows: 81.Bd -literal 82struct domain { 83 /* 84 * Mandatory fields. 85 */ 86 int dom_family; /* PF_xxx, first argument of socket(2) */ 87 char *dom_name; /* text name of the domain */ 88 u_int dom_nprotosw; /* length of dom_protosw[] */ 89 /* 90 * Following methods are optional. 91 */ 92 int (*dom_probe)(void); /* check for support */ 93 struct rib_head *(*dom_rtattach)(uint32_t); /* init route table */ 94 void (*dom_rtdetach)(struct rib_head *); /* clean up table */ 95 void *(*dom_ifattach)(struct ifnet *); /* interface attach */ 96 void (*dom_ifdetach)(struct ifnet *, void *);/* & detach callbacks */ 97 int (*dom_ifmtu)(struct ifnet *); /* mtu change */ 98 /* 99 * Mandatory variable size array of pointers to protosw structs. 100 */ 101 struct protosw *dom_protosw[]; 102}; 103.Ed 104.Pp 105Each domain contains the 106.Va dom_protosw 107array of protocol switch structures 108.Pq Vt "struct protosw *" , 109one for each socket type supported. 110The array may have 111.Dv NULL 112spacers for loadable protocols. 113Sparse C99 initializers shall be used to initialize 114.Nm protosw 115structures. 116The structure has mandatory field 117.Va pr_type 118and mandatory 119.Va pr_attach 120method. 121The rest of the methods are optional, but a meaningful protocol should 122implement some. 123.Bd -literal 124struct protosw { 125 short pr_type; /* second argument of socket(2) */ 126 short pr_protocol; /* third argument of socket(2) or 0 */ 127 short pr_flags; /* see protosw.h */ 128 pr_soreceive_t *pr_soreceive; /* recv(2) */ 129 pr_rcvd_t *pr_rcvd; /* soreceive_generic() if PR_WANTRCV */ 130 pr_sosend_t *pr_sosend; /* send(2) */ 131 pr_send_t *pr_send; /* send(2) via sosend_generic() */ 132 pr_ready_t *pr_ready; /* sendfile/ktls readyness */ 133 pr_sopoll_t *pr_sopoll; /* poll(2) */ 134 pr_attach_t *pr_attach; /* creation: socreate(), sonewconn() */ 135 pr_detach_t *pr_detach; /* destruction: sofree() */ 136 pr_connect_t *pr_connect; /* connect(2) */ 137 pr_disconnect_t *pr_disconnect; /* sodisconnect() */ 138 pr_close_t *pr_close; /* close(2) */ 139 pr_shutdown_t *pr_shutdown; /* shutdown(2) */ 140 pr_abort_t *pr_abort; /* abrupt tear down: soabort() */ 141 pr_aio_queue_t *pr_aio_queue; /* aio(9) */ 142 pr_bind_t *pr_bind; /* bind(2) */ 143 pr_bindat_t *pr_bindat; /* bindat(2) */ 144 pr_listen_t *pr_listen; /* listen(2) */ 145 pr_accept_t *pr_accept; /* accept(2) */ 146 pr_connectat_t *pr_connectat; /* connectat(2) */ 147 pr_connect2_t *pr_connect2; /* socketpair(2) */ 148 pr_control_t *pr_control; /* ioctl(2) */ 149 pr_rcvoob_t *pr_rcvoob; /* soreceive_rcvoob() */ 150 pr_ctloutput_t *pr_ctloutput; /* control output (from above) */ 151 pr_peeraddr_t *pr_peeraddr; /* getpeername(2) */ 152 pr_sockaddr_t *pr_sockaddr; /* getsockname(2) */ 153 pr_sense_t *pr_sense; /* stat(2) */ 154}; 155.Ed 156.Pp 157The following functions handle the registration of new domains and protocols. 158.Pp 159.Fn domain_add 160adds a new protocol domain to the system. 161In most cases 162.Fn domain_add 163is not called directly, instead 164.Fn DOMAIN_SET 165is used, which is a wrapper around 166.Fn SYSINIT 167macro. 168If the new domain has defined a 169.Va dom_probe 170routine, it is called first in 171.Fn domain_add 172to determine if the domain should be supported on the current system. 173If the probe routine returns a non-0 value, then the domain will not be added. 174Once a domain is added it cannot be completely unloaded. 175This is because there is 176no reference counting system in place to determine if there are any 177active references from sockets within that domain. 178However, the exprimental 179.Fn domain_remove 180exists, and unloadable domains may be supported in the future. 181.Pp 182.Fn protosw_register 183dynamically adds a protocol to a domain, if the latter 184has an empty slot in its 185.Va dom_protosw . 186Dynamically added protocol can later be unloaded with 187.Fn protosw_unregister . 188.Ed 189.Sh RETURN VALUES 190The 191.Fn domain_add 192never fails, but it may not add a domain if its 193.Va dom_probe 194fails. 195.Pp 196The 197.Fn protosw_register 198function may fail if: 199.Bl -tag -width Er 200.It Bq Er EEXIST 201A protocol with the same value of 202.Va pr_type 203and 204.Va pr_protocol 205already exists in the domain. 206.It Bq Er ENOMEM 207The domain doesn't have any NULL slots in its 208.Va dom_protosw . 209.El 210.Sh SEE ALSO 211.Xr socket 2 , 212.Xr SYSINIT 9 213.Sh HISTORY 214The 215.Nm 216subsystem first appeared in 217.Bx 4.3 218as the part of the very first 219.Xr socket 2 220API implementation. 221.Pp 222The 223.Nm 224subsystem and this manual page were significantly rewritten in 225.Fx 14 . 226.Sh AUTHORS 227This manual page was written by 228.An Chad David Aq Mt davidc@acns.ab.ca 229and 230.An Gleb Smirnoff Aq Mt glebius@FreeBSD.org . 231