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);
* Set socket options on an inet socket.
*/
int inet_setsockopt(struct socket *sock, int level, int optname,
- char *optval, int optlen)
+ char __user *optval, int optlen)
{
struct sock *sk = sock->sk;
*/
int inet_getsockopt(struct socket *sock, int level, int optname,
- char *optval, int *optlen)
+ char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
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 */
switch (cmd) {
case SIOCGSTAMP:
- err = sock_get_timestamp(sk, (struct timeval *)arg);
+ err = sock_get_timestamp(sk, (struct timeval __user *)arg);
break;
case SIOCADDRT:
case SIOCDELRT:
case SIOCDARP:
case SIOCGARP:
case SIOCSARP:
- err = arp_ioctl(cmd, (void *)arg);
+ err = arp_ioctl(cmd, (void __user *)arg);
break;
case SIOCGIFADDR:
case SIOCSIFADDR:
case SIOCSIFPFLAGS:
case SIOCGIFPFLAGS:
case SIOCSIFFLAGS:
- err = devinet_ioctl(cmd, (void *)arg);
+ err = devinet_ioctl(cmd, (void __user *)arg);
break;
default:
if (!sk->sk_prot->ioctl ||
(err = sk->sk_prot->ioctl(sk, cmd, arg)) ==
-ENOIOCTLCMD)
- err = dev_ioctl(cmd, (void *)arg);
+ err = dev_ioctl(cmd, (void __user *)arg);
break;
}
return err;
spin_lock_bh(&inetsw_lock);
- if (p->type > SOCK_MAX)
+ if (p->type >= SOCK_MAX)
goto out_illegal;
/* If we are trying to override a permanent protocol, bail. */