Skip to content

Commit 013d2c5

Browse files
committed
Merge tag 'nf-24-11-07' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says: ==================== Netfilter fix for net The following series contains a Netfilter fix: 1) Wait for rcu grace period after netdevice removal is reported via event. * tag 'nf-24-11-07' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: wait for rcu grace period on net_device removal ==================== Link: https://patch.msgid.link/20241107113212.116634-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 5f897f3 + c03d278 commit 013d2c5

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ struct nft_rule_blob {
11031103
* @name: name of the chain
11041104
* @udlen: user data length
11051105
* @udata: user data in the chain
1106+
* @rcu_head: rcu head for deferred release
11061107
* @blob_next: rule blob pointer to the next in the chain
11071108
*/
11081109
struct nft_chain {
@@ -1120,6 +1121,7 @@ struct nft_chain {
11201121
char *name;
11211122
u16 udlen;
11221123
u8 *udata;
1124+
struct rcu_head rcu_head;
11231125

11241126
/* Only used during control plane commit phase: */
11251127
struct nft_rule_blob *blob_next;
@@ -1263,6 +1265,7 @@ static inline void nft_use_inc_restore(u32 *use)
12631265
* @sets: sets in the table
12641266
* @objects: stateful objects in the table
12651267
* @flowtables: flow tables in the table
1268+
* @net: netnamespace this table belongs to
12661269
* @hgenerator: handle generator state
12671270
* @handle: table handle
12681271
* @use: number of chain references to this table
@@ -1282,6 +1285,7 @@ struct nft_table {
12821285
struct list_head sets;
12831286
struct list_head objects;
12841287
struct list_head flowtables;
1288+
possible_net_t net;
12851289
u64 hgenerator;
12861290
u64 handle;
12871291
u32 use;

net/netfilter/nf_tables_api.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
14951495
INIT_LIST_HEAD(&table->sets);
14961496
INIT_LIST_HEAD(&table->objects);
14971497
INIT_LIST_HEAD(&table->flowtables);
1498+
write_pnet(&table->net, net);
14981499
table->family = family;
14991500
table->flags = flags;
15001501
table->handle = ++nft_net->table_handle;
@@ -11430,22 +11431,48 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
1143011431
}
1143111432
EXPORT_SYMBOL_GPL(nft_data_dump);
1143211433

11433-
int __nft_release_basechain(struct nft_ctx *ctx)
11434+
static void __nft_release_basechain_now(struct nft_ctx *ctx)
1143411435
{
1143511436
struct nft_rule *rule, *nr;
1143611437

11437-
if (WARN_ON(!nft_is_base_chain(ctx->chain)))
11438-
return 0;
11439-
11440-
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
1144111438
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
1144211439
list_del(&rule->list);
11443-
nft_use_dec(&ctx->chain->use);
1144411440
nf_tables_rule_release(ctx, rule);
1144511441
}
11442+
nf_tables_chain_destroy(ctx->chain);
11443+
}
11444+
11445+
static void nft_release_basechain_rcu(struct rcu_head *head)
11446+
{
11447+
struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
11448+
struct nft_ctx ctx = {
11449+
.family = chain->table->family,
11450+
.chain = chain,
11451+
.net = read_pnet(&chain->table->net),
11452+
};
11453+
11454+
__nft_release_basechain_now(&ctx);
11455+
put_net(ctx.net);
11456+
}
11457+
11458+
int __nft_release_basechain(struct nft_ctx *ctx)
11459+
{
11460+
struct nft_rule *rule;
11461+
11462+
if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
11463+
return 0;
11464+
11465+
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
11466+
list_for_each_entry(rule, &ctx->chain->rules, list)
11467+
nft_use_dec(&ctx->chain->use);
11468+
1144611469
nft_chain_del(ctx->chain);
1144711470
nft_use_dec(&ctx->table->use);
11448-
nf_tables_chain_destroy(ctx->chain);
11471+
11472+
if (maybe_get_net(ctx->net))
11473+
call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
11474+
else
11475+
__nft_release_basechain_now(ctx);
1144911476

1145011477
return 0;
1145111478
}

0 commit comments

Comments
 (0)