All of lore.kernel.org
 help / color / mirror / Atom feed
* 2.6.22 [PATCH 2/3] SUNRPC client: add interface for binding to a local address
@ 2007-07-09 20:23 Frank van Maarseveen
  0 siblings, 0 replies; only message in thread
From: Frank van Maarseveen @ 2007-07-09 20:23 UTC (permalink / raw)
  To: Linux NFS mailing list

In addition to binding to a local privileged port the NFS client should
allow binding to a specific local address. This is used by the server
for callbacks. The patch adds the necessary interface.

Signed-off-by: Frank van Maarseveen <frankvm@frankvm.com>
---

diff -urp a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
--- a/include/linux/sunrpc/clnt.h	2007-07-09 19:43:50.000000000 +0200
+++ b/include/linux/sunrpc/clnt.h	2007-07-09 19:53:10.000000000 +0200
@@ -98,6 +98,7 @@ struct rpc_create_args {
 	int			protocol;
 	struct sockaddr		*address;
 	size_t			addrsize;
+	struct sockaddr		*saddress;
 	struct rpc_timeout	*timeout;
 	char			*servername;
 	struct rpc_program	*program;
diff -urp a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
--- a/include/linux/sunrpc/xprt.h	2007-07-09 19:48:04.000000000 +0200
+++ b/include/linux/sunrpc/xprt.h	2007-07-09 19:53:10.000000000 +0200
@@ -198,6 +198,7 @@ struct rpc_xprt {
 
 struct rpc_xprtsock_create {
 	int			proto;		/* IPPROTO_UDP or IPPROTO_TCP */
+	struct sockaddr *	srcaddr;	/* optional local address */
 	struct sockaddr *	dstaddr;	/* remote peer address */
 	size_t			addrlen;
 	struct rpc_timeout *	timeout;	/* optional timeout parameters */
diff -urp a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c	2007-07-09 19:46:35.000000000 +0200
+++ b/net/sunrpc/clnt.c	2007-07-09 19:53:10.000000000 +0200
@@ -207,6 +207,7 @@ struct rpc_clnt *rpc_create(struct rpc_c
 	struct rpc_clnt *clnt;
 	struct rpc_xprtsock_create xprtargs = {
 		.proto = args->protocol,
+		.srcaddr = args->saddress,
 		.dstaddr = args->address,
 		.addrlen = args->addrsize,
 		.timeout = args->timeout
diff -urp a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
--- a/net/sunrpc/xprtsock.c	2007-07-09 19:46:35.000000000 +0200
+++ b/net/sunrpc/xprtsock.c	2007-07-09 19:53:10.000000000 +0200
@@ -235,6 +235,7 @@ struct sock_xprt {
 	 * Connection of transports
 	 */
 	struct delayed_work	connect_worker;
+	struct sockaddr_storage	addr;
 	unsigned short		port;
 
 	/*
@@ -1146,31 +1147,36 @@ static void xs_set_port(struct rpc_xprt 
 	sap->sin_port = htons(port);
 }
 
-static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock)
+static int xs_bind(struct sock_xprt *transport, struct socket *sock)
 {
 	struct sockaddr_in myaddr = {
 		.sin_family = AF_INET,
 	};
+	struct sockaddr_in *sa;
 	int err;
 	unsigned short port = transport->port;
 
+	if (!transport->xprt.resvport)
+		port = 0;
+	sa = (struct sockaddr_in *)&transport->addr;
+	myaddr.sin_addr = sa->sin_addr;
 	do {
 		myaddr.sin_port = htons(port);
 		err = kernel_bind(sock, (struct sockaddr *) &myaddr,
 						sizeof(myaddr));
+		if (!transport->xprt.resvport)
+			break;
 		if (err == 0) {
 			transport->port = port;
-			dprintk("RPC:       xs_bindresvport bound to port %u\n",
-					port);
-			return 0;
+			break;
 		}
 		if (port <= xprt_min_resvport)
 			port = xprt_max_resvport;
 		else
 			port--;
 	} while (err == -EADDRINUSE && port != transport->port);
-
-	dprintk("RPC:       can't bind to reserved port (%d).\n", -err);
+	dprintk("RPC:       xs_bind "NIPQUAD_FMT":%u: %s (%d)\n",
+		NIPQUAD(myaddr.sin_addr), port, err ? "failed" : "ok", err);
 	return err;
 }
 
@@ -1229,7 +1235,7 @@ static void xs_udp_connect_worker(struct
 	}
 	xs_reclassify_socket(sock);
 
-	if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
+	if (xs_bind(transport, sock)) {
 		sock_release(sock);
 		goto out;
 	}
@@ -1316,7 +1322,7 @@ static void xs_tcp_connect_worker(struct
 		}
 		xs_reclassify_socket(sock);
 
-		if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
+		if (xs_bind(transport, sock)) {
 			sock_release(sock);
 			goto out;
 		}
@@ -1534,6 +1540,8 @@ static struct rpc_xprt *xs_setup_xprt(st
 
 	memcpy(&xprt->addr, args->dstaddr, args->addrlen);
 	xprt->addrlen = args->addrlen;
+	if (args->srcaddr)
+		memcpy(&new->addr, args->srcaddr, args->addrlen);
 	new->port = xs_get_random_port();
 
 	return xprt;

-- 
Frank

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-07-09 20:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-09 20:23 2.6.22 [PATCH 2/3] SUNRPC client: add interface for binding to a local address Frank van Maarseveen

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.