ipv6: Fix commit 63d9950b08 (ipv6: Make v4-mapped bindings consistent with IPv4)

Commit 63d9950b08
  (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>
This commit is contained in:
Bruno Prémont 2009-08-23 19:06:28 -07:00 committed by David S. Miller
parent 6ff9c2e7fa
commit ca6982b858

View File

@ -306,8 +306,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
v4addr != htonl(INADDR_ANY) && v4addr != htonl(INADDR_ANY) &&
chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_MULTICAST &&
chk_addr_ret != RTN_BROADCAST) chk_addr_ret != RTN_BROADCAST) {
err = -EADDRNOTAVAIL;
goto out; goto out;
}
} else { } else {
if (addr_type != IPV6_ADDR_ANY) { if (addr_type != IPV6_ADDR_ANY) {
struct net_device *dev = NULL; struct net_device *dev = NULL;