]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ip6mr: Allocate skb earlier in ip6mr_rtm_getroute().
authorKuniyuki Iwashima <kuniyu@google.com>
Thu, 4 Jun 2026 22:46:22 +0000 (22:46 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 9 Jun 2026 00:06:23 +0000 (17:06 -0700)
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>
net/ipv6/ip6mr.c

index ed56c4c8fda07a86d5c5ab485deafc3cefdaddeb..018985593b032f3ec99b27f1657ce6412abc4c7c 100644 (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)