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>
This commit is contained in:
@@ -1103,6 +1103,7 @@ struct nft_rule_blob {
|
||||
* @name: name of the chain
|
||||
* @udlen: user data length
|
||||
* @udata: user data in the chain
|
||||
* @rcu_head: rcu head for deferred release
|
||||
* @blob_next: rule blob pointer to the next in the chain
|
||||
*/
|
||||
struct nft_chain {
|
||||
@@ -1120,6 +1121,7 @@ struct nft_chain {
|
||||
char *name;
|
||||
u16 udlen;
|
||||
u8 *udata;
|
||||
struct rcu_head rcu_head;
|
||||
|
||||
/* Only used during control plane commit phase: */
|
||||
struct nft_rule_blob *blob_next;
|
||||
@@ -1263,6 +1265,7 @@ static inline void nft_use_inc_restore(u32 *use)
|
||||
* @sets: sets in the table
|
||||
* @objects: stateful objects in the table
|
||||
* @flowtables: flow tables in the table
|
||||
* @net: netnamespace this table belongs to
|
||||
* @hgenerator: handle generator state
|
||||
* @handle: table handle
|
||||
* @use: number of chain references to this table
|
||||
@@ -1282,6 +1285,7 @@ struct nft_table {
|
||||
struct list_head sets;
|
||||
struct list_head objects;
|
||||
struct list_head flowtables;
|
||||
possible_net_t net;
|
||||
u64 hgenerator;
|
||||
u64 handle;
|
||||
u32 use;
|
||||
|
||||
@@ -1495,6 +1495,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
INIT_LIST_HEAD(&table->sets);
|
||||
INIT_LIST_HEAD(&table->objects);
|
||||
INIT_LIST_HEAD(&table->flowtables);
|
||||
write_pnet(&table->net, net);
|
||||
table->family = family;
|
||||
table->flags = flags;
|
||||
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,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_data_dump);
|
||||
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
static void __nft_release_basechain_now(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule, *nr;
|
||||
|
||||
if (WARN_ON(!nft_is_base_chain(ctx->chain)))
|
||||
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
nf_tables_rule_release(ctx, rule);
|
||||
}
|
||||
nf_tables_chain_destroy(ctx->chain);
|
||||
}
|
||||
|
||||
static void nft_release_basechain_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
|
||||
struct nft_ctx ctx = {
|
||||
.family = chain->table->family,
|
||||
.chain = chain,
|
||||
.net = read_pnet(&chain->table->net),
|
||||
};
|
||||
|
||||
__nft_release_basechain_now(&ctx);
|
||||
put_net(ctx.net);
|
||||
}
|
||||
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule;
|
||||
|
||||
if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
|
||||
return 0;
|
||||
|
||||
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
|
||||
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
list_for_each_entry(rule, &ctx->chain->rules, list)
|
||||
nft_use_dec(&ctx->chain->use);
|
||||
nf_tables_rule_release(ctx, rule);
|
||||
}
|
||||
|
||||
nft_chain_del(ctx->chain);
|
||||
nft_use_dec(&ctx->table->use);
|
||||
nf_tables_chain_destroy(ctx->chain);
|
||||
|
||||
if (maybe_get_net(ctx->net))
|
||||
call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
|
||||
else
|
||||
__nft_release_basechain_now(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user