fib_empty_table() probes every table ID from 1 until it finds a
free one. IPv4 tables are stored in a 256-bucket hash table, so a
dense set of IDs makes each probe walk a growing hash chain while
RTNL is held.
Automatic table assignment ("ip rule ... table 0") is an IPv4-only
legacy path. Bound the automatically allocated ID to 4096 so the
RTNL hold stays bounded, without changing lookups of explicitly
specified table IDs.
Fixes: b801f54917b7 ("[NET]: Increate RT_TABLE_MAX to 2^32")
Cc: stable@vger.kernel.org
Reported-by: Vega <redacted>
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zihan Xi <redacted>
---
changes in v2:
- Replace the bitmap-based O(N) rewrite with a 4096 cap on
automatically allocated table IDs, as suggested by Ido Schimmel.
- Point Fixes: at b801f54917b7, which first raised RT_TABLE_MAX
to 2^32. 1af5a8c4a11c only switched the probe to a hash lookup
while the scan was still capped at 255.
- v1 Link: https://lore.kernel.org/all/0a00492a13038b268c1e0a219c138d07cfab92b3.1787982246.git.zihanx@nebusec.ai/ (local)
net/ipv4/fib_rules.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 4edb0dca7be8..060501b376a8 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -214,6 +214,8 @@ INDIRECT_CALLABLE_SCOPE int fib4_rule_match(struct fib_rule *rule,
return 1;
}
+#define FIB_MAX_AUTO_TABLE_ID 4096
+
static struct fib_table *fib_empty_table(struct net *net)
{
u32 id = 1;@@ -222,7 +224,7 @@ static struct fib_table *fib_empty_table(struct net *net)
if (!fib_get_table(net, id))
return fib_new_table(net, id);
- if (id++ == RT_TABLE_MAX)
+ if (id++ == FIB_MAX_AUTO_TABLE_ID)
break;
}
return NULL;
--
2.43.0