aboutsummaryrefslogtreecommitdiffstats
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 d89b0bc7ab75..bdcc863a60a4 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -71,6 +71,10 @@ extern int ipv6_chk_addr(struct net *net,
71extern int ipv6_chk_home_addr(struct net *net, 71extern int ipv6_chk_home_addr(struct net *net,
72 struct in6_addr *addr); 72 struct in6_addr *addr);
73#endif 73#endif
74
75extern int ipv6_chk_prefix(struct in6_addr *addr,
76 struct net_device *dev);
77
74extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, 78extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
75 struct in6_addr *addr, 79 struct in6_addr *addr,
76 struct net_device *dev, 80 struct net_device *dev,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5ab9973571ef..c17f8c0b933e 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,
1249 return ifp != NULL; 1249 return ifp != NULL;
1250} 1250}
1251 1251
1252int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
1253{
1254 struct inet6_dev *idev;
1255 struct inet6_ifaddr *ifa;
1256 int onlink;
1257
1258 onlink = 0;
1259 rcu_read_lock();
1260 idev = __in6_dev_get(dev);
1261 if (idev) {
1262 read_lock_bh(&idev->lock);
1263 for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
1264 onlink = ipv6_prefix_equal(addr, &ifa->addr,
1265 ifa->prefix_len);
1266 if (onlink)
1267 break;
1268 }
1269 read_unlock_bh(&idev->lock);
1270 }
1271 rcu_read_unlock();
1272 return onlink;
1273}
1274
1275EXPORT_SYMBOL(ipv6_chk_prefix);
1276
1252struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, 1277struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
1253 struct net_device *dev, int strict) 1278 struct net_device *dev, int strict)
1254{ 1279{
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 463bd95d6b13..36e817492095 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);
48/* Big ac list lock for all the sockets */ 48/* Big ac list lock for all the sockets */
49static DEFINE_RWLOCK(ipv6_sk_ac_lock); 49static DEFINE_RWLOCK(ipv6_sk_ac_lock);
50 50
51static int
52ip6_onlink(struct in6_addr *addr, struct net_device *dev)
53{
54 struct inet6_dev *idev;
55 struct inet6_ifaddr *ifa;
56 int onlink;
57
58 onlink = 0;
59 rcu_read_lock();
60 idev = __in6_dev_get(dev);
61 if (idev) {
62 read_lock_bh(&idev->lock);
63 for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
64 onlink = ipv6_prefix_equal(addr, &ifa->addr,
65 ifa->prefix_len);
66 if (onlink)
67 break;
68 }
69 read_unlock_bh(&idev->lock);
70 }
71 rcu_read_unlock();
72 return onlink;
73}
74 51
75/* 52/*
76 * socket join an anycast group 53 * socket join an anycast group
@@ -142,7 +119,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
142 * This obviates the need for propagating anycast routes while 119 * This obviates the need for propagating anycast routes while
143 * still allowing some non-router anycast participation. 120 * still allowing some non-router anycast participation.
144 */ 121 */
145 if (!ip6_onlink(addr, dev)) { 122 if (!ipv6_chk_prefix(addr, dev)) {
146 if (ishost) 123 if (ishost)
147 err = -EADDRNOTAVAIL; 124 err = -EADDRNOTAVAIL;
148 if (err) 125 if (err)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 08a483a8de50..cc16fe07bbff 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -344,31 +344,6 @@ out:
344 return 0; 344 return 0;
345} 345}
346 346
347/* copied directly from anycast.c */
348static int
349ipip6_onlink(struct in6_addr *addr, struct net_device *dev)
350{
351 struct inet6_dev *idev;
352 struct inet6_ifaddr *ifa;
353 int onlink;
354
355 onlink = 0;
356 rcu_read_lock();
357 idev = __in6_dev_get(dev);
358 if (idev) {
359 read_lock_bh(&idev->lock);
360 for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
361 onlink = ipv6_prefix_equal(addr, &ifa->addr,
362 ifa->prefix_len);
363 if (onlink)
364 break;
365 }
366 read_unlock_bh(&idev->lock);
367 }
368 rcu_read_unlock();
369 return onlink;
370}
371
372static int 347static int
373isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t) 348isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
374{ 349{
@@ -386,7 +361,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
386 struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr; 361 struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
387 if (ipv6_addr_is_isatap(addr6) && 362 if (ipv6_addr_is_isatap(addr6) &&
388 (addr6->s6_addr32[3] == iph->saddr) && 363 (addr6->s6_addr32[3] == iph->saddr) &&
389 ipip6_onlink(addr6, t->dev)) 364 ipv6_chk_prefix(addr6, t->dev))
390 skb->ndisc_nodetype = NDISC_NODETYPE_HOST; 365 skb->ndisc_nodetype = NDISC_NODETYPE_HOST;
391 else 366 else
392 ok = 0; 367 ok = 0;