mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
ip6mr: Convert ip6mr_rtm_getroute() to RCU.
ip6mr_rtm_getroute() calls __ip6mr_get_table(), ip6mr_cache_find(), and ip6mr_fill_mroute(). Once created, struct mr_table is not freed until netns dismantle, so it's safe under RCU. ip6mr_cache_find() iterates mrt->mfc_hash with rhl_for_each_entry_rcu(). struct mr_mfc is freed with call_rcu(), so this is also safe under RCU. ip6mr_fill_mroute() calls mr_fill_mroute(), which properly uses RCU helpers. Let's call them under RCU and register ip6mr_rtm_getroute() with RTNL_FLAG_DOIT_UNLOCKED. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260604224712.3209821-6-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
c2f5fd21ac
commit
76ea2ba229
|
|
@ -1386,7 +1386,8 @@ static struct pernet_operations ip6mr_net_ops = {
|
|||
static const struct rtnl_msg_handler ip6mr_rtnl_msg_handlers[] __initconst_or_module = {
|
||||
{.owner = THIS_MODULE, .protocol = RTNL_FAMILY_IP6MR,
|
||||
.msgtype = RTM_GETROUTE,
|
||||
.doit = ip6mr_rtm_getroute, .dumpit = ip6mr_rtm_dumproute},
|
||||
.doit = ip6mr_rtm_getroute, .dumpit = ip6mr_rtm_dumproute,
|
||||
.flags = RTNL_FLAG_DOIT_UNLOCKED},
|
||||
};
|
||||
|
||||
int __init ip6_mr_init(void)
|
||||
|
|
@ -2710,6 +2711,8 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
|||
grp = nla_get_in6_addr(tb[RTA_DST]);
|
||||
tableid = nla_get_u32_default(tb[RTA_TABLE], 0);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
mrt = __ip6mr_get_table(net, tableid ?: RT_TABLE_DEFAULT);
|
||||
if (!mrt) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "MR table does not exist");
|
||||
|
|
@ -2717,10 +2720,7 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* entries are added/deleted only under RTNL */
|
||||
rcu_read_lock();
|
||||
cache = ip6mr_cache_find(mrt, &src, &grp);
|
||||
rcu_read_unlock();
|
||||
if (!cache) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "MR cache entry not found");
|
||||
err = -ENOENT;
|
||||
|
|
@ -2732,9 +2732,12 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
|||
if (err < 0)
|
||||
goto err;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
|
||||
|
||||
err:
|
||||
rcu_read_unlock();
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user