Hi Greg, Sasha,
This batch contains a backport fix for 5.15 -stable.
The following list shows the backported patches, I am using original commit IDs for reference:
1) 8965d42bcf54 ("netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx")
This is a stable dependency for the next patch.
2) c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")
3) b04df3da1b5c ("netfilter: nf_tables: do not defer rule destruction via call_rcu")
This is a fix-for-fix for patch 2.
These three patches are required to fix the netdevice release path for netdev family basechains.
Please, apply, Thanks
Florian Westphal (2): netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx netfilter: nf_tables: do not defer rule destruction via call_rcu
Pablo Neira Ayuso (1): netfilter: nf_tables: wait for rcu grace period on net_device removal
include/net/netfilter/nf_tables.h | 2 +- net/netfilter/nf_tables_api.c | 54 ++++++++++++++++++++++--------- net/netfilter/nft_immediate.c | 2 +- 3 files changed, 41 insertions(+), 17 deletions(-)
From: Florian Westphal fw@strlen.de
commit 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd upstream.
It would be better to not store nft_ctx inside nft_trans object, the netlink ctx strucutre is huge and most of its information is never needed in places that use trans->ctx.
Avoid/reduce its usage if possible, no runtime behaviour change intended.
Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org --- include/net/netfilter/nf_tables.h | 2 +- net/netfilter/nf_tables_api.c | 17 ++++++++--------- net/netfilter/nft_immediate.c | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 9ee225cff611..605d4c0a63e9 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1088,7 +1088,7 @@ static inline bool nft_chain_is_bound(struct nft_chain *chain)
int nft_chain_add(struct nft_table *table, struct nft_chain *chain); void nft_chain_del(struct nft_chain *chain); -void nf_tables_chain_destroy(struct nft_ctx *ctx); +void nf_tables_chain_destroy(struct nft_chain *chain);
struct nft_stats { u64 bytes; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 07fdd5f18f3c..e82c5dfdef2e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1981,9 +1981,9 @@ static void nf_tables_chain_free_chain_rules(struct nft_chain *chain) kvfree(chain->rules_next); }
-void nf_tables_chain_destroy(struct nft_ctx *ctx) +void nf_tables_chain_destroy(struct nft_chain *chain) { - struct nft_chain *chain = ctx->chain; + const struct nft_table *table = chain->table; struct nft_hook *hook, *next;
if (WARN_ON(chain->use > 0)) @@ -1995,7 +1995,7 @@ void nf_tables_chain_destroy(struct nft_ctx *ctx) if (nft_is_base_chain(chain)) { struct nft_base_chain *basechain = nft_base_chain(chain);
- if (nft_base_chain_netdev(ctx->family, basechain->ops.hooknum)) { + if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) { list_for_each_entry_safe(hook, next, &basechain->hook_list, list) { list_del_rcu(&hook->list); @@ -2445,7 +2445,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, err_use: nf_tables_unregister_hook(net, table, chain); err_destroy_chain: - nf_tables_chain_destroy(ctx); + nf_tables_chain_destroy(chain);
return err; } @@ -8809,7 +8809,7 @@ static void nft_commit_release(struct nft_trans *trans) kfree(nft_trans_chain_name(trans)); break; case NFT_MSG_DELCHAIN: - nf_tables_chain_destroy(&trans->ctx); + nf_tables_chain_destroy(nft_trans_chain(trans)); break; case NFT_MSG_DELRULE: nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); @@ -9721,7 +9721,7 @@ static void nf_tables_abort_release(struct nft_trans *trans) nf_tables_table_destroy(&trans->ctx); break; case NFT_MSG_NEWCHAIN: - nf_tables_chain_destroy(&trans->ctx); + nf_tables_chain_destroy(nft_trans_chain(trans)); break; case NFT_MSG_NEWRULE: nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); @@ -10443,7 +10443,7 @@ int __nft_release_basechain(struct nft_ctx *ctx) } nft_chain_del(ctx->chain); nft_use_dec(&ctx->table->use); - nf_tables_chain_destroy(ctx); + nf_tables_chain_destroy(ctx->chain);
return 0; } @@ -10519,10 +10519,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table) nft_obj_destroy(&ctx, obj); } list_for_each_entry_safe(chain, nc, &table->chains, list) { - ctx.chain = chain; nft_chain_del(chain); nft_use_dec(&table->use); - nf_tables_chain_destroy(&ctx); + nf_tables_chain_destroy(chain); } nf_tables_table_destroy(&ctx); } diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c index d154fe67ca8a..a889cf1d863e 100644 --- a/net/netfilter/nft_immediate.c +++ b/net/netfilter/nft_immediate.c @@ -221,7 +221,7 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx, list_del(&rule->list); nf_tables_rule_destroy(&chain_ctx, rule); } - nf_tables_chain_destroy(&chain_ctx); + nf_tables_chain_destroy(chain); break; default: break;
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd
WARNING: Author mismatch between patch and upstream commit: Backport author: Pablo Neira Ayusopablo@netfilter.org Commit author: Florian Westphalfw@strlen.de
Status in newer kernel trees: 6.14.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (different SHA1: 825a80817cf1) 6.1.y | Not found
Note: The patch differs from the upstream commit: --- 1: 8965d42bcf54d ! 1: 55bc2f4ca3c46 netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx @@ Metadata ## Commit message ## netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
+ commit 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd upstream. + It would be better to not store nft_ctx inside nft_trans object, the netlink ctx strucutre is huge and most of its information is never needed in places that use trans->ctx. @@ include/net/netfilter/nf_tables.h: static inline bool nft_chain_is_bound(struct
## net/netfilter/nf_tables_api.c ## @@ net/netfilter/nf_tables_api.c: static void nf_tables_chain_free_chain_rules(struct nft_chain *chain) - kvfree(chain->blob_next); + kvfree(chain->rules_next); }
-void nf_tables_chain_destroy(struct nft_ctx *ctx) @@ net/netfilter/nf_tables_api.c: void nf_tables_chain_destroy(struct nft_ctx *ctx) &basechain->hook_list, list) { list_del_rcu(&hook->list); @@ net/netfilter/nf_tables_api.c: static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - err_trans: - nft_use_dec_restore(&table->use); + err_use: + nf_tables_unregister_hook(net, table, chain); err_destroy_chain: - nf_tables_chain_destroy(ctx); + nf_tables_chain_destroy(chain); @@ net/netfilter/nf_tables_api.c: static int nf_tables_addchain(struct nft_ctx *ctx return err; } @@ net/netfilter/nf_tables_api.c: static void nft_commit_release(struct nft_trans *trans) - if (nft_trans_chain_update(trans)) - nft_hooks_destroy(&nft_trans_chain_hooks(trans)); - else -- nf_tables_chain_destroy(&trans->ctx); -+ nf_tables_chain_destroy(nft_trans_chain(trans)); + kfree(nft_trans_chain_name(trans)); + break; + case NFT_MSG_DELCHAIN: +- nf_tables_chain_destroy(&trans->ctx); ++ nf_tables_chain_destroy(nft_trans_chain(trans)); break; case NFT_MSG_DELRULE: - case NFT_MSG_DESTROYRULE: + nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); @@ net/netfilter/nf_tables_api.c: static void nf_tables_abort_release(struct nft_trans *trans) - if (nft_trans_chain_update(trans)) - nft_hooks_destroy(&nft_trans_chain_hooks(trans)); - else -- nf_tables_chain_destroy(&trans->ctx); -+ nf_tables_chain_destroy(nft_trans_chain(trans)); + nf_tables_table_destroy(&trans->ctx); + break; + case NFT_MSG_NEWCHAIN: +- nf_tables_chain_destroy(&trans->ctx); ++ nf_tables_chain_destroy(nft_trans_chain(trans)); break; case NFT_MSG_NEWRULE: nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |
commit c03d278fdf35e73dd0ec543b9b556876b9d9a8dc upstream.
8c873e219970 ("netfilter: core: free hooks with call_rcu") removed synchronize_net() call when unregistering basechain hook, however, net_device removal event handler for the NFPROTO_NETDEV was not updated to wait for RCU grace period.
Note that 835b803377f5 ("netfilter: nf_tables_netdev: unregister hooks on net_device removal") does not remove basechain rules on device removal, I was hinted to remove rules on net_device removal later, see 5ebe0b0eec9d ("netfilter: nf_tables: destroy basechain and rules on netdevice removal").
Although NETDEV_UNREGISTER event is guaranteed to be handled after synchronize_net() call, this path needs to wait for rcu grace period via rcu callback to release basechain hooks if netns is alive because an ongoing netlink dump could be in progress (sockets hold a reference on the netns).
Note that nf_tables_pre_exit_net() unregisters and releases basechain hooks but it is possible to see NETDEV_UNREGISTER at a later stage in the netns exit path, eg. veth peer device in another netns:
cleanup_net() default_device_exit_batch() unregister_netdevice_many_notify() notifier_call_chain() nf_tables_netdev_event() __nft_release_basechain()
In this particular case, same rule of thumb applies: if netns is alive, then wait for rcu grace period because netlink dump in the other netns could be in progress. Otherwise, if the other netns is going away then no netlink dump can be in progress and basechain hooks can be released inmediately.
While at it, turn WARN_ON() into WARN_ON_ONCE() for the basechain validation, which should not ever happen.
Fixes: 835b803377f5 ("netfilter: nf_tables_netdev: unregister hooks on net_device removal") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org --- include/net/netfilter/nf_tables.h | 3 +++ net/netfilter/nf_tables_api.c | 41 +++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 605d4c0a63e9..69eb652a9b77 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1028,6 +1028,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 **rules_next; @@ -1170,6 +1171,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 @@ -1185,6 +1187,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; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index e82c5dfdef2e..49755897db6b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1360,6 +1360,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; @@ -10428,22 +10429,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))) - 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); - nft_use_dec(&ctx->chain->use); 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(rule, &ctx->chain->rules, list) + nft_use_dec(&ctx->chain->use); + 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; }
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues: ℹ️ This is part 2/3 of a series ⚠️ Found follow-up fixes in mainline
The upstream commit SHA1 provided is correct: c03d278fdf35e73dd0ec543b9b556876b9d9a8dc
Status in newer kernel trees: 6.14.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (different SHA1: bfd05c68e4c6) 6.1.y | Not found
Found fixes commits: b04df3da1b5c netfilter: nf_tables: do not defer rule destruction via call_rcu
Note: The patch differs from the upstream commit: --- 1: c03d278fdf35e ! 1: 14e8d506ade73 netfilter: nf_tables: wait for rcu grace period on net_device removal @@ Metadata ## Commit message ## netfilter: nf_tables: wait for rcu grace period on net_device removal
+ commit c03d278fdf35e73dd0ec543b9b556876b9d9a8dc upstream. + 8c873e219970 ("netfilter: core: free hooks with call_rcu") removed synchronize_net() call when unregistering basechain hook, however, net_device removal event handler for the NFPROTO_NETDEV was not updated @@ Commit message Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org
## include/net/netfilter/nf_tables.h ## -@@ include/net/netfilter/nf_tables.h: 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 { @@ include/net/netfilter/nf_tables.h: struct nft_chain { char *name; u16 udlen; @@ include/net/netfilter/nf_tables.h: struct nft_chain { + struct rcu_head rcu_head;
/* Only used during control plane commit phase: */ - struct nft_rule_blob *blob_next; + struct nft_rule **rules_next; @@ include/net/netfilter/nf_tables.h: static inline void nft_use_inc_restore(u32 *use) * @sets: sets in the table * @objects: stateful objects in the table ---
NOTE: These results are for this patch alone. Full series testing will be performed when all parts are received.
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.1.y | Success | Success |
From: Florian Westphal fw@strlen.de
commit b04df3da1b5c6f6dc7cdccc37941740c078c4043 upstream.
nf_tables_chain_destroy can sleep, it can't be used from call_rcu callbacks.
Moreover, nf_tables_rule_release() is only safe for error unwinding, while transaction mutex is held and the to-be-desroyed rule was not exposed to either dataplane or dumps, as it deactives+frees without the required synchronize_rcu() in-between.
nft_rule_expr_deactivate() callbacks will change ->use counters of other chains/sets, see e.g. nft_lookup .deactivate callback, these must be serialized via transaction mutex.
Also add a few lockdep asserts to make this more explicit.
Calling synchronize_rcu() isn't ideal, but fixing this without is hard and way more intrusive. As-is, we can get:
WARNING: .. net/netfilter/nf_tables_api.c:5515 nft_set_destroy+0x.. Workqueue: events nf_tables_trans_destroy_work RIP: 0010:nft_set_destroy+0x3fe/0x5c0 Call Trace: <TASK> nf_tables_trans_destroy_work+0x6b7/0xad0 process_one_work+0x64a/0xce0 worker_thread+0x613/0x10d0
In case the synchronize_rcu becomes an issue, we can explore alternatives.
One way would be to allocate nft_trans_rule objects + one nft_trans_chain object, deactivate the rules + the chain and then defer the freeing to the nft destroy workqueue. We'd still need to keep the synchronize_rcu path as a fallback to handle -ENOMEM corner cases though.
Reported-by: syzbot+b26935466701e56cfdc2@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/67478d92.050a0220.253251.0062.GAE@google.com/T/ Fixes: c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org --- include/net/netfilter/nf_tables.h | 3 --- net/netfilter/nf_tables_api.c | 32 +++++++++++++++---------------- 2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 69eb652a9b77..605d4c0a63e9 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1028,7 +1028,6 @@ struct nft_chain { char *name; u16 udlen; u8 *udata; - struct rcu_head rcu_head;
/* Only used during control plane commit phase: */ struct nft_rule **rules_next; @@ -1171,7 +1170,6 @@ 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 @@ -1187,7 +1185,6 @@ 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; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 49755897db6b..a1f60f275814 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1360,7 +1360,6 @@ 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; @@ -3441,8 +3440,11 @@ void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule) kfree(rule); }
+/* can only be used if rule is no longer visible to dumps */ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule) { + lockdep_commit_lock_is_held(ctx->net); + nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE); nf_tables_rule_destroy(ctx, rule); } @@ -5178,6 +5180,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase) { + lockdep_commit_lock_is_held(ctx->net); + switch (phase) { case NFT_TRANS_PREPARE_ERROR: nft_set_trans_unbind(ctx, set); @@ -10440,19 +10444,6 @@ static void __nft_release_basechain_now(struct nft_ctx *ctx) 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; @@ -10467,11 +10458,18 @@ int __nft_release_basechain(struct nft_ctx *ctx) nft_chain_del(ctx->chain); nft_use_dec(&ctx->table->use);
- if (maybe_get_net(ctx->net)) - call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu); - else + if (!maybe_get_net(ctx->net)) { __nft_release_basechain_now(ctx); + return 0; + } + + /* wait for ruleset dumps to complete. Owning chain is no longer in + * lists, so new dumps can't find any of these rules anymore. + */ + synchronize_rcu();
+ __nft_release_basechain_now(ctx); + put_net(ctx->net); return 0; } EXPORT_SYMBOL_GPL(__nft_release_basechain);
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: b04df3da1b5c6f6dc7cdccc37941740c078c4043
WARNING: Author mismatch between patch and upstream commit: Backport author: Pablo Neira Ayusopablo@netfilter.org Commit author: Florian Westphalfw@strlen.de
Status in newer kernel trees: 6.14.y | Present (exact SHA1) 6.12.y | Present (different SHA1: 7cf0bd232b56) 6.6.y | Present (different SHA1: 27f0574253f6) 6.1.y | Not found
Note: The patch differs from the upstream commit: --- 1: b04df3da1b5c6 ! 1: a847bddc4639b netfilter: nf_tables: do not defer rule destruction via call_rcu @@ Metadata ## Commit message ## netfilter: nf_tables: do not defer rule destruction via call_rcu
+ commit b04df3da1b5c6f6dc7cdccc37941740c078c4043 upstream. + nf_tables_chain_destroy can sleep, it can't be used from call_rcu callbacks.
@@ Commit message Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org
## include/net/netfilter/nf_tables.h ## -@@ include/net/netfilter/nf_tables.h: 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 { @@ include/net/netfilter/nf_tables.h: struct nft_chain { char *name; u16 udlen; @@ include/net/netfilter/nf_tables.h: struct nft_chain { - struct rcu_head rcu_head;
/* Only used during control plane commit phase: */ - struct nft_rule_blob *blob_next; + struct nft_rule **rules_next; @@ include/net/netfilter/nf_tables.h: static inline void nft_use_inc_restore(u32 *use) * @sets: sets in the table * @objects: stateful objects in the table ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.1.y | Success | Success |
linux-stable-mirror@lists.linaro.org