Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_subr.c
Show First 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | static struct tcp_function_block tcp_def_funcblk = { | ||||
.tfb_tcp_output = tcp_output, | .tfb_tcp_output = tcp_output, | ||||
.tfb_tcp_do_segment = tcp_do_segment, | .tfb_tcp_do_segment = tcp_do_segment, | ||||
.tfb_tcp_ctloutput = tcp_default_ctloutput, | .tfb_tcp_ctloutput = tcp_default_ctloutput, | ||||
.tfb_tcp_handoff_ok = tcp_default_handoff_ok, | .tfb_tcp_handoff_ok = tcp_default_handoff_ok, | ||||
.tfb_tcp_fb_init = tcp_default_fb_init, | .tfb_tcp_fb_init = tcp_default_fb_init, | ||||
.tfb_tcp_fb_fini = tcp_default_fb_fini, | .tfb_tcp_fb_fini = tcp_default_fb_fini, | ||||
}; | }; | ||||
int t_functions_inited = 0; | |||||
static int tcp_fb_cnt = 0; | static int tcp_fb_cnt = 0; | ||||
struct tcp_funchead t_functions; | struct tcp_funchead t_functions; | ||||
static struct tcp_function_block *tcp_func_set_ptr = &tcp_def_funcblk; | 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 * | static struct tcp_function_block * | ||||
find_tcp_functions_locked(struct tcp_function_set *fs) | find_tcp_functions_locked(struct tcp_function_set *fs) | ||||
{ | { | ||||
struct tcp_function *f; | struct tcp_function *f; | ||||
struct tcp_function_block *blk=NULL; | struct tcp_function_block *blk=NULL; | ||||
TAILQ_FOREACH(f, &t_functions, tf_next) { | TAILQ_FOREACH(f, &t_functions, tf_next) { | ||||
if (strcmp(f->tf_name, fs->function_set_name) == 0) { | if (strcmp(f->tf_name, fs->function_set_name) == 0) { | ||||
▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | #endif | ||||
TAILQ_FOREACH(f, &t_functions, tf_next) { | TAILQ_FOREACH(f, &t_functions, tf_next) { | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
cnt++; | cnt++; | ||||
#endif | #endif | ||||
if (req->oldptr != NULL) { | if (req->oldptr != NULL) { | ||||
bzero(&tfi, sizeof(tfi)); | bzero(&tfi, sizeof(tfi)); | ||||
tfi.tfi_refcnt = f->tf_fb->tfb_refcnt; | tfi.tfi_refcnt = f->tf_fb->tfb_refcnt; | ||||
tfi.tfi_id = f->tf_fb->tfb_id; | tfi.tfi_id = f->tf_fb->tfb_id; | ||||
(void)strncpy(tfi.tfi_alias, f->tf_name, | (void)strlcpy(tfi.tfi_alias, f->tf_name, | ||||
TCP_FUNCTION_NAME_LEN_MAX); | sizeof(tfi.tfi_alias)); | ||||
tfi.tfi_alias[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0'; | (void)strlcpy(tfi.tfi_name, | ||||
(void)strncpy(tfi.tfi_name, | f->tf_fb->tfb_tcp_block_name, sizeof(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'; | |||||
error = SYSCTL_OUT(req, &tfi, sizeof(tfi)); | error = SYSCTL_OUT(req, &tfi, sizeof(tfi)); | ||||
/* | /* | ||||
* Don't stop on error, as that is the | * Don't stop on error, as that is the | ||||
* mechanism we use to accumulate length | * mechanism we use to accumulate length | ||||
* information if the buffer was too short. | * information if the buffer was too short. | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct tcp_function *n; | struct tcp_function *n; | ||||
struct tcp_function_set fs; | struct tcp_function_set fs; | ||||
int error, i; | int error, i; | ||||
KASSERT(names != NULL && *num_names > 0, | KASSERT(names != NULL && *num_names > 0, | ||||
("%s: Called with 0-length name list", __func__)); | ("%s: Called with 0-length name list", __func__)); | ||||
KASSERT(names != NULL, ("%s: Called with NULL 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) || | if ((blk->tfb_tcp_output == NULL) || | ||||
(blk->tfb_tcp_do_segment == NULL) || | (blk->tfb_tcp_do_segment == NULL) || | ||||
(blk->tfb_tcp_ctloutput == NULL) || | (blk->tfb_tcp_ctloutput == NULL) || | ||||
(strlen(blk->tfb_tcp_block_name) == 0)) { | (strlen(blk->tfb_tcp_block_name) == 0)) { | ||||
/* | /* | ||||
* These functions are required and you | * These functions are required and you | ||||
* need a name. | * need a name. | ||||
*/ | */ | ||||
Show All 23 Lines | register_tcp_functions_as_names(struct tcp_function_block *blk, int wait, | ||||
for (i = 0; i < *num_names; i++) { | for (i = 0; i < *num_names; i++) { | ||||
n = malloc(sizeof(struct tcp_function), M_TCPFUNCTIONS, wait); | n = malloc(sizeof(struct tcp_function), M_TCPFUNCTIONS, wait); | ||||
if (n == NULL) { | if (n == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
n->tf_fb = blk; | n->tf_fb = blk; | ||||
(void)strncpy(fs.function_set_name, names[i], | (void)strlcpy(fs.function_set_name, names[i], | ||||
TCP_FUNCTION_NAME_LEN_MAX); | sizeof(fs.function_set_name)); | ||||
fs.function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0'; | |||||
rw_wlock(&tcp_function_lock); | rw_wlock(&tcp_function_lock); | ||||
if (find_tcp_functions_locked(&fs) != NULL) { | if (find_tcp_functions_locked(&fs) != NULL) { | ||||
/* Duplicate name space not allowed */ | /* Duplicate name space not allowed */ | ||||
rw_wunlock(&tcp_function_lock); | rw_wunlock(&tcp_function_lock); | ||||
free(n, M_TCPFUNCTIONS); | free(n, M_TCPFUNCTIONS); | ||||
error = EALREADY; | error = EALREADY; | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
(void)strncpy(n->tf_name, names[i], TCP_FUNCTION_NAME_LEN_MAX); | (void)strlcpy(n->tf_name, names[i], sizeof(n->tf_name)); | ||||
n->tf_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0'; | |||||
TAILQ_INSERT_TAIL(&t_functions, n, tf_next); | TAILQ_INSERT_TAIL(&t_functions, n, tf_next); | ||||
tcp_fb_cnt++; | tcp_fb_cnt++; | ||||
rw_wunlock(&tcp_function_lock); | rw_wunlock(&tcp_function_lock); | ||||
} | } | ||||
return(0); | return(0); | ||||
cleanup: | cleanup: | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
* Returns 0 on success (or if the removal would succeed, or an error | * Returns 0 on success (or if the removal would succeed, or an error | ||||
* code on failure. | * code on failure. | ||||
*/ | */ | ||||
int | int | ||||
deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce, | deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce, | ||||
bool force) | bool force) | ||||
{ | { | ||||
struct tcp_function *f; | 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 */ | /* You can't un-register the default */ | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
rw_wlock(&tcp_function_lock); | rw_wlock(&tcp_function_lock); | ||||
if (blk == tcp_func_set_ptr) { | if (blk == tcp_func_set_ptr) { | ||||
/* You can't free the current default */ | /* You can't free the current default */ | ||||
rw_wunlock(&tcp_function_lock); | rw_wunlock(&tcp_function_lock); | ||||
return (EBUSY); | return (EBUSY); | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | #endif | ||||
tcp_rexmit_min = TCPTV_MIN; | tcp_rexmit_min = TCPTV_MIN; | ||||
if (tcp_rexmit_min < 1) | if (tcp_rexmit_min < 1) | ||||
tcp_rexmit_min = 1; | tcp_rexmit_min = 1; | ||||
tcp_persmin = TCPTV_PERSMIN; | tcp_persmin = TCPTV_PERSMIN; | ||||
tcp_persmax = TCPTV_PERSMAX; | tcp_persmax = TCPTV_PERSMAX; | ||||
tcp_rexmit_slop = TCPTV_CPU_VAR; | tcp_rexmit_slop = TCPTV_CPU_VAR; | ||||
tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT; | tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT; | ||||
tcp_tcbhashsize = hashsize; | tcp_tcbhashsize = hashsize; | ||||
/* Setup the tcp function block list */ | /* 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); | register_tcp_functions(&tcp_def_funcblk, M_WAITOK); | ||||
#ifdef TCP_BLACKBOX | #ifdef TCP_BLACKBOX | ||||
/* Initialize the TCP logging data. */ | /* Initialize the TCP logging data. */ | ||||
tcp_log_init(); | tcp_log_init(); | ||||
#endif | #endif | ||||
arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0); | arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0); | ||||
if (tcp_soreceive_stream) { | if (tcp_soreceive_stream) { | ||||
▲ Show 20 Lines • Show All 2,156 Lines • Show Last 20 Lines |