diff options
author | Eric Dumazet <edumazet@google.com> | 2025-03-12 11:22:50 +0300 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2025-03-18 15:18:36 +0300 |
commit | ca0359df45a55a9eb4d6dc09a481064abf78320f (patch) | |
tree | 4a9e6bcd4806324cfaf4b4b67f0fd082d99ae4cb /net/ipv6/netfilter | |
parent | eb0dfc0ef195a04e519b15d73cf25d8c25ee8df7 (diff) | |
download | linux-ca0359df45a55a9eb4d6dc09a481064abf78320f.tar.xz |
inet: frags: save a pair of atomic operations in reassembly
As mentioned in commit 648700f76b03 ("inet: frags:
use rhashtables for reassembly units"):
A followup patch will even remove the refcount hold/release
left from prior implementation and save a couple of atomic
operations.
This patch implements this idea, seven years later.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20250312082250.1803501-5-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/ipv6/netfilter')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index f33acb730dc5..d6bd8f7079bb 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -450,7 +450,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) struct frag_hdr *fhdr; struct frag_queue *fq; struct ipv6hdr *hdr; - int refs = 1; + int refs = 0; u8 prevhdr; /* Jumbo payload inhibits frag. header */ @@ -477,9 +477,11 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) hdr = ipv6_hdr(skb); fhdr = (struct frag_hdr *)skb_transport_header(skb); + rcu_read_lock(); fq = fq_find(net, fhdr->identification, user, hdr, skb->dev ? skb->dev->ifindex : 0); if (fq == NULL) { + rcu_read_unlock(); pr_debug("Can't find and can't create new queue\n"); return -ENOMEM; } @@ -493,6 +495,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) } spin_unlock_bh(&fq->q.lock); + rcu_read_unlock(); inet_frag_putn(&fq->q, refs); return ret; } |