[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Make vnet-module working on x86_64
Replacing the kernelcall "socketcall" with a partly copy from linux net/socket.c This call ist not in x86_64, ia64 and some other. With the patch the kernelcall is replaced. An other way will be an export of the needed function in net/socket.c... If there is something wrong with my patch, please let it me known, it's me first kernelmodule working ;-/ -- wbr Robert Valentan diff -r 2604abf98ede tools/vnet/vnet-module/varp_socket.c --- a/tools/vnet/vnet-module/varp_socket.c Tue Mar 28 09:09:44 2006 +++ b/tools/vnet/vnet-module/varp_socket.c Tue Mar 28 17:10:53 2006 @@ -16,6 +16,9 @@ * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA * */ + +static int errno; + #include <linux/kernel.h> #include <linux/types.h> #include <linux/version.h> @@ -36,7 +39,6 @@ /* Get macros needed to define system calls as functions in the kernel. */ #define __KERNEL_SYSCALLS__ -static int errno; #include <linux/unistd.h> #define MODULE_NAME "VARP" @@ -75,110 +77,254 @@ * The parts we need anyway. */ -/* Define the socketcall() syscall. - * Multiplexes all the socket-related calls. - * - * @param call socket call id - * @param args arguments (upto 6) - * @return call-dependent value - */ -static inline _syscall2(int, socketcall, - int, call, - unsigned long *, args) +/* the following code is copied from linux-kernel/net/socket.c + * As replacement of the __NR_socketcall, which exists not in x86_64 and + * same other systems. + * An alternate will be an export of the copied-functions in net/socket.c + */ +#define MAX_SOCK_ADDR 128 int socket(int family, int type, int protocol){ - unsigned long args[6]; - - args[0] = (unsigned long)family; - args[1] = (unsigned long)type; - args[2] = (unsigned long)protocol; - return socketcall(SYS_SOCKET, args); + + int retval; + struct socket *sock; + retval = sock_create(family, type, protocol, &sock); + if (retval < 0) + goto out; + + retval = sock_map_fd(sock); + if (retval < 0) + goto out_release; + +out: + /* It may be already another descriptor 8) Not kernel problem. */ + return retval; + +out_release: + sock_release(sock); + return retval; } int bind(int fd, struct sockaddr *umyaddr, int addrlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)umyaddr; - args[2] = (unsigned long)addrlen; - return socketcall(SYS_BIND, args); + + struct socket *sock; + char address[MAX_SOCK_ADDR]; + int err; + + if((sock = sockfd_lookup(fd,&err))!=NULL) + { + if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { + err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); + if (err) { + sockfd_put(sock); + return err; + } + err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); + } + sockfd_put(sock); + } + return err; } int connect(int fd, struct sockaddr *uservaddr, int addrlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)uservaddr; - args[2] = (unsigned long)addrlen; - return socketcall(SYS_CONNECT, args); + + struct socket *sock; + char address[MAX_SOCK_ADDR]; + int err; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + err = move_addr_to_kernel(uservaddr, addrlen, address); + if (err < 0) + goto out_put; + + err = security_socket_connect(sock, (struct sockaddr *)address, addrlen); + if (err) + goto out_put; + + err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, + sock->file->f_flags); +out_put: + sockfd_put(sock); +out: + return err; } int sendto(int fd, void * buff, size_t len, unsigned flags, struct sockaddr *addr, int addr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)buff; - args[2] = (unsigned long)len; - args[3] = (unsigned long)flags; - args[4] = (unsigned long)addr; - args[5] = (unsigned long)addr_len; - return socketcall(SYS_SENDTO, args); + + struct socket *sock; + char address[MAX_SOCK_ADDR]; + int err; + struct msghdr msg; + struct iovec iov; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + iov.iov_base=buff; + iov.iov_len=len; + msg.msg_name=NULL; + msg.msg_iov=&iov; + msg.msg_iovlen=1; + msg.msg_control=NULL; + msg.msg_controllen=0; + msg.msg_namelen=0; + if(addr) + { + err = move_addr_to_kernel(addr, addr_len, address); + if (err < 0) + goto out_put; + msg.msg_name=address; + msg.msg_namelen=addr_len; + } + if (sock->file->f_flags & O_NONBLOCK) + flags |= MSG_DONTWAIT; + msg.msg_flags = flags; + err = sock_sendmsg(sock, &msg, len); + +out_put: + sockfd_put(sock); +out: + return err; } int recvfrom(int fd, void * ubuf, size_t size, unsigned flags, struct sockaddr *addr, int *addr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)ubuf; - args[2] = (unsigned long)size; - args[3] = (unsigned long)flags; - args[4] = (unsigned long)addr; - args[5] = (unsigned long)addr_len; - return socketcall(SYS_RECVFROM, args); + + struct socket *sock; + struct iovec iov; + struct msghdr msg; + char address[MAX_SOCK_ADDR]; + int err,err2; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + + msg.msg_control=NULL; + msg.msg_controllen=0; + msg.msg_iovlen=1; + msg.msg_iov=&iov; + iov.iov_len=size; + iov.iov_base=ubuf; + msg.msg_name=address; + msg.msg_namelen=MAX_SOCK_ADDR; + if (sock->file->f_flags & O_NONBLOCK) + flags |= MSG_DONTWAIT; + err=sock_recvmsg(sock, &msg, size, flags); + + if(err >= 0 && addr != NULL) + { + err2=move_addr_to_user(address, msg.msg_namelen, addr, addr_len); + if(err2<0) + err=err2; + } + sockfd_put(sock); +out: + return err; } int setsockopt(int fd, int level, int optname, void *optval, int optlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)level; - args[2] = (unsigned long)optname; - args[3] = (unsigned long)optval; - args[4] = (unsigned long)optlen; - return socketcall(SYS_SETSOCKOPT, args); -} - + + int err; + struct socket *sock; + + if (optlen < 0) + return -EINVAL; + + if ((sock = sockfd_lookup(fd, &err))!=NULL) + { + err = security_socket_setsockopt(sock,level,optname); + if (err) { + sockfd_put(sock); + return err; + } + + if (level == SOL_SOCKET) + err=sock_setsockopt(sock,level,optname,optval,optlen); + else + err=sock->ops->setsockopt(sock, level, optname, optval, optlen); + sockfd_put(sock); + } + return err; +} + +/* not possible, because sock_getsockopt is not exported ... int getsockopt(int fd, int level, int optname, void *optval, int *optlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)level; - args[2] = (unsigned long)optname; - args[3] = (unsigned long)optval; - args[4] = (unsigned long)optlen; - return socketcall(SYS_GETSOCKOPT, args); -} + + int err; + struct socket *sock; + + if ((sock = sockfd_lookup(fd, &err))!=NULL) + { + err = security_socket_getsockopt(sock, level, optname); + if (err) { + sockfd_put(sock); + return err; + } + + if (level == SOL_SOCKET) + err=sock_getsockopt(sock,level,optname,optval,optlen); + else + err=sock->ops->getsockopt(sock, level, optname, optval, optlen); + sockfd_put(sock); + } + return err; +} +*/ int shutdown(int fd, int how){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)how; - return socketcall(SYS_SHUTDOWN, args); + + int err; + struct socket *sock; + + if ((sock = sockfd_lookup(fd, &err))!=NULL) + { + err = security_socket_shutdown(sock, how); + if (err) { + sockfd_put(sock); + return err; + } + + err=sock->ops->shutdown(sock, how); + sockfd_put(sock); + } + return err; } int getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)usockaddr; - args[2] = (unsigned long)usockaddr_len; - return socketcall(SYS_GETSOCKNAME, args); -} + + struct socket *sock; + char address[MAX_SOCK_ADDR]; + int len, err; + + sock = sockfd_lookup(fd, &err); + if (!sock) + goto out; + + err = security_socket_getsockname(sock); + if (err) + goto out_put; + + err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0); + if (err) + goto out_put; + err = move_addr_to_user(address, len, usockaddr, usockaddr_len); + +out_put: + sockfd_put(sock); +out: + return err; +} + +/** + * End of copy from net/socket.c + */ + /*============================================================================*/ /** Socket flags. */ @@ -577,7 +723,7 @@ int err = 0; mm_segment_t oldfs; - dprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port)); + iprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port)); oldfs = change_fs(KERNEL_DS); err = varp_mcast_open(mcaddr, port, &varp_mcast_sock); if(err < 0 ) goto exit; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |