X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Faf_inet.c;h=f4f7a57cbcc033daf4220e301d6ec90906d7b666;hb=1731da41698a0b4ce0b124c3771426720490471d;hp=eb044e25a45024219c8377361ec84d39fc12feef;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index eb044e25a..f4f7a57cb 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -112,7 +112,6 @@ #ifdef CONFIG_IP_MROUTE #include #endif -#include DEFINE_SNMP_STAT(struct linux_mib, net_statistics); @@ -160,7 +159,6 @@ void inet_sock_destruct(struct sock *sk) if (inet->opt) kfree(inet->opt); - vx_sock_dec(sk); clr_vx_info(&sk->sk_vx_info); sk->sk_xid = -1; clr_nx_info(&sk->sk_nx_info); @@ -344,7 +342,6 @@ override: set_vx_info(&sk->sk_vx_info, current->vx_info); sk->sk_xid = vx_current_xid(); - vx_sock_inc(sk); set_nx_info(&sk->sk_nx_info, current->nx_info); sk->sk_nid = nx_current_nid(); @@ -410,7 +407,6 @@ int inet_release(struct socket *sock) !(current->flags & PF_EXITING)) timeout = sk->sk_lingertime; sock->sk = NULL; - vx_sock_dec(sk); clr_vx_info(&sk->sk_vx_info); sk->sk_xid = -1; clr_nx_info(&sk->sk_nx_info); @@ -431,6 +427,10 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) unsigned short snum; int chk_addr_ret; int err; + __u32 s_addr; /* Address used for validation */ + __u32 s_addr1; + __u32 s_addr2 = 0xffffffffl; /* Optional address of the socket */ + struct nx_info *nxi = sk->sk_nx_info; /* If the socket has its own bind function then use it. (RAW) */ if (sk->sk_prot->bind) { @@ -441,7 +441,36 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len < sizeof(struct sockaddr_in)) goto out; - chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); + s_addr = s_addr1 = addr->sin_addr.s_addr; + nxdprintk("inet_bind(%p) %p,%p;%lx\n", + sk, nx_info, sk->sk_socket, + (sk->sk_socket?sk->sk_socket->flags:0)); + if (nxi) { + __u32 v4_bcast = nxi->v4_bcast; + __u32 ipv4root = nxi->ipv4[0]; + int nbipv4 = nxi->nbipv4; + if (s_addr == 0) { + s_addr = ipv4root; + if (nbipv4 > 1) + s_addr1 = 0; + else { + s_addr1 = ipv4root; + } + s_addr2 = v4_bcast; + } else if (s_addr == 0x0100007f) { + s_addr = s_addr1 = ipv4root; + } else if (s_addr != v4_bcast) { + int i; + for (i=0; iipv4[i]) + break; + } + if (i == nbipv4) { + return -EADDRNOTAVAIL; + } + } + } + chk_addr_ret = inet_addr_type(s_addr); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since @@ -453,7 +482,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = -EADDRNOTAVAIL; if (!sysctl_ip_nonlocal_bind && !inet->freebind && - addr->sin_addr.s_addr != INADDR_ANY && + s_addr != INADDR_ANY && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -478,7 +507,8 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (sk->sk_state != TCP_CLOSE || inet->num) goto out_release_sock; - inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; + inet->rcv_saddr = inet->saddr = s_addr1; + inet->rcv_saddr2 = s_addr2; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->saddr = 0; /* Use device */