[RFC net-next 06/17] mptcp: implement peek_len for proto_ops
From: Geliang Tang <geliang@kernel.org>
Date: 2026-06-22 10:44:44
Also in:
mptcp
Subsystem:
networking [general], networking [mptcp], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthieu Baerts, Mat Martineau, Linus Torvalds
From: Geliang Tang <redacted> The TLS stack uses tcp_inq() to query the amount of data available in the receive queue without consuming it. For MPTCP sockets, this information is not directly available from a TCP subflow; it must be computed from the MPTCP receive queue and the current mapping. Introduce mptcp_peek_len() which returns the number of bytes that can be peeked from the MPTCP socket. It reuses the existing mptcp_inq() helper (used by ioctl SIOCINQ). The implementation considers the first skb in the receive queue, the current ack_seq, and handles the FIN case. Assign .peek_len in both mptcp_stream_ops and mptcp_v6_stream_ops so that upper layers (e.g., TLS) can obtain the correct in-queue byte count for an MPTCP connection. Co-developed-by: Gang Yan <redacted> Signed-off-by: Gang Yan <redacted> Co-developed-by: Zqiang <qiang.zhang@linux.dev> Signed-off-by: Zqiang <qiang.zhang@linux.dev> Signed-off-by: Geliang Tang <redacted> --- net/mptcp/protocol.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 7f0c560f6b7e..18c8b6c64c3f 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c@@ -4689,6 +4689,38 @@ static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos, return ret; } +static int mptcp_inq(struct sock *sk) +{ + const struct mptcp_sock *msk = mptcp_sk(sk); + const struct sk_buff *skb; + + if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) + return 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb) { + u64 answ = READ_ONCE(msk->ack_seq) - MPTCP_SKB_CB(skb)->map_seq; + + if (answ >= INT_MAX) + answ = INT_MAX; + + /* Subtract 1, if FIN was received */ + if (answ && + (sk->sk_state == TCP_CLOSE || + (sk->sk_shutdown & RCV_SHUTDOWN))) + answ--; + + return (int)answ; + } + + return 0; +} + +static int mptcp_peek_len(struct socket *sock) +{ + return mptcp_inq(sock->sk); +} + static const struct proto_ops mptcp_stream_ops = { .family = PF_INET, .owner = THIS_MODULE,
@@ -4712,6 +4744,7 @@ static const struct proto_ops mptcp_stream_ops = { .read_sock = mptcp_read_sock, .splice_read = mptcp_splice_read, .sendmsg_locked = mptcp_sendmsg_locked, + .peek_len = mptcp_peek_len, }; static struct inet_protosw mptcp_protosw = {
@@ -4825,6 +4858,7 @@ static const struct proto_ops mptcp_v6_stream_ops = { .read_sock = mptcp_read_sock, .splice_read = mptcp_splice_read, .sendmsg_locked = mptcp_sendmsg_locked, + .peek_len = mptcp_peek_len, }; static struct proto mptcp_v6_prot;
--
2.53.0