Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_usrreq.c
Context not available. | |||||
#include <netinet/tcp_seq.h> | #include <netinet/tcp_seq.h> | ||||
#include <netinet/tcp_timer.h> | #include <netinet/tcp_timer.h> | ||||
#include <netinet/tcp_var.h> | #include <netinet/tcp_var.h> | ||||
#include <netinet/tcp_log_buf.h> | |||||
#include <netinet/tcpip.h> | #include <netinet/tcpip.h> | ||||
#include <netinet/cc/cc.h> | #include <netinet/cc/cc.h> | ||||
#ifdef TCPPCAP | #ifdef TCPPCAP | ||||
Context not available. | |||||
return (tp->t_fb->tfb_tcp_ctloutput(so, sopt, inp, tp)); | return (tp->t_fb->tfb_tcp_ctloutput(so, sopt, inp, tp)); | ||||
} | } | ||||
/* | |||||
* If this assert becomes untrue, we need to change the size of the buf | |||||
* variable in tcp_default_ctloutput(). | |||||
*/ | |||||
#ifdef CTASSERT | |||||
CTASSERT(TCP_CA_NAME_MAX <= TCP_LOG_ID_LEN); | |||||
CTASSERT(TCP_LOG_REASON_LEN <= TCP_LOG_ID_LEN); | |||||
#endif | |||||
int | int | ||||
tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp) | tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp) | ||||
{ | { | ||||
Context not available. | |||||
u_int ui; | u_int ui; | ||||
struct tcp_info ti; | struct tcp_info ti; | ||||
struct cc_algo *algo; | struct cc_algo *algo; | ||||
char *pbuf, buf[TCP_CA_NAME_MAX]; | char *pbuf, buf[TCP_LOG_ID_LEN]; | ||||
size_t len; | size_t len; | ||||
/* | /* | ||||
Context not available. | |||||
goto unlock_and_done; | goto unlock_and_done; | ||||
#endif | #endif | ||||
case TCP_LOG: | |||||
INP_WUNLOCK(inp); | |||||
error = sooptcopyin(sopt, &optval, sizeof optval, | |||||
sizeof optval); | |||||
if (error) | |||||
return (error); | |||||
INP_WLOCK_RECHECK(inp); | |||||
error = tcp_log_state_change(tp, optval); | |||||
goto unlock_and_done; | |||||
case TCP_LOGBUF: | |||||
INP_WUNLOCK(inp); | |||||
error = EINVAL; | |||||
break; | |||||
case TCP_LOGID: | |||||
INP_WUNLOCK(inp); | |||||
error = sooptcopyin(sopt, buf, TCP_LOG_ID_LEN - 1, 0); | |||||
if (error) | |||||
break; | |||||
buf[sopt->sopt_valsize] = '\0'; | |||||
INP_WLOCK_RECHECK(inp); | |||||
error = tcp_log_set_id(tp, buf); | |||||
/* tcp_log_set_id() unlocks the INP. */ | |||||
break; | |||||
case TCP_LOGDUMP: | |||||
case TCP_LOGDUMPID: | |||||
INP_WUNLOCK(inp); | |||||
error = | |||||
sooptcopyin(sopt, buf, TCP_LOG_REASON_LEN - 1, 0); | |||||
if (error) | |||||
break; | |||||
buf[sopt->sopt_valsize] = '\0'; | |||||
INP_WLOCK_RECHECK(inp); | |||||
if (sopt->sopt_name == TCP_LOGDUMP) { | |||||
error = tcp_log_dump_tp_logbuf(tp, buf, | |||||
M_WAITOK, true); | |||||
INP_WUNLOCK(inp); | |||||
} else { | |||||
tcp_log_dump_tp_bucket_logbufs(tp, buf); | |||||
/* | |||||
* tcp_log_dump_tp_bucket_logbufs() drops the | |||||
* INP lock. | |||||
*/ | |||||
} | |||||
break; | |||||
default: | default: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = ENOPROTOOPT; | error = ENOPROTOOPT; | ||||
Context not available. | |||||
error = sooptcopyout(sopt, &optval, sizeof optval); | error = sooptcopyout(sopt, &optval, sizeof optval); | ||||
break; | break; | ||||
#endif | #endif | ||||
case TCP_LOG: | |||||
optval = tp->t_logstate; | |||||
INP_WUNLOCK(inp); | |||||
error = sooptcopyout(sopt, &optval, sizeof(optval)); | |||||
break; | |||||
case TCP_LOGBUF: | |||||
/* tcp_log_getlogbuf() does INP_WUNLOCK(inp) */ | |||||
error = tcp_log_getlogbuf(sopt, tp); | |||||
break; | |||||
case TCP_LOGID: | |||||
len = tcp_log_get_id(tp, buf); | |||||
INP_WUNLOCK(inp); | |||||
error = sooptcopyout(sopt, buf, len + 1); | |||||
break; | |||||
case TCP_LOGDUMP: | |||||
case TCP_LOGDUMPID: | |||||
INP_WUNLOCK(inp); | |||||
error = EINVAL; | |||||
break; | |||||
default: | default: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
error = ENOPROTOOPT; | error = ENOPROTOOPT; | ||||
Context not available. |