All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Make vnet-module working on x86_64
@ 2006-03-28 15:27 Robert Valentan
  2006-03-29 12:51 ` Keir Fraser
  0 siblings, 1 reply; 2+ messages in thread
From: Robert Valentan @ 2006-03-28 15:27 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 380 bytes --]

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

[-- Attachment #2: patch_vnet_1 --]
[-- Type: text/plain, Size: 8727 bytes --]

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;

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-03-29 12:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-28 15:27 [PATCH] Make vnet-module working on x86_64 Robert Valentan
2006-03-29 12:51 ` Keir Fraser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.