diff options
-rw-r--r-- | include/net/addrconf.h | 4 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 25 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 25 | ||||
-rw-r--r-- | net/ipv6/sit.c | 27 |
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, | |||
71 | extern int ipv6_chk_home_addr(struct net *net, | 71 | extern int ipv6_chk_home_addr(struct net *net, |
72 | struct in6_addr *addr); | 72 | struct in6_addr *addr); |
73 | #endif | 73 | #endif |
74 | |||
75 | extern int ipv6_chk_prefix(struct in6_addr *addr, | ||
76 | struct net_device *dev); | ||
77 | |||
74 | extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, | 78 | extern 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 | ||
1252 | int 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 | |||
1275 | EXPORT_SYMBOL(ipv6_chk_prefix); | ||
1276 | |||
1252 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | 1277 | struct 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 */ |
49 | static DEFINE_RWLOCK(ipv6_sk_ac_lock); | 49 | static DEFINE_RWLOCK(ipv6_sk_ac_lock); |
50 | 50 | ||
51 | static int | ||
52 | ip6_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 */ | ||
348 | static int | ||
349 | ipip6_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 | |||
372 | static int | 347 | static int |
373 | isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t) | 348 | isatap_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; |