Thread (2 messages) 2 messages, 2 authors, 3d ago

[PATCH bpf v2 1/1] tcp_bpf: update copied_seq from current value

flat view
WARM3d

From: Zhiling Zou <hidden>
Date: 2026-10-27 04:59:05
Also in: bpf
Subsystem: bpf [l7 framework] (sockmap), networking [general], networking [tcp], the rest · Maintainers: John Fastabend, Jakub Sitnicki, Jiayuan Chen, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Neal Cardwell, Linus Torvalds

tcp_bpf_recvmsg_parser() snapshots tcp->copied_seq before processing
queued data and waiting for more. tcp_data_ready() and
tcp_msg_wait_data() can release the socket lock. While it is released,
a sockmap verdict can drop or redirect data and advance copied_seq. At
exit, writing back the old snapshot plus copied_from_self rewinds that
progress, leaving ordinary TCP receive behind queued data.

Keep copied_from_self as the count of bytes consumed from this socket,
but add it to the current tcp->copied_seq at exit instead of writing
back a stale snapshot. Count the FIN byte in copied_from_self as well.

Fixes: e5c6de5fa025 ("bpf, sockmap: Incorrectly handling copied_seq")
Cc: <redacted>
Reported-by: Vega <redacted>
Suggested-by: Alexei Starovoitov <redacted>
Assisted-by: LLM
Signed-off-by: Zhiling Zou <redacted>
---
changes in v2:
  - Update copied_seq relative to its current value at exit, preserving
    progress made while tcp_msg_wait_data() releases the socket lock.
  - Count the FIN sequence byte in copied_from_self.
  - v1 Link: https://lore.kernel.org/all/af73f81ba5060272e63bfe3757295fb09f5c6198.1792733621.git.zhilinz@nebusec.ai/ (local)

 net/ipv4/tcp_bpf.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index 2e234d155b5e6..fee7bd72cc272 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -228,7 +228,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
 	struct tcp_sock *tcp;
 	int copied_from_self = 0;
 	int copied = 0;
-	u32 seq;
 
 	if (unlikely(flags & MSG_ERRQUEUE))
 		return inet_recv_error(sk, msg, len);
@@ -242,7 +241,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
 
 	lock_sock(sk);
 	tcp = tcp_sk(sk);
-	seq = tcp->copied_seq;
 	/* We may have received data on the sk_receive_queue pre-accept and
 	 * then we can not use read_skb in this context because we haven't
 	 * assigned a sk_socket yet so have no link to the ops. The work-around
@@ -274,11 +272,10 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
 
 		if (is_fin) {
 			copied = 0;
-			seq++;
+			copied_from_self++;
 			goto out;
 		}
 	}
-	seq += copied_from_self;
 	if (!copied) {
 		long timeo;
 		int data;
@@ -321,7 +318,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
 	}
 out:
 	if (!peek)
-		WRITE_ONCE(tcp->copied_seq, seq);
+		WRITE_ONCE(tcp->copied_seq, tcp->copied_seq + copied_from_self);
 	tcp_rcv_space_adjust(sk);
 	if (copied > 0)
 		__tcp_cleanup_rbuf(sk, copied);
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help