From: Florian Westphal <fw@strlen.de>
To: <netdev@vger.kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
<netfilter-devel@vger.kernel.org>,
pablo@netfilter.org
Subject: [PATCH net 08/17] netfilter: ipset: cleanup the add/del backlog when resize failed
Date: Wed, 8 Jul 2026 16:03:00 +0200 [thread overview]
Message-ID: <20260708140309.19633-9-fw@strlen.de> (raw)
In-Reply-To: <20260708140309.19633-1-fw@strlen.de>
From: Jozsef Kadlecsik <kadlec@netfilter.org>
Sashiko pointed out that the add/del backlog was not cleaned up
when resize failed. Fix it in the corresponding error path. Also,
make sure that the add/del backlog is htable-specific so when
resize creates a new htable, old/new backlog can't be mixed up.
Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/ipset/ip_set_hash_gen.h | 28 +++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index 8104dbac02fa..c0132d0f4cc0 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -85,6 +85,7 @@ struct htable {
atomic_t uref; /* References for dumping and gc */
u8 htable_bits; /* size of hash table == 2^htable_bits */
u32 maxelem; /* Maxelem per region */
+ struct list_head ad; /* Resize add|del backlist */
struct ip_set_region *hregion; /* Region locks and ext sizes */
struct hbucket __rcu *bucket[]; /* hashtable buckets */
};
@@ -302,7 +303,6 @@ struct htype {
u8 netmask; /* netmask value for subnets to store */
union nf_inet_addr bitmask; /* stores bitmask */
#endif
- struct list_head ad; /* Resize add|del backlist */
struct mtype_elem next; /* temporary storage for uadd */
#ifdef IP_SET_HASH_WITH_NETS
struct net_prefixes nets[NLEN]; /* book-keeping of prefixes */
@@ -452,13 +452,14 @@ static void
mtype_destroy(struct ip_set *set)
{
struct htype *h = set->data;
+ struct htable *t = (__force struct htable *)h->table;
struct list_head *l, *lt;
- mtype_ahash_destroy(set, (__force struct htable *)h->table, true);
- list_for_each_safe(l, lt, &h->ad) {
+ list_for_each_safe(l, lt, &t->ad) {
list_del(l);
kfree(l);
}
+ mtype_ahash_destroy(set, t, true);
kfree(h);
set->data = NULL;
@@ -672,6 +673,7 @@ mtype_resize(struct ip_set *set, bool retried)
}
t->htable_bits = htable_bits;
t->maxelem = h->maxelem / ahash_numof_locks(htable_bits);
+ INIT_LIST_HEAD(&t->ad);
for (i = 0; i < ahash_numof_locks(htable_bits); i++)
spin_lock_init(&t->hregion[i].lock);
@@ -774,7 +776,7 @@ mtype_resize(struct ip_set *set, bool retried)
* Kernel-side add cannot trigger a resize and userspace actions
* are serialized by the mutex.
*/
- list_for_each_safe(l, lt, &h->ad) {
+ list_for_each_safe(l, lt, &orig->ad) {
x = list_entry(l, struct mtype_resize_ad, list);
if (x->ad == IPSET_ADD) {
mtype_add(set, &x->d, &x->ext, &x->mext, x->flags);
@@ -801,10 +803,21 @@ mtype_resize(struct ip_set *set, bool retried)
spin_lock_bh(&h->gc.lock);
orig->resizing = false;
spin_unlock_bh(&h->gc.lock);
+ /* Make sure parallel readers see that orig->resizing is false
+ * before we decrement uref */
+ synchronize_rcu();
atomic_dec(&orig->uref);
mtype_ahash_destroy(set, t, false);
if (ret == -EAGAIN)
goto retry;
+
+ /* Cleanup the backlog of ADD/DEL elements */
+ spin_lock_bh(&set->lock);
+ list_for_each_safe(l, lt, &orig->ad) {
+ list_del(l);
+ kfree(l);
+ }
+ spin_unlock_bh(&set->lock);
goto out;
hbwarn:
@@ -1022,7 +1035,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
memcpy(&x->mext, mext, sizeof(struct ip_set_ext));
x->flags = flags;
spin_lock_bh(&set->lock);
- list_add_tail(&x->list, &h->ad);
+ list_add_tail(&x->list, &t->ad);
spin_unlock_bh(&set->lock);
}
goto out;
@@ -1146,7 +1159,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
spin_unlock_bh(&t->hregion[r].lock);
if (x) {
spin_lock_bh(&set->lock);
- list_add(&x->list, &h->ad);
+ list_add(&x->list, &t->ad);
spin_unlock_bh(&set->lock);
}
if (atomic_dec_and_test(&t->uref) && t->resizing) {
@@ -1625,9 +1638,8 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
}
t->htable_bits = hbits;
t->maxelem = h->maxelem / ahash_numof_locks(hbits);
+ INIT_LIST_HEAD(&t->ad);
RCU_INIT_POINTER(h->table, t);
-
- INIT_LIST_HEAD(&h->ad);
set->data = h;
#ifndef IP_SET_PROTO_UNDEF
if (set->family == NFPROTO_IPV4) {
--
2.54.0
next prev parent reply other threads:[~2026-07-08 14:03 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 14:02 [PATCH net 00/17] netfilter: updates for net Florian Westphal
2026-07-08 14:02 ` [PATCH net 01/17] netfilter: nf_conntrack_reasm: guard mac_header adjustment after IPv6 defrag Florian Westphal
2026-07-09 9:50 ` patchwork-bot+netdevbpf
2026-07-08 14:02 ` [PATCH net 02/17] netfilter: ebtables: terminate table name before find_table_lock() Florian Westphal
2026-07-08 14:02 ` [PATCH net 03/17] netfilter: ebtables: zero chainstack array Florian Westphal
2026-07-08 14:02 ` [PATCH net 04/17] netfilter: ebtables: module names must be null-terminated Florian Westphal
2026-07-08 14:02 ` [PATCH net 05/17] netfilter: nft_lookup: fix catchall element handling with inverted lookups Florian Westphal
2026-07-08 14:02 ` [PATCH net 06/17] netfilter: ipset: mark the rcu locked areas properly Florian Westphal
2026-07-08 14:02 ` [PATCH net 07/17] netfilter: ipset: exclude gc when resize is in progress Florian Westphal
2026-07-08 14:03 ` Florian Westphal [this message]
2026-07-08 14:03 ` [PATCH net 09/17] netfilter: ipset: allocate the proper memory for the generic hash structure Florian Westphal
2026-07-08 14:03 ` [PATCH net 10/17] netfilter: flowtable: use dst in this direction when pushing IPIP header Florian Westphal
2026-07-08 14:03 ` [PATCH net 11/17] netfilter: flowtable: IPIP tunnel hardware offload is not yet support Florian Westphal
2026-07-08 14:03 ` [PATCH net 12/17] netfilter: flowtable: support IPIP tunnel with direct xmit Florian Westphal
2026-07-08 14:03 ` [PATCH net 13/17] netfilter: handle unreadable frags Florian Westphal
2026-07-08 14:03 ` [PATCH net 14/17] ipvs: pass parsed transport offset to state handlers Florian Westphal
2026-07-08 14:03 ` [PATCH net 15/17] ipvs: use parsed transport offset in TCP state lookup Florian Westphal
2026-07-08 14:03 ` [PATCH net 16/17] ipvs: use parsed transport offset in SCTP " Florian Westphal
2026-07-08 14:03 ` [PATCH net 17/17] ipvs: ensure inner headers in ICMP errors are in headroom Florian Westphal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260708140309.19633-9-fw@strlen.de \
--to=fw@strlen.de \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox