ip6mr: Allocate skb earlier in ip6mr_rtm_getroute().

We will convert ip6mr_rtm_getroute() to RCU in the following patch,
where __ip6mr_get_table() will be called under RCU.

nlmsg_new() uses GFP_KERNEL and needs to be called before holding
rcu_read_lock().

As a prep, let's move nlmsg_new() before __ip6mr_get_table().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260604224712.3209821-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Kuniyuki Iwashima 2026-06-04 22:46:22 +00:00 committed by Jakub Kicinski
parent 36be7d7c5d
commit c2f5fd21ac

View File

@ -2700,6 +2700,10 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (err < 0)
return err;
skb = nlmsg_new(mr6_msgsize(false), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
if (tb[RTA_SRC])
src = nla_get_in6_addr(tb[RTA_SRC]);
if (tb[RTA_DST])
@ -2709,7 +2713,8 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
mrt = __ip6mr_get_table(net, tableid ?: RT_TABLE_DEFAULT);
if (!mrt) {
NL_SET_ERR_MSG_MOD(extack, "MR table does not exist");
return -ENOENT;
err = -ENOENT;
goto err;
}
/* entries are added/deleted only under RTNL */
@ -2718,21 +2723,20 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
rcu_read_unlock();
if (!cache) {
NL_SET_ERR_MSG_MOD(extack, "MR cache entry not found");
return -ENOENT;
err = -ENOENT;
goto err;
}
skb = nlmsg_new(mr6_msgsize(false), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
err = ip6mr_fill_mroute(mrt, skb, NETLINK_CB(in_skb).portid,
nlh->nlmsg_seq, cache, RTM_NEWROUTE, 0);
if (err < 0) {
kfree_skb(skb);
return err;
}
if (err < 0)
goto err;
return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
err:
kfree_skb(skb);
return err;
}
static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)