Various cleanups to the management of multiple TCP stacks.

- Use strlcpy() with sizeof() instead of strncpy().

- Simplify initialization of TCP functions structures.

  init_tcp_functions() was already called before the first call to
  register a stack.  Just inline the work in the SYSINIT and remove
  the racy helper variable.  Instead, KASSERT that the rw lock is
  initialized when registering a stack.

- Protect the default stack via a direct pointer comparison.

  The default stack uses the name "freebsd" instead of "default" so
  this protection wasn't working for the default stack anyway.

Reviewed by:	rrs
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D19152
This commit is contained in:
John Baldwin 2019-02-27 20:24:23 +00:00
parent 62c47c7f6c
commit dbcc200058

View File

@ -257,21 +257,10 @@ static struct tcp_function_block tcp_def_funcblk = {
.tfb_tcp_fb_fini = tcp_default_fb_fini,
};
int t_functions_inited = 0;
static int tcp_fb_cnt = 0;
struct tcp_funchead t_functions;
static struct tcp_function_block *tcp_func_set_ptr = &tcp_def_funcblk;
static void
init_tcp_functions(void)
{
if (t_functions_inited == 0) {
TAILQ_INIT(&t_functions);
rw_init_flags(&tcp_function_lock, "tcp_func_lock" , 0);
t_functions_inited = 1;
}
}
static struct tcp_function_block *
find_tcp_functions_locked(struct tcp_function_set *fs)
{
@ -559,13 +548,10 @@ sysctl_net_inet_list_func_info(SYSCTL_HANDLER_ARGS)
bzero(&tfi, sizeof(tfi));
tfi.tfi_refcnt = f->tf_fb->tfb_refcnt;
tfi.tfi_id = f->tf_fb->tfb_id;
(void)strncpy(tfi.tfi_alias, f->tf_name,
TCP_FUNCTION_NAME_LEN_MAX);
tfi.tfi_alias[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
(void)strncpy(tfi.tfi_name,
f->tf_fb->tfb_tcp_block_name,
TCP_FUNCTION_NAME_LEN_MAX);
tfi.tfi_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
(void)strlcpy(tfi.tfi_alias, f->tf_name,
sizeof(tfi.tfi_alias));
(void)strlcpy(tfi.tfi_name,
f->tf_fb->tfb_tcp_block_name, sizeof(tfi.tfi_name));
error = SYSCTL_OUT(req, &tfi, sizeof(tfi));
/*
* Don't stop on error, as that is the
@ -781,10 +767,9 @@ register_tcp_functions_as_names(struct tcp_function_block *blk, int wait,
KASSERT(names != NULL && *num_names > 0,
("%s: Called with 0-length name list", __func__));
KASSERT(names != NULL, ("%s: Called with NULL name list", __func__));
KASSERT(rw_initialized(&tcp_function_lock),
("%s: called too early", __func__));
if (t_functions_inited == 0) {
init_tcp_functions();
}
if ((blk->tfb_tcp_output == NULL) ||
(blk->tfb_tcp_do_segment == NULL) ||
(blk->tfb_tcp_ctloutput == NULL) ||
@ -824,9 +809,8 @@ register_tcp_functions_as_names(struct tcp_function_block *blk, int wait,
}
n->tf_fb = blk;
(void)strncpy(fs.function_set_name, names[i],
TCP_FUNCTION_NAME_LEN_MAX);
fs.function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
(void)strlcpy(fs.function_set_name, names[i],
sizeof(fs.function_set_name));
rw_wlock(&tcp_function_lock);
if (find_tcp_functions_locked(&fs) != NULL) {
/* Duplicate name space not allowed */
@ -835,8 +819,7 @@ register_tcp_functions_as_names(struct tcp_function_block *blk, int wait,
error = EALREADY;
goto cleanup;
}
(void)strncpy(n->tf_name, names[i], TCP_FUNCTION_NAME_LEN_MAX);
n->tf_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
(void)strlcpy(n->tf_name, names[i], sizeof(n->tf_name));
TAILQ_INSERT_TAIL(&t_functions, n, tf_next);
tcp_fb_cnt++;
rw_wunlock(&tcp_function_lock);
@ -923,8 +906,8 @@ deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce,
bool force)
{
struct tcp_function *f;
if (strcmp(blk->tfb_tcp_block_name, "default") == 0) {
if (blk == &tcp_def_funcblk) {
/* You can't un-register the default */
return (EPERM);
}
@ -1090,8 +1073,10 @@ tcp_init(void)
tcp_rexmit_slop = TCPTV_CPU_VAR;
tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT;
tcp_tcbhashsize = hashsize;
/* Setup the tcp function block list */
init_tcp_functions();
TAILQ_INIT(&t_functions);
rw_init(&tcp_function_lock, "tcp_func_lock");
register_tcp_functions(&tcp_def_funcblk, M_WAITOK);
#ifdef TCP_BLACKBOX
/* Initialize the TCP logging data. */