aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/addrconf.h4
-rw-r--r--net/ipv6/addrconf.c25
-rw-r--r--net/ipv6/anycast.c25
-rw-r--r--net/ipv6/sit.c27
4 files changed, 31 insertions, 50 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index d89b0bc7ab7..bdcc863a60a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -71,6 +71,10 @@ extern int ipv6_chk_addr(struct net *net,
extern int ipv6_chk_home_addr(struct net *net,
struct in6_addr *addr);
#endif
+
+extern int ipv6_chk_prefix(struct in6_addr *addr,
+ struct net_device *dev);
+
extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
struct in6_addr *addr,
struct net_device *dev,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5ab9973571e..c17f8c0b933 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1249,6 +1249,31 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
return ifp != NULL;
}
+int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
+{
+ struct inet6_dev *idev;
+ struct inet6_ifaddr *ifa;
+ int onlink;
+
+ onlink = 0;
+ rcu_read_lock();
+ idev = __in6_dev_get(dev);
+ if (idev) {
+ read_lock_bh(&idev->lock);
+ for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
+ onlink = ipv6_prefix_equal(addr, &ifa->addr,
+ ifa->prefix_len);
+ if (onlink)
+ break;
+ }
+ read_unlock_bh(&idev->lock);
+ }
+ rcu_read_unlock();
+ return onlink;
+}
+
+EXPORT_SYMBOL(ipv6_chk_prefix);
+
struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
struct net_device *dev, int strict)
{
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 463bd95d6b1..36e81749209 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -48,29 +48,6 @@ static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
/* Big ac list lock for all the sockets */
static DEFINE_RWLOCK(ipv6_sk_ac_lock);
-static int
-ip6_onlink(struct in6_addr *addr, struct net_device *dev)
-{
- struct inet6_dev *idev;
- struct inet6_ifaddr *ifa;
- int onlink;
-
- onlink = 0;
- rcu_read_lock();
- idev = __in6_dev_get(dev);
- if (idev) {
- read_lock_bh(&idev->lock);
- for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
- onlink = ipv6_prefix_equal(addr, &ifa->addr,
- ifa->prefix_len);
- if (onlink)
- break;
- }
- read_unlock_bh(&idev->lock);
- }
- rcu_read_unlock();
- return onlink;
-}
/*
* socket join an anycast group
@@ -142,7 +119,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
* This obviates the need for propagating anycast routes while
* still allowing some non-router anycast participation.
*/
- if (!ip6_onlink(addr, dev)) {
+ if (!ipv6_chk_prefix(addr, dev)) {
if (ishost)
err = -EADDRNOTAVAIL;
if (err)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 08a483a8de5..cc16fe07bbf 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -344,31 +344,6 @@ out:
return 0;
}
-/* copied directly from anycast.c */
-static int
-ipip6_onlink(struct in6_addr *addr, struct net_device *dev)
-{
- struct inet6_dev *idev;
- struct inet6_ifaddr *ifa;
- int onlink;
-
- onlink = 0;
- rcu_read_lock();
- idev = __in6_dev_get(dev);
- if (idev) {
- read_lock_bh(&idev->lock);
- for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
- onlink = ipv6_prefix_equal(addr, &ifa->addr,
- ifa->prefix_len);
- if (onlink)
- break;
- }
- read_unlock_bh(&idev->lock);
- }
- rcu_read_unlock();
- return onlink;
-}
-
static int
isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
{
@@ -386,7 +361,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
if (ipv6_addr_is_isatap(addr6) &&
(addr6->s6_addr32[3] == iph->saddr) &&
- ipip6_onlink(addr6, t->dev))
+ ipv6_chk_prefix(addr6, t->dev))
skb->ndisc_nodetype = NDISC_NODETYPE_HOST;
else
ok = 0;