aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
authorKuniyuki Iwashima <kuniyu@google.com>2026-06-19 21:27:20 +0000
committerJakub Kicinski <kuba@kernel.org>2026-06-22 18:37:36 -0700
commitb72f0db64205d9ce462038ba995d5d31eff32dc1 (patch)
tree5e334d15166aed238d7e93956df95da27552e488 /include
parent40529e58629baa9ce72143cb46cf1b3d2ca0d465 (diff)
downloadath-b72f0db64205d9ce462038ba995d5d31eff32dc1.tar.gz
ipv4: fib: Don't ignore error route in local/main tables.
When CONFIG_IP_MULTIPLE_TABLES is enabled but no rule is added, fib_lookup() performs route lookup directly on two tables. Since the first lookup does not properly bail out, the result of an error route in the merged local/main table could be overwritten by another route in the default table: # unshare -n # ip link set lo up # ip route add 192.168.0.0/24 dev lo table 253 # ip route add unreachable 192.168.0.0/24 # ip route get 192.168.0.1 192.168.0.1 dev lo table default uid 0 cache <local> Once a random rule is added, the error route is respected: # ip rule add table 0 # ip rule del table 0 # ip route get 192.168.0.1 RTNETLINK answers: No route to host Let's fix the inconsistent behaviour. Fixes: f4530fa574df ("ipv4: Avoid overhead when no custom FIB rules are installed.") Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260619212753.3367244-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/ip_fib.h7
1 files changed, 3 insertions, 4 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index a71a985056507..c63a3c4967ae6 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -374,7 +374,7 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp,
struct fib_result *res, unsigned int flags)
{
struct fib_table *tb;
- int err = -ENETUNREACH;
+ int err = -EAGAIN;
flags |= FIB_LOOKUP_NOREF;
if (net->ipv4.fib_has_custom_rules)
@@ -388,17 +388,16 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp,
if (tb)
err = fib_table_lookup(tb, flp, res, flags);
- if (!err)
+ if (err != -EAGAIN)
goto out;
tb = rcu_dereference_rtnl(net->ipv4.fib_default);
if (tb)
err = fib_table_lookup(tb, flp, res, flags);
-out:
if (err == -EAGAIN)
err = -ENETUNREACH;
-
+out:
rcu_read_unlock();
return err;