ktls: Fix error/mode confusion in TCP_*TLS_MODE getsockopt handlers

ktls_get_(rx|tx)_mode() can return an errno value or a TLS mode, so
errors are effectively hidden.  Fix this by using a separate output
parameter.  Convert to the new socket buffer locking macros while here.

Note that the socket buffer lock is not needed to synchronize the
SOLISTENING check here, we can rely on the PCB lock.

Reviewed by:	jhb
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D31977
This commit is contained in:
Mark Johnston 2021-09-17 12:14:29 -04:00
parent d6e77cda9b
commit bf25678226
3 changed files with 22 additions and 20 deletions

View File

@ -1199,45 +1199,43 @@ ktls_enable_tx(struct socket *so, struct tls_enable *en)
}
int
ktls_get_rx_mode(struct socket *so)
ktls_get_rx_mode(struct socket *so, int *modep)
{
struct ktls_session *tls;
struct inpcb *inp;
int mode;
if (SOLISTENING(so))
return (EINVAL);
inp = so->so_pcb;
INP_WLOCK_ASSERT(inp);
SOCKBUF_LOCK(&so->so_rcv);
SOCK_RECVBUF_LOCK(so);
tls = so->so_rcv.sb_tls_info;
if (tls == NULL)
mode = TCP_TLS_MODE_NONE;
*modep = TCP_TLS_MODE_NONE;
else
mode = tls->mode;
SOCKBUF_UNLOCK(&so->so_rcv);
return (mode);
*modep = tls->mode;
SOCK_RECVBUF_UNLOCK(so);
return (0);
}
int
ktls_get_tx_mode(struct socket *so)
ktls_get_tx_mode(struct socket *so, int *modep)
{
struct ktls_session *tls;
struct inpcb *inp;
int mode;
if (SOLISTENING(so))
return (EINVAL);
inp = so->so_pcb;
INP_WLOCK_ASSERT(inp);
SOCKBUF_LOCK(&so->so_snd);
SOCK_SENDBUF_LOCK(so);
tls = so->so_snd.sb_tls_info;
if (tls == NULL)
mode = TCP_TLS_MODE_NONE;
*modep = TCP_TLS_MODE_NONE;
else
mode = tls->mode;
SOCKBUF_UNLOCK(&so->so_snd);
return (mode);
*modep = tls->mode;
SOCK_SENDBUF_UNLOCK(so);
return (0);
}
/*

View File

@ -2563,14 +2563,18 @@ unhold:
#endif
#ifdef KERN_TLS
case TCP_TXTLS_MODE:
optval = ktls_get_tx_mode(so);
error = ktls_get_tx_mode(so, &optval);
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, &optval, sizeof(optval));
if (error == 0)
error = sooptcopyout(sopt, &optval,
sizeof(optval));
break;
case TCP_RXTLS_MODE:
optval = ktls_get_rx_mode(so);
error = ktls_get_rx_mode(so, &optval);
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, &optval, sizeof(optval));
if (error == 0)
error = sooptcopyout(sopt, &optval,
sizeof(optval));
break;
#endif
case TCP_LRD:

View File

@ -212,9 +212,9 @@ void ktls_frame(struct mbuf *m, struct ktls_session *tls, int *enqueue_cnt,
void ktls_seq(struct sockbuf *sb, struct mbuf *m);
void ktls_enqueue(struct mbuf *m, struct socket *so, int page_count);
void ktls_enqueue_to_free(struct mbuf *m);
int ktls_get_rx_mode(struct socket *so);
int ktls_get_rx_mode(struct socket *so, int *modep);
int ktls_set_tx_mode(struct socket *so, int mode);
int ktls_get_tx_mode(struct socket *so);
int ktls_get_tx_mode(struct socket *so, int *modep);
int ktls_output_eagain(struct inpcb *inp, struct ktls_session *tls);
#ifdef RATELIMIT
int ktls_modify_txrtlmt(struct ktls_session *tls, uint64_t max_pacing_rate);