#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <net/tux.h>
#include <linux/wanrouter.h>
#include <linux/if_bridge.h>
#include <linux/init.h>
#include <net/sock.h>
#include <linux/netfilter.h>
+#include <linux/vs_base.h>
+#include <linux/vs_socket.h>
static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
* in the operation structures but are done directly via the socketcall() multiplexor.
*/
-static struct file_operations socket_file_ops = {
+struct file_operations socket_file_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.aio_read = sock_aio_read,
ei->socket.ops = NULL;
ei->socket.sk = NULL;
ei->socket.file = NULL;
- ei->socket.passcred = 0;
+ ei->socket.flags = 0;
return &ei->vfs_inode;
}
* but we take care of internal coherence yet.
*/
-int sock_map_fd(struct socket *sock)
+struct file * sock_map_file(struct socket *sock)
{
- int fd;
+ struct file *file;
struct qstr this;
char name[32];
- /*
- * Find a file descriptor suitable for return to the user.
- */
+ file = get_empty_filp();
- fd = get_unused_fd();
- if (fd >= 0) {
- struct file *file = get_empty_filp();
+ if (!file)
+ return ERR_PTR(-ENFILE);
- if (!file) {
- put_unused_fd(fd);
- fd = -ENFILE;
- goto out;
- }
+ sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
+ this.name = name;
+ this.len = strlen(name);
+ this.hash = SOCK_INODE(sock)->i_ino;
- sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
- this.name = name;
- this.len = strlen(name);
- this.hash = SOCK_INODE(sock)->i_ino;
+ file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
+ if (!file->f_dentry) {
+ put_filp(file);
+ return ERR_PTR(-ENOMEM);
+ }
+ file->f_dentry->d_op = &sockfs_dentry_operations;
+ d_add(file->f_dentry, SOCK_INODE(sock));
+ file->f_vfsmnt = mntget(sock_mnt);
+file->f_mapping = file->f_dentry->d_inode->i_mapping;
- file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
- if (!file->f_dentry) {
- put_filp(file);
- put_unused_fd(fd);
- fd = -ENOMEM;
- goto out;
- }
- file->f_dentry->d_op = &sockfs_dentry_operations;
- d_add(file->f_dentry, SOCK_INODE(sock));
- file->f_vfsmnt = mntget(sock_mnt);
- file->f_mapping = file->f_dentry->d_inode->i_mapping;
+ if (sock->file)
+ BUG();
+ sock->file = file;
+ file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
+ file->f_mode = FMODE_READ | FMODE_WRITE;
+ file->f_flags = O_RDWR;
+ file->f_pos = 0;
- sock->file = file;
- file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
- file->f_mode = FMODE_READ | FMODE_WRITE;
- file->f_flags = O_RDWR;
- file->f_pos = 0;
- fd_install(fd, file);
- }
+ return file;
+}
-out:
+int sock_map_fd(struct socket *sock)
+{
+ int fd;
+ struct file *file;
+
+ /*
+ * Find a file descriptor suitable for return to the user.
+ */
+
+ fd = get_unused_fd();
+ if (fd < 0)
+ return fd;
+
+ file = sock_map_file(sock);
+ if (IS_ERR(file)) {
+ put_unused_fd(fd);
+ return PTR_ERR(file);
+ }
+ fd_install(fd, file);
+
return fd;
}
struct msghdr *msg, size_t size)
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- int err;
+ int err, len;
si->sock = sock;
si->scm = NULL;
if (err)
return err;
- return sock->ops->sendmsg(iocb, sock, msg, size);
+ len = sock->ops->sendmsg(iocb, sock, msg, size);
+ if (sock->sk) {
+ if (len == size)
+ vx_sock_send(sock->sk, size);
+ else
+ vx_sock_fail(sock->sk, size);
+ }
+ vxdprintk(VXD_CBIT(net, 7),
+ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d",
+ sock, sock->sk,
+ (sock->sk)?sock->sk->sk_nx_info:0,
+ (sock->sk)?sock->sk->sk_vx_info:0,
+ (sock->sk)?sock->sk->sk_xid:0,
+ (unsigned int)size, len);
+ return len;
}
int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
- int err;
+ int err, len;
struct sock_iocb *si = kiocb_to_siocb(iocb);
si->sock = sock;
if (err)
return err;
- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ if ((len >= 0) && sock->sk)
+ vx_sock_recv(sock->sk, len);
+ vxdprintk(VXD_CBIT(net, 7),
+ "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d",
+ sock, sock->sk,
+ (sock->sk)?sock->sk->sk_nx_info:0,
+ (sock->sk)?sock->sk->sk_vx_info:0,
+ (sock->sk)?sock->sk->sk_xid:0,
+ (unsigned int)size, len);
+ return len;
}
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
}
out:
+ if (sock->sk != sk)
+ BUG();
release_sock(sock->sk);
return 0;
}
if (type < 0 || type >= SOCK_MAX)
return -EINVAL;
+ /* disable IPv6 inside vservers for now */
+ if (family == PF_INET6 && !vx_check(0, VX_ADMIN))
+ return -EAFNOSUPPORT;
+
/* Compatibility.
This uglymoron is moved from INET layer to here to avoid
if (retval < 0)
goto out;
+ set_bit(SOCK_USER_SOCKET, &sock->flags);
retval = sock_map_fd(sock);
if (retval < 0)
goto out_release;
err = sock_create(family, type, protocol, &sock1);
if (err < 0)
goto out;
+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
err = sock_create(family, type, protocol, &sock2);
if (err < 0)
goto out_release_1;
+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
err = sock1->ops->socketpair(sock1, sock2);
if (err < 0)
#endif
}
+int tux_Dprintk;
+int tux_TDprintk;
+
+#ifdef CONFIG_TUX_MODULE
+
+asmlinkage long (*sys_tux_ptr) (unsigned int action, user_req_t *u_info) = NULL;
+
+struct module *tux_module = NULL;
+spinlock_t tux_module_lock = SPIN_LOCK_UNLOCKED;
+
+asmlinkage long sys_tux (unsigned int action, user_req_t *u_info)
+{
+ int ret;
+
+ if (current->tux_info)
+ return sys_tux_ptr(action, u_info);
+
+ ret = -ENOSYS;
+ spin_lock(&tux_module_lock);
+ if (!tux_module)
+ goto out_unlock;
+ if (!try_module_get(tux_module))
+ goto out_unlock;
+ spin_unlock(&tux_module_lock);
+
+ if (!sys_tux_ptr)
+ TUX_BUG();
+ ret = sys_tux_ptr(action, u_info);
+
+ spin_lock(&tux_module_lock);
+ module_put(tux_module);
+out_unlock:
+ spin_unlock(&tux_module_lock);
+
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(tux_module);
+EXPORT_SYMBOL_GPL(tux_module_lock);
+EXPORT_SYMBOL_GPL(sys_tux_ptr);
+
+EXPORT_SYMBOL_GPL(tux_Dprintk);
+EXPORT_SYMBOL_GPL(tux_TDprintk);
+
+#endif
#ifdef CONFIG_PROC_FS
void socket_seq_show(struct seq_file *seq)
{