ip6mr: Use MAXMIFS in mr6_msgsize().

mr6_msgsize() calculates skb size needed for ip6mr_fill_mroute().

The size differs based on mrt->maxvif.

We will drop RTNL for ip6mr_rtm_getroute() and mrt->maxvif may
change under RCU.

To avoid -EMSGSIZE, let's calculate the size with the maximum
value of mrt->maxvif, MAXMIFS.

struct rtnexthop is 8 bytes and MAXMIFS is 32, so the maximum delta
is 256 bytes, which is small enough.

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

View File

@ -2537,7 +2537,7 @@ static int _ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
cmd, flags);
}
static int mr6_msgsize(bool unresolved, int maxvif)
static int mr6_msgsize(bool unresolved)
{
size_t len =
NLMSG_ALIGN(sizeof(struct rtmsg))
@ -2550,7 +2550,7 @@ static int mr6_msgsize(bool unresolved, int maxvif)
len = len
+ nla_total_size(4) /* RTA_IIF */
+ nla_total_size(0) /* RTA_MULTIPATH */
+ maxvif * NLA_ALIGN(sizeof(struct rtnexthop))
+ MAXMIFS * NLA_ALIGN(sizeof(struct rtnexthop))
/* RTA_MFC_STATS */
+ nla_total_size_64bit(sizeof(struct rta_mfc_stats))
;
@ -2565,8 +2565,7 @@ static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
struct sk_buff *skb;
int err = -ENOBUFS;
skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
GFP_ATOMIC);
skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS), GFP_ATOMIC);
if (!skb)
goto errout;
@ -2722,7 +2721,7 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
return -ENOENT;
}
skb = nlmsg_new(mr6_msgsize(false, mrt->maxvif), GFP_KERNEL);
skb = nlmsg_new(mr6_msgsize(false), GFP_KERNEL);
if (!skb)
return -ENOBUFS;