Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_subr.c
Show All 12 Lines | |||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
V_tcp_mssdflt = new; | V_tcp_mssdflt = new; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, | SYSCTL_PROC(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, &VNET_NAME(tcp_mssdflt), 0, | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
&VNET_NAME(tcp_mssdflt), 0, | |||||
&sysctl_net_inet_tcp_mss_check, "I", | &sysctl_net_inet_tcp_mss_check, "I", | ||||
"Default TCP Maximum Segment Size"); | "Default TCP Maximum Segment Size"); | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int | static int | ||||
sysctl_net_inet_tcp_mss_v6_check(SYSCTL_HANDLER_ARGS) | sysctl_net_inet_tcp_mss_v6_check(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int error, new; | int error, new; | ||||
new = V_tcp_v6mssdflt; | new = V_tcp_v6mssdflt; | ||||
error = sysctl_handle_int(oidp, &new, 0, req); | error = sysctl_handle_int(oidp, &new, 0, req); | ||||
if (error == 0 && req->newptr) { | if (error == 0 && req->newptr) { | ||||
if (new < TCP_MINMSS) | if (new < TCP_MINMSS) | ||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
V_tcp_v6mssdflt = new; | V_tcp_v6mssdflt = new; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, | SYSCTL_PROC(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, &VNET_NAME(tcp_v6mssdflt), 0, | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
&VNET_NAME(tcp_v6mssdflt), 0, | |||||
&sysctl_net_inet_tcp_mss_v6_check, "I", | &sysctl_net_inet_tcp_mss_v6_check, "I", | ||||
"Default TCP Maximum Segment Size for IPv6"); | "Default TCP Maximum Segment Size for IPv6"); | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
/* | /* | ||||
* Minimum MSS we accept and use. This prevents DoS attacks where | * Minimum MSS we accept and use. This prevents DoS attacks where | ||||
* we are forced to a ridiculous low MSS like 20 and send hundreds | * we are forced to a ridiculous low MSS like 20 and send hundreds | ||||
* of packets instead of one. The effect scales with the available | * of packets instead of one. The effect scales with the available | ||||
Show All 24 Lines | |||||
if (new > 0 && new < TCP_MIN_MAP_ENTRIES_LIMIT) | if (new > 0 && new < TCP_MIN_MAP_ENTRIES_LIMIT) | ||||
error = EINVAL; | error = EINVAL; | ||||
else | else | ||||
V_tcp_map_entries_limit = new; | V_tcp_map_entries_limit = new; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, map_limit, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, map_limit, | ||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, | CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
&VNET_NAME(tcp_map_entries_limit), 0, | &VNET_NAME(tcp_map_entries_limit), 0, | ||||
&sysctl_net_inet_tcp_map_limit_check, "IU", | &sysctl_net_inet_tcp_map_limit_check, "IU", | ||||
"Total sendmap entries limit"); | "Total sendmap entries limit"); | ||||
VNET_DEFINE(uint32_t, tcp_map_split_limit) = 0; /* unlimited */ | VNET_DEFINE(uint32_t, tcp_map_split_limit) = 0; /* unlimited */ | ||||
SYSCTL_UINT(_net_inet_tcp, OID_AUTO, split_limit, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_UINT(_net_inet_tcp, OID_AUTO, split_limit, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_map_split_limit), 0, | &VNET_NAME(tcp_map_split_limit), 0, | ||||
"Total sendmap split entries limit"); | "Total sendmap split entries limit"); | ||||
Show All 24 Lines | |||||
} | } | ||||
tcp_func_set_ptr = blk; | tcp_func_set_ptr = blk; | ||||
done: | done: | ||||
rw_wunlock(&tcp_function_lock); | rw_wunlock(&tcp_function_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_default, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_default, | ||||
CTLTYPE_STRING | CTLFLAG_RW, | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
NULL, 0, sysctl_net_inet_default_tcp_functions, "A", | NULL, 0, sysctl_net_inet_default_tcp_functions, "A", | ||||
"Set/get the default TCP functions"); | "Set/get the default TCP functions"); | ||||
static int | static int | ||||
sysctl_net_inet_list_available(SYSCTL_HANDLER_ARGS) | sysctl_net_inet_list_available(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int error, cnt, linesz; | int error, cnt, linesz; | ||||
struct tcp_function *f; | struct tcp_function *f; | ||||
char *buffer, *cp; | char *buffer, *cp; | ||||
size_t bufsz, outsz; | size_t bufsz, outsz; | ||||
Show All 24 Lines | |||||
rw_runlock(&tcp_function_lock); | rw_runlock(&tcp_function_lock); | ||||
if (error == 0) | if (error == 0) | ||||
error = sysctl_handle_string(oidp, buffer, outsz + 1, req); | error = sysctl_handle_string(oidp, buffer, outsz + 1, req); | ||||
free(buffer, M_TEMP); | free(buffer, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_available, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_available, | ||||
CTLTYPE_STRING|CTLFLAG_RD, | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, | ||||
NULL, 0, sysctl_net_inet_list_available, "A", | NULL, 0, sysctl_net_inet_list_available, "A", | ||||
"list available TCP Function sets"); | "list available TCP Function sets"); | ||||
/* | /* | ||||
* Exports one (struct tcp_function_info) for each alias/name. | * Exports one (struct tcp_function_info) for each alias/name. | ||||
*/ | */ | ||||
static int | static int | ||||
sysctl_net_inet_list_func_info(SYSCTL_HANDLER_ARGS) | sysctl_net_inet_list_func_info(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int cnt, error; | int cnt, error; | ||||
Show All 24 Lines | |||||
counter_u64_fetch(V_tcps_states[TCPS_SYN_RECEIVED]); | counter_u64_fetch(V_tcps_states[TCPS_SYN_RECEIVED]); | ||||
error = SYSCTL_OUT(req, &xig, sizeof xig); | error = SYSCTL_OUT(req, &xig, sizeof xig); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, | SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, | ||||
CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0, | CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_NEEDGIANT, | ||||
tcp_pcblist, "S,xtcpcb", "List of active TCP connections"); | NULL, 0, tcp_pcblist, "S,xtcpcb", | ||||
"List of active TCP connections"); | |||||
#ifdef INET | #ifdef INET | ||||
static int | static int | ||||
tcp_getcred(SYSCTL_HANDLER_ARGS) | tcp_getcred(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct xucred xuc; | struct xucred xuc; | ||||
struct sockaddr_in addrs[2]; | struct sockaddr_in addrs[2]; | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
Show All 21 Lines | |||||
} else | } else | ||||
error = ENOENT; | error = ENOENT; | ||||
if (error == 0) | if (error == 0) | ||||
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); | error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, | ||||
CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, | CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT, | ||||
tcp_getcred, "S,xucred", "Get the xucred of a TCP connection"); | 0, 0, tcp_getcred, "S,xucred", | ||||
"Get the xucred of a TCP connection"); | |||||
#endif /* INET */ | #endif /* INET */ | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int | static int | ||||
tcp6_getcred(SYSCTL_HANDLER_ARGS) | tcp6_getcred(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
struct xucred xuc; | struct xucred xuc; | ||||
Show All 24 Lines | |||||
} else | } else | ||||
error = ENOENT; | error = ENOENT; | ||||
if (error == 0) | if (error == 0) | ||||
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); | error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, | SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, | ||||
CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, | CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT, | ||||
tcp6_getcred, "S,xucred", "Get the xucred of a TCP6 connection"); | 0, 0, tcp6_getcred, "S,xucred", | ||||
"Get the xucred of a TCP6 connection"); | |||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
#ifdef INET | #ifdef INET | ||||
void | void | ||||
tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) | tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) | ||||
{ | { | ||||
struct ip *ip = vip; | struct ip *ip = vip; | ||||
Show All 24 Lines | |||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
} else | } else | ||||
error = ESRCH; | error = ESRCH; | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, TCPCTL_DROP, drop, | SYSCTL_PROC(_net_inet_tcp, TCPCTL_DROP, drop, | ||||
CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP, NULL, | CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | | ||||
0, sysctl_drop, "", "Drop TCP connection"); | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_drop, "", | ||||
"Drop TCP connection"); | |||||
#ifdef KERN_TLS | #ifdef KERN_TLS | ||||
static int | static int | ||||
sysctl_switch_tls(SYSCTL_HANDLER_ARGS) | sysctl_switch_tls(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
/* addrs[0] is a foreign socket, addrs[1] is a local one. */ | /* addrs[0] is a foreign socket, addrs[1] is a local one. */ | ||||
struct sockaddr_storage addrs[2]; | struct sockaddr_storage addrs[2]; | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
Show All 24 Lines | |||||
sorele(so); | sorele(so); | ||||
} | } | ||||
} else | } else | ||||
error = ESRCH; | error = ESRCH; | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_sw_tls, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_sw_tls, | ||||
CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP, NULL, | CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | | ||||
0, sysctl_switch_tls, "", "Switch TCP connection to SW TLS"); | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_switch_tls, "", | ||||
"Switch TCP connection to SW TLS"); | |||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_ifnet_tls, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_ifnet_tls, | ||||
CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP, NULL, | CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | | ||||
1, sysctl_switch_tls, "", "Switch TCP connection to ifnet TLS"); | CTLFLAG_NEEDGIANT, NULL, 1, sysctl_switch_tls, "", | ||||
"Switch TCP connection to ifnet TLS"); | |||||
#endif | #endif | ||||
/* | /* | ||||
* Generate a standardized TCP log line for use throughout the | * Generate a standardized TCP log line for use throughout the | ||||
* tcp subsystem. Memory allocation is done with M_NOWAIT to | * tcp subsystem. Memory allocation is done with M_NOWAIT to | ||||
* allow use in the interrupt context. | * allow use in the interrupt context. | ||||
* | * | ||||
* NB: The caller MUST free(s, M_TCPLOG) the returned string. | * NB: The caller MUST free(s, M_TCPLOG) the returned string. | ||||
Show All 12 Lines |