| From ca6982b858e1d08010c1d29d8e8255b2ac2ad70a Mon Sep 17 00:00:00 2001 |
| From: Bruno Prémont <bonbons@linux-vserver.org> |
| Date: Sun, 23 Aug 2009 19:06:28 -0700 |
| Subject: ipv6: Fix commit 63d9950b08184e6531adceb65f64b429909cc101 (ipv6: Make v4-mapped bindings consistent with IPv4) |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Bruno Prémont <bonbons@linux-vserver.org> |
| |
| 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> |
| |
| --- |
| net/ipv6/af_inet6.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/net/ipv6/af_inet6.c |
| +++ b/net/ipv6/af_inet6.c |
| @@ -294,8 +294,10 @@ int inet6_bind(struct socket *sock, stru |
| 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; |