if (inet->opt)
kfree(inet->opt);
+
+ BUG_ON(sk->sk_nx_info);
+ BUG_ON(sk->sk_vx_info);
dst_release(sk->sk_dst_cache);
#ifdef INET_REFCNT_DEBUG
atomic_dec(&inet_sock_nr);
sk->sk_family = PF_INET;
sk->sk_protocol = protocol;
sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+
+ set_vx_info(&sk->sk_vx_info, current->vx_info);
+ sk->sk_xid = vx_current_xid();
+ set_nx_info(&sk->sk_nx_info, current->nx_info);
+ sk->sk_nid = nx_current_nid();
inet->uc_ttl = -1;
inet->mc_loop = 1;
if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);
- if (err)
- inet_sock_release(sk);
+ if (err) {
+/* sk->sk_vx_info = NULL;
+ put_vx_info(current->vx_info);
+ sk->sk_nx_info = NULL;
+ put_nx_info(current->nx_info);
+*/ inet_sock_release(sk);
+ }
}
out:
return err;
!(current->flags & PF_EXITING))
timeout = sk->sk_lingertime;
sock->sk = NULL;
+ clr_vx_info(&sk->sk_vx_info);
+ clr_nx_info(&sk->sk_nx_info);
sk->sk_prot->close(sk, timeout);
}
return 0;
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) {
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; i<nbipv4; i++) {
+ if (s_addr == nxi->ipv4[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
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)
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 */