Re: [PATCH net-next v2 2/6] net: Introduce read_sock_rectype proto_ops for control record delivery
Hannes Reinecke <[email protected]> Thu, 23 Jul 2026 09:14:17 +0200
| Newsgroups | dev.linux.lists.kernel-tls-handshake,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-nfs,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On 7/20/26 4:27 PM, Chuck Lever wrote: > From: Chuck Lever <[email protected]> > > Kernel TCP consumers that use the read_sock interface > (proto_ops.read_sock) cannot receive TLS control messages (Alerts, > Handshake records) when kTLS is active. The current > tls_sw_read_sock() method rejects non-data records with -EINVAL, and > the sk_read_actor_t callback has no channel for delivering record- > type metadata. > > Four kernel subsystems are affected: NFSD (sunrpc svcsock), NFS > client (sunrpc xprtsock), NVMe target (nvmet-tcp), and NVMe host > (nvme-tcp). Each of these either falls back to the sock_recvmsg() > API or lacks TLS alert handling entirely. > > A new read_sock_rectype method in struct proto_ops provides a > separate code path that delivers non-data TLS records to a callback, > without changing the behavior seen by existing read_sock consumers. > > The new sk_read_rectype_actor_t callback type extends the > sk_read_actor_t signature with a rectype parameter carrying the > protocol-layer record type (for example, TLS_RECORD_TYPE_ALERT). The > record-type callback returns 0 to consume a record or a negative > value to requeue it and stop delivery; unlike the data callback, its > return value does not count bytes. > > Signed-off-by: Chuck Lever <[email protected]> > --- > include/linux/net.h | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/include/linux/net.h b/include/linux/net.h > index 277188a40c72..7a19a743a617 100644 > --- a/include/linux/net.h > +++ b/include/linux/net.h > @@ -198,6 +198,13 @@ struct sk_buff; > struct proto_accept_arg; > typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, > unsigned int, size_t); > +/* rectype carries the transport record type, for example a > + * TLS_RECORD_TYPE_* value. > + */ > +typedef int (*sk_read_rectype_actor_t)(read_descriptor_t *, > + struct sk_buff *, > + unsigned int, size_t, > + u8 rectype); > typedef int (*skb_read_actor_t)(struct sock *, struct sk_buff *); > > > @@ -264,6 +271,27 @@ struct proto_ops { > */ > int (*read_sock)(struct sock *sk, read_descriptor_t *desc, > sk_read_actor_t recv_actor); > + /* > + * read_sock_rectype splits delivery across two callbacks: > + * recv_actor for data records, per the sk_read_actor_t > + * convention, and rectype_actor for all other records, > + * with rectype identifying each. A NULL rectype_actor > + * leaves non-data records pending. rectype_actor returns 0 > + * to consume a record or negative to leave it pending for > + * redelivery and stop delivery; the negative return is a > + * backpressure signal, not a fatal error. Both callbacks > + * report errors and early stop the way recv_actor does: > + * by setting desc->count to 0 and recording the reason in > + * desc->error, per the read_descriptor_t convention and > + * independent of the return value. The return value reports > + * only data bytes consumed by recv_actor; the caller > + * detects an error or early stop via desc->count and > + * desc->error. > + */ > + int (*read_sock_rectype)(struct sock *sk, > + read_descriptor_t *desc, > + sk_read_actor_t recv_actor, > + sk_read_rectype_actor_t rectype_actor); > /* This is different from read_sock(), it reads an entire skb at a time. */ > int (*read_skb)(struct sock *sk, skb_read_actor_t recv_actor); > int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg, > Naming is a bit odd, but hey. Reviewed-by: Hannes Reinecke <[email protected]> Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich