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