[PATCH 5/8] SUNRPC: fold svc_tcp_sock_process_cmsg() into its only caller
Chuck Lever <[email protected]> Wed, 05 Aug 2026 14:30:56 -0400
| Newsgroups | gmane.linux.nfs,gmane.linux.network |
|---|---|
| Message-ID | <[email protected]> |
svc_tcp_sock_process_cmsg() switches on the TLS record type. svc_tcp_sock_recv_cmsg() now returns -EAGAIN for every record type except an alert before it calls the helper. The case 0, TLS_RECORD_TYPE_DATA, and default arms are unreachable. The DATA arm is inert twice over. It clears MSG_EOR in the msghdr local to svc_tcp_sock_recv_cmsg(), and that msghdr is discarded on return. svc_tcp_sock_recvmsg() has already cleared the flag in the caller's msghdr. Deriving the record type a second time inside the helper also fires trace_tls_contenttype() twice for every alert. Move the alert handling into svc_tcp_sock_recv_cmsg() and delete the helper. The DATA arm's account of MSG_EOR moves to svc_tcp_sock_recvmsg(), where the flag is now cleared. Signed-off-by: Chuck Lever <[email protected]> --- net/sunrpc/svcsock.c | 58 ++++++++++++++++------------------------------------ 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d8e836e0832e..6ed136dff0a4 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -271,45 +271,6 @@ svc_tcp_sock_drain_record(struct socket *sock) } } -static int -svc_tcp_sock_process_cmsg(struct socket *sock, struct msghdr *msg, - struct cmsghdr *cmsg, int ret) -{ - u8 content_type = tls_get_record_type(sock->sk, cmsg); - u8 level, description; - - switch (content_type) { - case 0: - break; - case TLS_RECORD_TYPE_DATA: - /* TLS sets EOR at the end of each application data - * record, even though there might be more frames - * waiting to be decrypted. - */ - msg->msg_flags &= ~MSG_EOR; - break; - case TLS_RECORD_TYPE_ALERT: - tls_alert_recv(sock->sk, msg, &level, &description); - /* RFC 8446 Section 6: every alert but a closure alert is - * an error alert, whatever the legacy AlertLevel octet - * says. - */ - switch (description) { - case TLS_ALERT_DESC_CLOSE_NOTIFY: - case TLS_ALERT_DESC_USER_CANCELED: - ret = -EAGAIN; - break; - default: - ret = -ENOTCONN; - } - break; - default: - /* discard this record type */ - ret = -EAGAIN; - } - return ret; -} - static int svc_tcp_sock_recv_cmsg(struct socket *sock, unsigned int *msg_flags) { @@ -327,6 +288,7 @@ svc_tcp_sock_recv_cmsg(struct socket *sock, unsigned int *msg_flags) .msg_control = &u, .msg_controllen = sizeof(u), }; + u8 level, description; int ret; iov_iter_kvec(&msg.msg_iter, ITER_DEST, &alert_kvec, 1, @@ -358,7 +320,19 @@ svc_tcp_sock_recv_cmsg(struct socket *sock, unsigned int *msg_flags) if (ret != sizeof(alert) || !(msg.msg_flags & MSG_EOR)) return -EBADMSG; iov_iter_revert(&msg.msg_iter, ret); - ret = svc_tcp_sock_process_cmsg(sock, &msg, &u.cmsg, -EAGAIN); + tls_alert_recv(sock->sk, &msg, &level, &description); + /* RFC 8446 Section 6: every alert but a closure alert is + * an error alert, whatever the legacy AlertLevel octet + * says. + */ + switch (description) { + case TLS_ALERT_DESC_CLOSE_NOTIFY: + case TLS_ALERT_DESC_USER_CANCELED: + ret = -EAGAIN; + break; + default: + ret = -ENOTCONN; + } } return ret; } @@ -371,6 +345,10 @@ svc_tcp_sock_recvmsg(struct svc_sock *svsk, struct msghdr *msg) ret = sock_recvmsg(sock, msg, MSG_DONTWAIT); if (msg->msg_flags & MSG_CTRUNC) { + /* TLS sets EOR at the end of each application data + * record, even though there might be more frames + * waiting to be decrypted. + */ msg->msg_flags &= ~(MSG_CTRUNC | MSG_EOR); if (ret == 0 || ret == -EIO) { ret = svc_tcp_sock_recv_cmsg(sock, &msg->msg_flags); -- 2.54.0