From: Kuniyuki Iwashima Date: Sat, 28 Feb 2026 22:17:29 +0000 (+0000) Subject: ipmr: Call fib_rules_unregister() without RTNL. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=478c2add78b13e36d781d6891d5861e6e1eecef4;p=thirdparty%2Fkernel%2Flinux.git 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 Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260228221800.1082070-12-kuniyu@google.com Signed-off-by: Jakub Kicinski --- diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c22bcaead348c..07f2d4f8dcbe0 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); }