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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
<table class="head">
<tr>
<td class="head-ltitle">TCP_FUNCTIONS(9)</td>
<td class="head-vol">Kernel Developer's Manual</td>
<td class="head-rtitle">TCP_FUNCTIONS(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">tcp_functions</code> —
<span class="Nd">Alternate TCP Stack Framework</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
<<a class="In">netinet/tcp.h</a>></code>
<br/>
<code class="In">#include
<<a class="In">netinet/tcp_var.h</a>></code></p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">register_tcp_functions</code>(<var class="Fa" style="white-space: nowrap;">struct
tcp_function_block *blk</var>,
<var class="Fa" style="white-space: nowrap;">int wait</var>);</p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">register_tcp_functions_as_name</code>(<var class="Fa" style="white-space: nowrap;">struct
tcp_function_block *blk</var>,
<var class="Fa" style="white-space: nowrap;">const char *name</var>,
<var class="Fa" style="white-space: nowrap;">int wait</var>);</p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">register_tcp_functions_as_names</code>(<var class="Fa" style="white-space: nowrap;">struct
tcp_function_block *blk</var>,
<var class="Fa" style="white-space: nowrap;">int wait</var>,
<var class="Fa" style="white-space: nowrap;">const char *names[]</var>,
<var class="Fa" style="white-space: nowrap;">int *num_names</var>);</p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">deregister_tcp_functions</code>(<var class="Fa" style="white-space: nowrap;">struct
tcp_function_block *blk</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">tcp_functions</code> framework allows a
kernel developer to implement alternate TCP stacks. The alternate stacks can
be compiled in the kernel or can be implemented in loadable kernel modules.
This functionality is intended to encourage experimentation with the TCP
stack and to allow alternate behaviors to be deployed for different TCP
connections on a single system.</p>
<p class="Pp">A system administrator can set a system default stack. By default,
all TCP connections will use the system default stack. Additionally, users
can specify a particular stack to use on a per-connection basis. (See
<a class="Xr">tcp(4)</a> for details on setting the system default stack, or
selecting a specific stack for a given connection.)</p>
<p class="Pp">This man page treats "TCP stacks" as synonymous with
"function blocks". This is intentional. A "TCP stack" is
a collection of functions that implement a set of behavior. Therefore, an
alternate "function block" defines an alternate "TCP
stack".</p>
<p class="Pp" id="register_tcp_functions">The
<a class="permalink" href="#register_tcp_functions"><code class="Fn">register_tcp_functions</code></a>(),
<code class="Fn">register_tcp_functions_as_name</code>(), and
<code class="Fn">register_tcp_functions_as_names</code>() functions request
that the system add a specified function block and register it for use with
a given name. Modules may register the same function block multiple times
with different names. However, names must be globally unique among all
registered function blocks. Also, modules may not ever modify the contents
of the function block (including the name) after it has been registered,
unless the module first successfully de-registers the function block.</p>
<p class="Pp" id="register_tcp_functions~2">The
<a class="permalink" href="#register_tcp_functions~2"><code class="Fn">register_tcp_functions</code></a>()
function requests that the system register the function block with the name
defined in the function block's <var class="Va">tfb_tcp_block_name</var>
field. Note that this is the only one of the three registration functions
that automatically registers the function block using the name defined in
the function block's <var class="Va">tfb_tcp_block_name</var> field. If a
module uses one of the other registration functions, it may request that the
system register the function block using the name defined in the function
block's <var class="Va">tfb_tcp_block_name</var> field by explicitly
providing that name.</p>
<p class="Pp" id="register_tcp_functions_as_name">The
<a class="permalink" href="#register_tcp_functions_as_name"><code class="Fn">register_tcp_functions_as_name</code></a>()
function requests that the system register the function block with the name
provided in the <var class="Fa">name</var> argument.</p>
<p class="Pp" id="register_tcp_functions_as_names">The
<a class="permalink" href="#register_tcp_functions_as_names"><code class="Fn">register_tcp_functions_as_names</code></a>()
function requests that the system register the function block with all the
names provided in the <var class="Fa">names</var> argument. The
<var class="Fa">num_names</var> argument provides a pointer to the number of
names. This number must not exceed TCP_FUNCTION_NAME_NUM_MAX. This function
will either succeed in registering all of the names in the array, or none of
the names in the array. On failure, the <var class="Fa">num_names</var>
argument is updated with the index number of the entry in the
<var class="Fa">names</var> array which the system was processing when it
encountered the error.</p>
<p class="Pp" id="deregister_tcp_functions">The
<a class="permalink" href="#deregister_tcp_functions"><code class="Fn">deregister_tcp_functions</code></a>()
function requests that the system remove a specified function block from the
system. If this call succeeds, it will completely deregister the function
block, regardless of the number of names used to register the function
block. If the call fails because sockets are still using the specified
function block, the system will mark the function block as being in the
process of being removed. This will prevent additional sockets from using
the specified function block. However, it will not impact sockets that are
already using the function block.</p>
<p class="Pp" id="deregister_tcp_functions~2"><code class="Nm">tcp_functions</code>
modules must call one or more of the registration functions during
initialization and successfully call the
<a class="permalink" href="#deregister_tcp_functions~2"><code class="Fn">deregister_tcp_functions</code></a>()
function prior to allowing the module to be unloaded.</p>
<p class="Pp">The <var class="Fa">blk</var> argument is a pointer to a
<var class="Vt">struct tcp_function_block</var>, which is explained below
(see <a class="Sx" href="#Function_Block_Structure">Function Block
Structure</a>). The <var class="Fa">wait</var> argument is used as the
<var class="Fa">flags</var> argument to <a class="Xr">malloc(9)</a>, and
must be set to one of the valid values defined in that man page.</p>
<section class="Ss">
<h2 class="Ss" id="Function_Block_Structure"><a class="permalink" href="#Function_Block_Structure">Function
Block Structure</a></h2>
<p class="Pp">The <var class="Fa">blk argument is a pointer to a</var>
<var class="Vt">struct tcp_function_block</var>, which has the following
members:</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct tcp_function_block {
char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
int (*tfb_tcp_output)(struct tcpcb *);
void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
struct socket *, struct tcpcb *,
int, int, uint8_t,
int);
int (*tfb_tcp_ctloutput)(struct socket *so,
struct sockopt *sopt,
struct inpcb *inp, struct tcpcb *tp);
/* Optional memory allocation/free routine */
void (*tfb_tcp_fb_init)(struct tcpcb *);
void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
/* Optional timers, must define all if you define one */
int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
void (*tfb_tcp_timer_activate)(struct tcpcb *,
uint32_t, u_int);
int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
/* Optional function */
void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
/* Mandatory function */
int (*tfb_tcp_handoff_ok)(struct tcpcb *);
/* System use */
volatile uint32_t tfb_refcnt;
uint32_t tfb_flags;
};</pre>
</div>
<p class="Pp">The <var class="Va">tfb_tcp_block_name</var> field identifies the
unique name of the TCP stack, and should be no longer than
TCP_FUNCTION_NAME_LEN_MAX-1 characters in length.</p>
<p class="Pp" id="tcp_output">The <var class="Va">tfb_tcp_output</var>,
<var class="Va">tfb_tcp_do_segment</var>, and
<var class="Va">tfb_tcp_ctloutput</var> fields are pointers to functions
that perform the equivalent actions as the default
<a class="permalink" href="#tcp_output"><code class="Fn">tcp_output</code></a>(),
<a class="permalink" href="#tcp_do_segment"><code class="Fn" id="tcp_do_segment">tcp_do_segment</code></a>(),
and
<a class="permalink" href="#tcp_default_ctloutput"><code class="Fn" id="tcp_default_ctloutput">tcp_default_ctloutput</code></a>()
functions, respectively. Each of these function pointers must be
non-NULL.</p>
<p class="Pp">If a TCP stack needs to initialize data when a socket first
selects the TCP stack (or, when the socket is first opened), it should set a
non-NULL pointer in the <var class="Va">tfb_tcp_fb_init</var> field.
Likewise, if a TCP stack needs to cleanup data when a socket stops using the
TCP stack (or, when the socket is closed), it should set a non-NULL pointer
in the <var class="Va">tfb_tcp_fb_fini</var> field.</p>
<p class="Pp">If the <var class="Va">tfb_tcp_fb_fini</var> argument is non-NULL,
the function to which it points is called when the kernel is destroying the
TCP control block or when the socket is transitioning to use a different TCP
stack. The function is called with arguments of the TCP control block and an
integer flag. The flag will be zero if the socket is transitioning to use
another TCP stack or one if the TCP control block is being destroyed.</p>
<p class="Pp" id="tcp_timer_activate">If the TCP stack implements additional
timers, the TCP stack should set a non-NULL pointer in the
<var class="Va">tfb_tcp_timer_stop_all</var>,
<var class="Va">tfb_tcp_timer_activate</var>,
<var class="Va">tfb_tcp_timer_active</var>, and
<var class="Va">tfb_tcp_timer_stop</var> fields. These fields should all be
<code class="Dv">NULL</code> or should all contain pointers to functions.
The <var class="Va">tfb_tcp_timer_activate</var>,
<var class="Va">tfb_tcp_timer_active</var>, and
<var class="Va">tfb_tcp_timer_stop</var> functions will be called when the
<a class="permalink" href="#tcp_timer_activate"><code class="Fn">tcp_timer_activate</code></a>(),
<a class="permalink" href="#tcp_timer_active"><code class="Fn" id="tcp_timer_active">tcp_timer_active</code></a>(),
and
<a class="permalink" href="#tcp_timer_stop"><code class="Fn" id="tcp_timer_stop">tcp_timer_stop</code></a>()
functions, respectively, are called with a timer type other than the
standard types. The functions defined by the TCP stack have the same
semantics (both for arguments and return values) as the normal timer
functions they supplement.</p>
<p class="Pp">Additionally, a stack may define its own actions to take when the
retransmit timer fires by setting a non-NULL function pointer in the
<var class="Va">tfb_tcp_rexmit_tmr</var> field. This function is called very
early in the process of handling a retransmit timer. However, care must be
taken to ensure the retransmit timer leaves the TCP control block in a valid
state for the remainder of the retransmit timer logic.</p>
<p class="Pp">A user may select a new TCP stack before calling at any time.
Therefore, the function pointer <var class="Va">tfb_tcp_handoff_ok</var>
field must be non-NULL. If a user attempts to select that TCP stack, the
kernel will call the function pointed to by the
<var class="Va">tfb_tcp_handoff_ok</var> field. The function should return 0
if the user is allowed to switch the socket to use the TCP stack. In this
case, the kernel will call the function pointed to by
<var class="Va">tfb_tcp_fb_init</var> if this function pointer is non-NULL
and finally perform the stack switch. If the user is not allowed to switch
the socket, the function should undo any changes it made to the connection
state configuration and return an error code, which will be returned to the
user.</p>
<p class="Pp">The <var class="Va">tfb_refcnt</var> and
<var class="Va">tfb_flags</var> fields are used by the kernel's TCP code and
will be initialized when the TCP stack is registered.</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Requirements_for_Alternate_TCP_Stacks"><a class="permalink" href="#Requirements_for_Alternate_TCP_Stacks">Requirements
for Alternate TCP Stacks</a></h2>
<p class="Pp">If the TCP stack needs to store data beyond what is stored in the
default TCP control block, the TCP stack can initialize its own
per-connection storage. The <var class="Va">t_fb_ptr</var> field in the
<var class="Vt">struct tcpcb</var> control block structure has been reserved
to hold a pointer to this per-connection storage. If the TCP stack uses this
alternate storage, it should understand that the value of the
<var class="Va">t_fb_ptr</var> pointer may not be initialized to
<code class="Dv">NULL</code>. Therefore, it should use a
<var class="Va">tfb_tcp_fb_init</var> function to initialize this field.
Additionally, it should use a <var class="Va">tfb_tcp_fb_fini</var> function
to deallocate storage when the socket is closed.</p>
<p class="Pp">It is understood that alternate TCP stacks may keep different sets
of data. However, in order to ensure that data is available to both the user
and the rest of the system in a standardized format, alternate TCP stacks
must update all fields in the TCP control block to the greatest extent
practical.</p>
</section>
</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">register_tcp_functions</code>(),
<code class="Fn">register_tcp_functions_as_name</code>(),
<code class="Fn">register_tcp_functions_as_names</code>(), and
<code class="Fn">deregister_tcp_functions</code>() functions return zero on
success and non-zero on failure. In particular, the
<code class="Fn">deregister_tcp_functions</code>() will return
<code class="Er">EBUSY</code> until no more connections are using the
specified TCP stack. A module calling
<code class="Fn">deregister_tcp_functions</code>() must be prepared to wait
until all connections have stopped using the specified TCP stack.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="ERRORS"><a class="permalink" href="#ERRORS">ERRORS</a></h1>
<p class="Pp">The <code class="Fn">register_tcp_functions</code>(),
<code class="Fn">register_tcp_functions_as_name</code>(), and
<code class="Fn">register_tcp_functions_as_names</code>() functions will
fail if:</p>
<dl class="Bl-tag">
<dt id="EINVAL">[<a class="permalink" href="#EINVAL"><code class="Er">EINVAL</code></a>]</dt>
<dd>Any of the members of the <var class="Fa">blk</var> argument are set
incorrectly.</dd>
<dt id="ENOMEM">[<a class="permalink" href="#ENOMEM"><code class="Er">ENOMEM</code></a>]</dt>
<dd>The function could not allocate memory for its internal data.</dd>
<dt id="EALREADY">[<a class="permalink" href="#EALREADY"><code class="Er">EALREADY</code></a>]</dt>
<dd>The <var class="Fa">blk</var> is already registered or a function block is
already registered with the same name.</dd>
</dl>
Additionally, <code class="Fn">register_tcp_functions_as_names</code>() will
fail if:
<dl class="Bl-tag">
<dt id="E2BIG">[<a class="permalink" href="#E2BIG"><code class="Er">E2BIG</code></a>]</dt>
<dd>The number of names pointed to by the <var class="Fa">num_names</var>
argument is larger than TCP_FUNCTION_NAME_NUM_MAX.</dd>
</dl>
The <code class="Fn">deregister_tcp_functions</code>() function will fail if:
<dl class="Bl-tag">
<dt id="EPERM">[<a class="permalink" href="#EPERM"><code class="Er">EPERM</code></a>]</dt>
<dd>The <var class="Fa">blk</var> argument references the kernel's compiled-in
default function block.</dd>
<dt id="EBUSY">[<a class="permalink" href="#EBUSY"><code class="Er">EBUSY</code></a>]</dt>
<dd>The function block is still in use by one or more sockets, or is defined
as the current default function block.</dd>
<dt id="ENOENT">[<a class="permalink" href="#ENOENT"><code class="Er">ENOENT</code></a>]</dt>
<dd>The <var class="Fa">blk</var> argument references a function block that is
not currently registered.</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">connect(2)</a>, <a class="Xr">listen(2)</a>,
<a class="Xr">tcp(4)</a>, <a class="Xr">malloc(9)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">This framework first appeared in <span class="Ux">FreeBSD
11.0</span>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp">The <code class="Nm">tcp_functions</code> framework was written by
<span class="An">Randall Stewart</span>
<<a class="Mt" href="mailto:rrs@FreeBSD.org">rrs@FreeBSD.org</a>>.</p>
<p class="Pp">This manual page was written by <span class="An">Jonathan
Looney</span>
<<a class="Mt" href="mailto:jtl@FreeBSD.org">jtl@FreeBSD.org</a>>.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">July 13, 2024</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|