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