[PATCH net v2 1/1] ipv4: avoid divide by zero in fib_rebalance

From: Zihan Xi

Date: Thu Aug 27 2026 - 14:31:33 EST


fib_rebalance() computes the total eligible nexthop weight in one pass
and programs upper bounds in a second pass. A concurrent change to
ignore_routes_with_linkdown can make the first pass return zero while
the second pass sees an eligible nexthop, resulting in division by zero.

If the first pass reports a zero total, set each nexthop upper bound to
-1 and skip the division. This matches the IPv6 fix in commit
d2c26c2911dd ("ipv6: avoid divide by zero in rt6_multipath_rebalance")
and preserves the lock-free rebalance path.

Fixes: 0e884c78ee19 ("ipv4: L3 hash-based multipath")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: Vega <vega@xxxxxxxxxx>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zihan Xi <zihanx@xxxxxxxxxx>
---
changes in v2:
- Replace the v1 RTNL sysctl serialization with a total == 0 guard
in fib_rebalance(), matching the applied IPv6 fix.
- v1 Link: https://lore.kernel.org/all/cover.1786812660.git.zihanx@xxxxxxxxxx

net/ipv4/fib_semantics.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 0483519b7fb0..7a362f2e2c2b 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -874,7 +874,7 @@ static void fib_rebalance(struct fib_info *fi)
change_nexthops(fi) {
int upper_bound;

- if (nexthop_nh->fib_nh_flags & RTNH_F_DEAD) {
+ if (!total || nexthop_nh->fib_nh_flags & RTNH_F_DEAD) {
upper_bound = -1;
} else if (ip_ignore_linkdown(nexthop_nh->fib_nh_dev) &&
nexthop_nh->fib_nh_flags & RTNH_F_LINKDOWN) {
--
2.43.0