summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2026-07-16 17:06:07 +0000
committerPaolo Abeni <pabeni@redhat.com>2026-07-23 13:36:46 +0200
commit3671f0419d90b98a02f313830595ab958c8b2025 (patch)
tree82328ac7c2b0a2416ba97e16946a72a2fc7fa9c5 /net
parent675ed582c1aa4d919dd535490de08c015005c653 (diff)
downloadlinux-3671f0419d90b98a02f313830595ab958c8b2025.tar.gz
linux-3671f0419d90b98a02f313830595ab958c8b2025.tar.bz2
linux-3671f0419d90b98a02f313830595ab958c8b2025.zip
mpls: Set rt->rt_nhn just before returning from mpls_nh_build_multi().
Commit f0914b8436c5 ("mpls: Hold dev refcnt for mpls_nh.") added change_nexthops() loop to call netdev_put() for the nexthop devices before freeing mpls_route. Then, mpls_nh_build_multi() was also changed to avoid iterating uninitialised nexthops in mpls_rt_free_rcu(). However, setting rt->rt_nhn to 0 at the entry of mpls_nh_build_multi() makes the following change_nexthops() no-op. Let's set rt->rt_nhn just before returning from mpls_nh_build_multi(). Fixes: f0914b8436c5 ("mpls: Hold dev refcnt for mpls_nh.") Reported-by: Anthony Doeraene <anthony.doeraene@uclouvain.be> Closes: https://lore.kernel.org/netdev/036a0c95-f5d4-46ab-88e7-1eab567d7a84@uclouvain.be/ Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260716170609.804629-1-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/mpls/af_mpls.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 318cb7e2ac5f..4406c304b639 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -922,8 +922,7 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg,
struct nlattr *nla_via, *nla_newdst;
int remaining = cfg->rc_mp_len;
int err = 0;
-
- rt->rt_nhn = 0;
+ u8 nhs = 0;
change_nexthops(rt) {
int attrlen;
@@ -959,12 +958,15 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg,
rt->rt_nhn_alive--;
rtnh = rtnh_next(rtnh, &remaining);
- rt->rt_nhn++;
+ nhs++;
} endfor_nexthops(rt);
+ rt->rt_nhn = nhs;
+
return 0;
errout:
+ rt->rt_nhn = nhs;
return err;
}