summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Prémont <bonbons@linux-vserver.org>2009-08-23 19:06:28 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-08 20:33:59 -0700
commit3970742fce3383231a240f5bcd018c7f7106f5ea (patch)
treeb928cc19f1ac72d6a47487e7cb3e5289fd088187
parentdf221c536aa18008724e57acc4170e0ba38fb11c (diff)
ipv6: Fix commit 63d9950b08184e6531adceb65f64b429909cc101 (ipv6: Make v4-mapped bindings consistent with IPv4)
commit ca6982b858e1d08010c1d29d8e8255b2ac2ad70a upstream. 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.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 61f55386a236..55e315a5f0af 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -294,8 +294,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
v4addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
- chk_addr_ret != RTN_BROADCAST)
+ chk_addr_ret != RTN_BROADCAST) {
+ err = -EADDRNOTAVAIL;
goto out;
+ }
} else {
if (addr_type != IPV6_ADDR_ANY) {
struct net_device *dev = NULL;