Commit d519e870 authored by Florian Westphal's avatar Florian Westphal Committed by David S. Miller

devinet: use in_dev_for_each_ifa_rcu in more places

This also replaces spots that used for_primary_ifa().

for_primary_ifa() aborts the loop on the first secondary address seen.

Replace it with either the rcu or rtnl variant of in_dev_for_each_ifa(),
but two places will now also consider secondary addresses too:
inet_addr_onlink() and inet_ifa_byprefix().

I do not understand why they should ignore secondary addresses.

Why would a secondary address not be considered 'on link'?
When matching a prefix, why ignore a matching secondary address?

Other places get converted as well, but gain "->flags & SECONDARY" check.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ef11db33
...@@ -327,15 +327,17 @@ static void inetdev_destroy(struct in_device *in_dev) ...@@ -327,15 +327,17 @@ static void inetdev_destroy(struct in_device *in_dev)
int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b) int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
{ {
const struct in_ifaddr *ifa;
rcu_read_lock(); rcu_read_lock();
for_primary_ifa(in_dev) { in_dev_for_each_ifa_rcu(ifa, in_dev) {
if (inet_ifa_match(a, ifa)) { if (inet_ifa_match(a, ifa)) {
if (!b || inet_ifa_match(b, ifa)) { if (!b || inet_ifa_match(b, ifa)) {
rcu_read_unlock(); rcu_read_unlock();
return 1; return 1;
} }
} }
} endfor_ifa(in_dev); }
rcu_read_unlock(); rcu_read_unlock();
return 0; return 0;
} }
...@@ -580,12 +582,14 @@ EXPORT_SYMBOL(inetdev_by_index); ...@@ -580,12 +582,14 @@ EXPORT_SYMBOL(inetdev_by_index);
struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
__be32 mask) __be32 mask)
{ {
struct in_ifaddr *ifa;
ASSERT_RTNL(); ASSERT_RTNL();
for_primary_ifa(in_dev) { in_dev_for_each_ifa_rtnl(ifa, in_dev) {
if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa)) if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
return ifa; return ifa;
} endfor_ifa(in_dev); }
return NULL; return NULL;
} }
...@@ -1245,17 +1249,22 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len, int s ...@@ -1245,17 +1249,22 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len, int s
static __be32 in_dev_select_addr(const struct in_device *in_dev, static __be32 in_dev_select_addr(const struct in_device *in_dev,
int scope) int scope)
{ {
for_primary_ifa(in_dev) { const struct in_ifaddr *ifa;
in_dev_for_each_ifa_rcu(ifa, in_dev) {
if (ifa->ifa_flags & IFA_F_SECONDARY)
continue;
if (ifa->ifa_scope != RT_SCOPE_LINK && if (ifa->ifa_scope != RT_SCOPE_LINK &&
ifa->ifa_scope <= scope) ifa->ifa_scope <= scope)
return ifa->ifa_local; return ifa->ifa_local;
} endfor_ifa(in_dev); }
return 0; return 0;
} }
__be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
{ {
const struct in_ifaddr *ifa;
__be32 addr = 0; __be32 addr = 0;
struct in_device *in_dev; struct in_device *in_dev;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
...@@ -1266,7 +1275,9 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) ...@@ -1266,7 +1275,9 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
if (!in_dev) if (!in_dev)
goto no_in_dev; goto no_in_dev;
for_primary_ifa(in_dev) { in_dev_for_each_ifa_rcu(ifa, in_dev) {
if (ifa->ifa_flags & IFA_F_SECONDARY)
continue;
if (ifa->ifa_scope > scope) if (ifa->ifa_scope > scope)
continue; continue;
if (!dst || inet_ifa_match(dst, ifa)) { if (!dst || inet_ifa_match(dst, ifa)) {
...@@ -1275,7 +1286,7 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) ...@@ -1275,7 +1286,7 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
} }
if (!addr) if (!addr)
addr = ifa->ifa_local; addr = ifa->ifa_local;
} endfor_ifa(in_dev); }
if (addr) if (addr)
goto out_unlock; goto out_unlock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment