[PATCH v1 net-next 08/10] net: fib_rules: Use dev_get_by_name_rcu().
From: Kuniyuki Iwashima <kuniyu@google.com>
Date: 2026-06-29 18:12:36
Subsystem:
networking [general], networking [ipv4/ipv6], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds
We will no longer hold RTNL for RTM_NEWRULE and RMT_DELRULE except for the first IPv4 RTM_NEWRULE. Let's covnert __dev_get_by_name() in fib_nl2rule_rtnl() to dev_get_by_name_rcu() and rename it to fib_nl2rule_locked(). Note that dev_get_by_name_rcu() must be called inside ops->lock to serialise fib_rules_event() by __dev_change_net_namespace(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> --- net/core/fib_rules.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 5eef5d6ace82..2b652dd83241 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c@@ -734,10 +734,10 @@ static int fib_nl2rule(struct net *net, struct nlmsghdr *nlh, return err; } -static int fib_nl2rule_rtnl(struct fib_rule *nlrule, - struct fib_rules_ops *ops, - struct nlattr *tb[], - struct netlink_ext_ack *extack) +static int fib_nl2rule_locked(struct fib_rule *nlrule, + struct fib_rules_ops *ops, + struct nlattr *tb[], + struct netlink_ext_ack *extack) { if (!tb[FRA_PRIORITY]) nlrule->pref = fib_default_rule_pref(ops);
@@ -748,12 +748,14 @@ static int fib_nl2rule_rtnl(struct fib_rule *nlrule, return -EINVAL; } + rcu_read_lock(); + if (tb[FRA_IIFNAME]) { struct net_device *dev; - dev = __dev_get_by_name(nlrule->fr_net, nlrule->iifname); + dev = dev_get_by_name_rcu(nlrule->fr_net, nlrule->iifname); if (dev) { - nlrule->iifindex = dev->ifindex; + nlrule->iifindex = READ_ONCE(dev->ifindex); nlrule->iif_is_l3_master = netif_is_l3_master(dev); } }
@@ -761,13 +763,15 @@ static int fib_nl2rule_rtnl(struct fib_rule *nlrule, if (tb[FRA_OIFNAME]) { struct net_device *dev; - dev = __dev_get_by_name(nlrule->fr_net, nlrule->oifname); + dev = dev_get_by_name_rcu(nlrule->fr_net, nlrule->oifname); if (dev) { - nlrule->oifindex = dev->ifindex; + nlrule->oifindex = READ_ONCE(dev->ifindex); nlrule->oif_is_l3_master = netif_is_l3_master(dev); } } + rcu_read_unlock(); + return 0; }
@@ -906,7 +910,7 @@ int fib_newrule(struct net *net, struct sk_buff *skb, struct nlmsghdr *nlh, rtnl_net_lock(net); mutex_lock(&ops->lock); - err = fib_nl2rule_rtnl(rule, ops, tb, extack); + err = fib_nl2rule_locked(rule, ops, tb, extack); if (err) goto errout_free;
@@ -1038,7 +1042,7 @@ int fib_delrule(struct net *net, struct sk_buff *skb, struct nlmsghdr *nlh, rtnl_net_lock(net); mutex_lock(&ops->lock); - err = fib_nl2rule_rtnl(nlrule, ops, tb, extack); + err = fib_nl2rule_locked(nlrule, ops, tb, extack); if (err) goto errout_free;
--
2.55.0.rc0.799.gd6f94ed593-goog