diff options
author | Bruno Prémont <bonbons@linux-vserver.org> | 2009-08-23 22:06:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-23 22:06:28 -0400 |
commit | ca6982b858e1d08010c1d29d8e8255b2ac2ad70a (patch) | |
tree | ccc9ad39b1d1b974fa971cf9f3538415240dfa18 | |
parent | 6ff9c2e7fa8ca63a575792534b63c5092099c286 (diff) |
ipv6: Fix commit 63d9950b08184e6531adceb65f64b429909cc101 (ipv6: Make v4-mapped bindings consistent with IPv4)
Commit 63d9950b08184e6531adceb65f64b429909cc101
(ipv6: Make v4-mapped bindings consistent with IPv4)
changes behavior of inet6_bind() for v4-mapped addresses so it should
behave the same way as inet_bind().
During this change setting of err to -EADDRNOTAVAIL got lost:
af_inet.c:469 inet_bind()
err = -EADDRNOTAVAIL;
if (!sysctl_ip_nonlocal_bind &&
!(inet->freebind || inet->transparent) &&
addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
chk_addr_ret != RTN_BROADCAST)
goto out;
af_inet6.c:463 inet6_bind()
if (addr_type == IPV6_ADDR_MAPPED) {
int chk_addr_ret;
/* Binding to v4-mapped address on a v6-only socket
* makes no sense
*/
if (np->ipv6only) {
err = -EINVAL;
goto out;
}
/* Reproduce AF_INET checks to make the bindings consitant */
v4addr = addr->sin6_addr.s6_addr32[3];
chk_addr_ret = inet_addr_type(net, v4addr);
if (!sysctl_ip_nonlocal_bind &&
!(inet->freebind || inet->transparent) &&
v4addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
chk_addr_ret != RTN_BROADCAST)
goto out;
} else {
Signed-off-by Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/af_inet6.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index caa0278d30a9..45f9a2a42d56 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -306,8 +306,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
306 | v4addr != htonl(INADDR_ANY) && | 306 | v4addr != htonl(INADDR_ANY) && |
307 | chk_addr_ret != RTN_LOCAL && | 307 | chk_addr_ret != RTN_LOCAL && |
308 | chk_addr_ret != RTN_MULTICAST && | 308 | chk_addr_ret != RTN_MULTICAST && |
309 | chk_addr_ret != RTN_BROADCAST) | 309 | chk_addr_ret != RTN_BROADCAST) { |
310 | err = -EADDRNOTAVAIL; | ||
310 | goto out; | 311 | goto out; |
312 | } | ||
311 | } else { | 313 | } else { |
312 | if (addr_type != IPV6_ADDR_ANY) { | 314 | if (addr_type != IPV6_ADDR_ANY) { |
313 | struct net_device *dev = NULL; | 315 | struct net_device *dev = NULL; |