Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_usrreq.c
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include "opt_inet.h" | #include "opt_inet.h" | ||||
#include "opt_inet6.h" | #include "opt_inet6.h" | ||||
#include "opt_ipsec.h" | #include "opt_ipsec.h" | ||||
#include "opt_kern_tls.h" | #include "opt_kern_tls.h" | ||||
#include "opt_tcpdebug.h" | #include "opt_tcpdebug.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/arb.h> | |||||
#include <sys/limits.h> | #include <sys/limits.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/refcount.h> | #include <sys/refcount.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/ktls.h> | #include <sys/ktls.h> | ||||
#include <sys/qmath.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#ifdef INET6 | #ifdef INET6 | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/socketvar.h> | #include <sys/socketvar.h> | ||||
#include <sys/protosw.h> | #include <sys/protosw.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <sys/stats.h> | |||||
#ifdef DDB | #ifdef DDB | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
#endif | #endif | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
Show All 27 Lines | |||||
#ifdef TCPDEBUG | #ifdef TCPDEBUG | ||||
#include <netinet/tcp_debug.h> | #include <netinet/tcp_debug.h> | ||||
#endif | #endif | ||||
#ifdef TCP_OFFLOAD | #ifdef TCP_OFFLOAD | ||||
#include <netinet/tcp_offload.h> | #include <netinet/tcp_offload.h> | ||||
#endif | #endif | ||||
#include <netipsec/ipsec_support.h> | #include <netipsec/ipsec_support.h> | ||||
#include <vm/vm.h> | |||||
#include <vm/vm_param.h> | |||||
#include <vm/pmap.h> | |||||
#include <vm/vm_extern.h> | |||||
#include <vm/vm_map.h> | |||||
#include <vm/vm_page.h> | |||||
/* | /* | ||||
* TCP protocol interface to socket abstraction. | * TCP protocol interface to socket abstraction. | ||||
*/ | */ | ||||
static int tcp_attach(struct socket *); | static int tcp_attach(struct socket *); | ||||
#ifdef INET | #ifdef INET | ||||
static int tcp_connect(struct tcpcb *, struct sockaddr *, | static int tcp_connect(struct tcpcb *, struct sockaddr *, | ||||
struct thread *td); | struct thread *td); | ||||
#endif /* INET */ | #endif /* INET */ | ||||
▲ Show 20 Lines • Show All 1,692 Lines • ▼ Show 20 Lines | tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp) | ||||
int error, opt, optval; | int error, opt, optval; | ||||
u_int ui; | u_int ui; | ||||
struct tcp_info ti; | struct tcp_info ti; | ||||
#ifdef KERN_TLS | #ifdef KERN_TLS | ||||
struct tls_enable tls; | struct tls_enable tls; | ||||
#endif | #endif | ||||
struct cc_algo *algo; | struct cc_algo *algo; | ||||
char *pbuf, buf[TCP_LOG_ID_LEN]; | char *pbuf, buf[TCP_LOG_ID_LEN]; | ||||
#ifdef STATS | |||||
struct statsblob *sbp; | |||||
#endif | |||||
size_t len; | size_t len; | ||||
/* | /* | ||||
* For TCP_CCALGOOPT forward the control to CC module, for both | * For TCP_CCALGOOPT forward the control to CC module, for both | ||||
* SOPT_SET and SOPT_GET. | * SOPT_SET and SOPT_GET. | ||||
*/ | */ | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case TCP_CCALGOOPT: | case TCP_CCALGOOPT: | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | case TCP_MAXSEG: | ||||
error = EINVAL; | error = EINVAL; | ||||
goto unlock_and_done; | goto unlock_and_done; | ||||
case TCP_INFO: | case TCP_INFO: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
case TCP_STATS: | |||||
INP_WUNLOCK(inp); | |||||
#ifdef STATS | |||||
error = sooptcopyin(sopt, &optval, sizeof optval, | |||||
sizeof optval); | |||||
if (error) | |||||
return (error); | |||||
if (optval > 0) | |||||
sbp = stats_blob_alloc( | |||||
V_tcp_perconn_stats_dflt_tpl, 0); | |||||
else | |||||
sbp = NULL; | |||||
INP_WLOCK_RECHECK(inp); | |||||
if ((tp->t_stats != NULL && sbp == NULL) || | |||||
(tp->t_stats == NULL && sbp != NULL)) { | |||||
struct statsblob *t = tp->t_stats; | |||||
tp->t_stats = sbp; | |||||
sbp = t; | |||||
} | |||||
INP_WUNLOCK(inp); | |||||
stats_blob_destroy(sbp); | |||||
#else | |||||
return (EOPNOTSUPP); | |||||
#endif /* !STATS */ | |||||
break; | |||||
case TCP_CONGESTION: | case TCP_CONGESTION: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX - 1, 1); | error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX - 1, 1); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
buf[sopt->sopt_valsize] = '\0'; | buf[sopt->sopt_valsize] = '\0'; | ||||
INP_WLOCK_RECHECK(inp); | INP_WLOCK_RECHECK(inp); | ||||
CC_LIST_RLOCK(); | CC_LIST_RLOCK(); | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | case TCP_NOPUSH: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = sooptcopyout(sopt, &optval, sizeof optval); | error = sooptcopyout(sopt, &optval, sizeof optval); | ||||
break; | break; | ||||
case TCP_INFO: | case TCP_INFO: | ||||
tcp_fill_info(tp, &ti); | tcp_fill_info(tp, &ti); | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = sooptcopyout(sopt, &ti, sizeof ti); | error = sooptcopyout(sopt, &ti, sizeof ti); | ||||
break; | break; | ||||
case TCP_STATS: | |||||
{ | |||||
#ifdef STATS | |||||
int nheld; | |||||
TYPEOF_MEMBER(struct statsblob, flags) sbflags = 0; | |||||
error = 0; | |||||
socklen_t outsbsz = sopt->sopt_valsize; | |||||
if (tp->t_stats == NULL) | |||||
error = ENOENT; | |||||
else if (outsbsz >= tp->t_stats->cursz) | |||||
outsbsz = tp->t_stats->cursz; | |||||
else if (outsbsz >= sizeof(struct statsblob)) | |||||
outsbsz = sizeof(struct statsblob); | |||||
else | |||||
error = EINVAL; | |||||
INP_WUNLOCK(inp); | |||||
if (error) | |||||
break; | |||||
sbp = sopt->sopt_val; | |||||
nheld = atop(round_page(((vm_offset_t)sbp) + | |||||
(vm_size_t)outsbsz) - trunc_page((vm_offset_t)sbp)); | |||||
vm_page_t ma[nheld]; | |||||
if (vm_fault_quick_hold_pages( | |||||
&curproc->p_vmspace->vm_map, (vm_offset_t)sbp, | |||||
outsbsz, VM_PROT_READ | VM_PROT_WRITE, ma, | |||||
nheld) < 0) { | |||||
error = EFAULT; | |||||
break; | |||||
} | |||||
if ((error = copyin_nofault(&(sbp->flags), &sbflags, | |||||
SIZEOF_MEMBER(struct statsblob, flags)))) | |||||
goto unhold; | |||||
INP_WLOCK_RECHECK(inp); | |||||
error = stats_blob_snapshot(&sbp, outsbsz, tp->t_stats, | |||||
sbflags | SB_CLONE_USRDSTNOFAULT); | |||||
INP_WUNLOCK(inp); | |||||
sopt->sopt_valsize = outsbsz; | |||||
unhold: | |||||
vm_page_unhold_pages(ma, nheld); | |||||
#else | |||||
INP_WUNLOCK(inp); | |||||
error = EOPNOTSUPP; | |||||
#endif /* !STATS */ | |||||
break; | |||||
} | |||||
case TCP_CONGESTION: | case TCP_CONGESTION: | ||||
len = strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX); | len = strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX); | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = sooptcopyout(sopt, buf, len + 1); | error = sooptcopyout(sopt, buf, len + 1); | ||||
break; | break; | ||||
case TCP_KEEPIDLE: | case TCP_KEEPIDLE: | ||||
case TCP_KEEPINTVL: | case TCP_KEEPINTVL: | ||||
case TCP_KEEPINIT: | case TCP_KEEPINIT: | ||||
▲ Show 20 Lines • Show All 551 Lines • Show Last 20 Lines |