[PATCH v3 net-next 04/15] ip6mr: Use MAXMIFS in mr6_msgsize().

Kuniyuki Iwashima
2026-04-07T21:20:10Z

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>
---
net/ipv6/ip6mr.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 5d368ee39b28..4d78041276c1 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2542,7 +2542,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))
@@ -2555,7 +2555,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))
;
@@ -2570,8 +2570,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;

@@ -2727,7 +2726,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;

--
2.53.0.1213.gd9a14994de-goog