Re: Can you specify a local IP or Interface to be used on a per NFSmount basis?

From: Ben Greear
Date: Thu Jan 19 2006 - 23:26:28 EST


Trond Myklebust wrote:
On Wed, 2006-01-18 at 19:28 -0800, Ben Greear wrote:


As David said, the place to fix it is in xs_bindresvport(), but there is
no support for passing this sort of information through the current NFS
binary mount structure. You would have to hack that up yourself.

I can think of some horrible hacks to grab info out of a text file based
on the mount point or some other available info...but if I actually
attempted to do it right..would you consider the patch for kernel
inclusion? Is it OK to modify the binary mount structure?


It is possible, yes: the binary structure carries a version number that
allows the kernel to distinguish the various revisions that the userland
mount program supports.

That said, the concensus at the moment appears to be that we should move
towards a text-based mount structure for NFS (like most of the other
filesystems have, and like NFSroot has) so I'd be reluctant to take
patches that define new binary structures.

Ok. This patch does extend the binary struct, and to do it really right,
we should probably pass in some sort of in_addr struct instead of the
single 'u32' for the IP address.

So, please just consider this a proof of concept. That said, with a
patched 'mount' binary (diff available if anyone cares), this does
do exactly what I want: allows binding an nfs client to a particular
local IP address.

If/when you get the text based interface working, I will try to cook
up an official patch worthy of inclusion if you have not already
done so.

This patch was inspired by a patch sent to me by: Dimitris Michailidis

Thanks,
Ben


diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -407,6 +407,12 @@ nfs_create_client(struct nfs_server *ser
__FUNCTION__, PTR_ERR(xprt));
return (struct rpc_clnt *)xprt;
}
+
+ if (data->local_ip != 0) {
+ printk("nfs: Configuring local ip address as: 0x%x\n",
+ data->local_ip);
+ }
+ xprt->local_address = data->local_ip; /* specify local IP address */
clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
server->rpc_ops->version, data->pseudoflavor);
if (IS_ERR(clnt)) {
@@ -1663,6 +1669,7 @@ static struct super_block *nfs_get_sb(st
deactivate_super(s);
return ERR_PTR(error);
}
+
s->s_flags |= MS_ACTIVE;
return s;
out_rpciod_down:
diff --git a/fs/super.c b/fs/super.c
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
--- a/include/linux/nfs_mount.h
+++ b/include/linux/nfs_mount.h
@@ -20,7 +20,7 @@
* mount-to-kernel version compatibility. Some of these aren't used yet
* but here they are anyway.
*/
-#define NFS_MOUNT_VERSION 6
+#define NFS_MOUNT_VERSION 7
#define NFS_MAX_CONTEXT_LEN 256

struct nfs_mount_data {
@@ -43,6 +43,8 @@ struct nfs_mount_data {
struct nfs3_fh root; /* 4 */
int pseudoflavor; /* 5 */
char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */
+ char pad[3]; /* 7 Align the context above */
+ unsigned int local_ip; /* 7 */
};

/* bits in the flags field */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -168,7 +168,8 @@ struct rpc_xprt {
reestablish_timeout;
struct work_struct connect_worker;
unsigned short port;
-
+ u32 local_address; /* local IP address to bind to */+
/*
* Disconnection of idle transports
*/
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -928,6 +928,8 @@ static int xs_bindresvport(struct rpc_xp
int err;
unsigned short port = xprt->port;

+ myaddr.sin_addr.s_addr = xprt->local_address;
+
do {
myaddr.sin_port = htons(port);
err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,

--
Ben Greear <greearb@xxxxxxxxxxxxxxx>
Candela Technologies Inc http://www.candelatech.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/