diff options
-rw-r--r-- | net/ipv4/devinet.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 914ccc7f192a..6fd4628d10b9 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1287,6 +1287,7 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) { const struct in_ifaddr *ifa; __be32 addr = 0; + unsigned char localnet_scope = RT_SCOPE_HOST; struct in_device *in_dev; struct net *net = dev_net(dev); int master_idx; @@ -1296,10 +1297,13 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) if (!in_dev) goto no_in_dev; + if (unlikely(IN_DEV_ROUTE_LOCALNET(in_dev))) + localnet_scope = RT_SCOPE_LINK; + in_dev_for_each_ifa_rcu(ifa, in_dev) { if (ifa->ifa_flags & IFA_F_SECONDARY) continue; - if (ifa->ifa_scope > scope) + if (min(ifa->ifa_scope, localnet_scope) > scope) continue; if (!dst || inet_ifa_match(dst, ifa)) { addr = ifa->ifa_local; |