diff options
| author | Kuniyuki Iwashima <kuniyu@google.com> | 2026-02-28 22:17:29 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-02 18:49:41 -0800 |
| commit | 478c2add78b13e36d781d6891d5861e6e1eecef4 (patch) | |
| tree | e90cf7feb242475013786ab9583f6c0dbdcb29f1 /net | |
| parent | 4a11adcd9eefb841d4595267bbd4df304a98ded6 (diff) | |
ipmr: Call fib_rules_unregister() without RTNL.
fib_rules_unregister() removes ops from net->rules_ops under
spinlock, calls ops->delete() for each rule, and frees the ops.
ipmr_rules_ops_template does not have ->delete(), and any
operation does not require RTNL there.
Let's move fib_rules_unregister() from ipmr_rules_exit_rtnl()
to ipmr_net_exit().
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260228221800.1082070-12-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/ipmr.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c22bcaead348..07f2d4f8dcbe 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -282,6 +282,11 @@ err1: return err; } +static void __net_exit ipmr_rules_exit(struct net *net) +{ + fib_rules_unregister(net->ipv4.mr_rules_ops); +} + static void __net_exit ipmr_rules_exit_rtnl(struct net *net, struct list_head *dev_kill_list) { @@ -291,8 +296,6 @@ static void __net_exit ipmr_rules_exit_rtnl(struct net *net, list_del(&mrt->list); ipmr_free_table(mrt, dev_kill_list); } - - fib_rules_unregister(net->ipv4.mr_rules_ops); } static int ipmr_rules_dump(struct net *net, struct notifier_block *nb, @@ -348,6 +351,10 @@ static int __net_init ipmr_rules_init(struct net *net) return 0; } +static void __net_exit ipmr_rules_exit(struct net *net) +{ +} + static void __net_exit ipmr_rules_exit_rtnl(struct net *net, struct list_head *dev_kill_list) { @@ -3286,6 +3293,7 @@ proc_cache_fail: remove_proc_entry("ip_mr_vif", net->proc_net); proc_vif_fail: ipmr_rules_exit_rtnl(net, &dev_kill_list); + ipmr_rules_exit(net); #endif ipmr_rules_fail: ipmr_notifier_exit(net); @@ -3299,6 +3307,7 @@ static void __net_exit ipmr_net_exit(struct net *net) remove_proc_entry("ip_mr_cache", net->proc_net); remove_proc_entry("ip_mr_vif", net->proc_net); #endif + ipmr_rules_exit(net); ipmr_notifier_exit(net); } |
