summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-11-20 19:17:06 +0300
committerSasha Levin <sashal@kernel.org>2026-03-04 15:20:09 +0300
commit79b713ef4261a8ead96af4703f89d0b5f25532e2 (patch)
tree11a620c34cfad587cda95c810125ace958a964fa /include/net
parent371de2bef6582a3f58049b3d18e190924af9c9a0 (diff)
downloadlinux-79b713ef4261a8ead96af4703f89d0b5f25532e2.tar.xz
netfilter: nfnetlink_queue: do shared-unconfirmed check before segmentation
[ Upstream commit 207b3ebacb6113acaaec0d171d5307032c690004 ] Ulrich reports a regression with nfqueue: If an application did not set the 'F_GSO' capability flag and a gso packet with an unconfirmed nf_conn entry is received all packets are now dropped instead of queued, because the check happens after skb_gso_segment(). In that case, we did have exclusive ownership of the skb and its associated conntrack entry. The elevated use count is due to skb_clone happening via skb_gso_segment(). Move the check so that its peformed vs. the aggregated packet. Then, annotate the individual segments except the first one so we can do a 2nd check at reinject time. For the normal case, where userspace does in-order reinjects, this avoids packet drops: first reinjected segment continues traversal and confirms entry, remaining segments observe the confirmed entry. While at it, simplify nf_ct_drop_unconfirmed(): We only care about unconfirmed entries with a refcnt > 1, there is no need to special-case dying entries. This only happens with UDP. With TCP, the only unconfirmed packet will be the TCP SYN, those aren't aggregated by GRO. Next patch adds a udpgro test case to cover this scenario. Reported-by: Ulrich Weber <ulrich.weber@gmail.com> Fixes: 7d8dc1c7be8d ("netfilter: nf_queue: drop packets with cloned unconfirmed conntracks") Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/netfilter/nf_queue.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index e6803831d6af..45eb26b2e95b 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h
@@ -21,6 +21,7 @@ struct nf_queue_entry {
struct net_device *physout;
#endif
struct nf_hook_state state;
+ bool nf_ct_is_unconfirmed;
u16 size; /* sizeof(entry) + saved route keys */
u16 queue_num;