[PATCH nf-next 2/9] netfilter: nf_tables: decrement element counters on set removal/flush

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Not a bug fix, idea is that this allows us to add runtime assertions,
when set is free'd counter should be 0 as well.

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 net/netfilter/nf_tables_api.c  | 5 +++++
 net/netfilter/nft_set_bitmap.c | 5 ++++-
 net/netfilter/nft_set_hash.c   | 6 ++++++
 net/netfilter/nft_set_pipapo.c | 2 ++
 net/netfilter/nft_set_rbtree.c | 2 ++
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index be8254d31988..bac5847a5499 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5261,6 +5261,10 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
 static void nft_set_put(struct nft_set *set)
 {
 	if (refcount_dec_and_test(&set->refs)) {
+		unsigned int nelems = atomic_read(&set->nelems);
+
+		WARN(nelems, "set %s (%ps) has element count of %u\n",
+		     set->name, set->ops->lookup, nelems);
 		kfree(set->name);
 		kvfree(set);
 	}
@@ -9663,6 +9667,7 @@ static void nft_trans_gc_trans_free(struct rcu_head *rcu)
 		if (!nft_setelem_is_catchall(trans->set, elem_priv))
 			atomic_dec(&trans->set->nelems);
 
+		WARN_ON_ONCE(atomic_read(&trans->set->nelems) < 0);
 		nf_tables_set_elem_destroy(&ctx, trans->set, elem_priv);
 	}
 
diff --git a/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
index 32df7a16835d..5999415467ef 100644
--- a/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -275,9 +275,12 @@ static void nft_bitmap_destroy(const struct nft_ctx *ctx,
 {
 	struct nft_bitmap *priv = nft_set_priv(set);
 	struct nft_bitmap_elem *be, *n;
+	struct nft_set *mset = (void *)set;
 
-	list_for_each_entry_safe(be, n, &priv->list, head)
+	list_for_each_entry_safe(be, n, &priv->list, head) {
 		nf_tables_set_elem_destroy(ctx, set, &be->priv);
+		atomic_dec(&mset->nelems);
+	}
 }
 
 static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
index 06337a089c34..6b0f84ef4e5f 100644
--- a/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -438,8 +438,12 @@ static void nft_rhash_elem_destroy(void *ptr, void *arg)
 {
 	struct nft_rhash_ctx *rhash_ctx = arg;
 	struct nft_rhash_elem *he = ptr;
+	struct nft_set *set;
 
 	nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, &he->priv);
+
+	set = (struct nft_set *)rhash_ctx->set;
+	atomic_dec(&set->nelems);
 }
 
 static void nft_rhash_destroy(const struct nft_ctx *ctx,
@@ -688,6 +692,7 @@ static int nft_hash_init(const struct nft_set *set,
 static void nft_hash_destroy(const struct nft_ctx *ctx,
 			     const struct nft_set *set)
 {
+	struct nft_set *mset = (struct nft_set *)set;
 	struct nft_hash *priv = nft_set_priv(set);
 	struct nft_hash_elem *he;
 	struct hlist_node *next;
@@ -697,6 +702,7 @@ static void nft_hash_destroy(const struct nft_ctx *ctx,
 		hlist_for_each_entry_safe(he, next, &priv->table[i], node) {
 			hlist_del_rcu(&he->node);
 			nf_tables_set_elem_destroy(ctx, set, &he->priv);
+			atomic_dec(&mset->nelems);
 		}
 	}
 }
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index c0ceea068936..4797f1aa3c11 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2295,6 +2295,7 @@ static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx,
 					 const struct nft_set *set,
 					 struct nft_pipapo_match *m)
 {
+	struct nft_set *mset = (void *)set;
 	struct nft_pipapo_field *f;
 	unsigned int i, r;
 
@@ -2310,6 +2311,7 @@ static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx,
 		e = f->mt[r].e;
 
 		nf_tables_set_elem_destroy(ctx, set, &e->priv);
+		atomic_dec(&mset->nelems);
 	}
 }
 
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 9944fe479e53..0da94e9378ca 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -709,6 +709,7 @@ static void nft_rbtree_destroy(const struct nft_ctx *ctx,
 			       const struct nft_set *set)
 {
 	struct nft_rbtree *priv = nft_set_priv(set);
+	struct nft_set *mset = (void *)set;
 	struct nft_rbtree_elem *rbe;
 	struct rb_node *node;
 
@@ -716,6 +717,7 @@ static void nft_rbtree_destroy(const struct nft_ctx *ctx,
 		rb_erase(node, &priv->root);
 		rbe = rb_entry(node, struct nft_rbtree_elem, node);
 		nf_tables_set_elem_destroy(ctx, set, &rbe->priv);
+		atomic_dec(&mset->nelems);
 	}
 }
 
-- 
2.43.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux