2003-04-11 23:35:17

by Bruce Allan

[permalink] [raw]
Subject: [PATCH 1/5] initial changes for NFS-over-IPv6 (linux-2.5.66-NFS_IPv6-nfs.dif)

This patch against 2.5.66 provides for IPv6 support for the NFS client.

diff -Naurp linux-2.5.66/fs/nfs/inode.c linux-2.5.66-NFS_IPV6/fs/nfs/inode.c
--- linux-2.5.66/fs/nfs/inode.c 2003-03-24 14:01:15.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/fs/nfs/inode.c 2003-04-07 17:37:15.000000000 -0700
@@ -34,6 +34,7 @@
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/vfs.h>
+#include <net/ipv6.h>

#include <asm/system.h>
#include <asm/uaccess.h>
@@ -404,8 +405,9 @@ int nfs_fill_super(struct super_block *s
timeparms.to_retries = 5;

/* Now create transport and client */
- xprt = xprt_create_proto(tcp? IPPROTO_TCP : IPPROTO_UDP,
- &server->addr, &timeparms);
+ xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
+ (struct sockaddr *)&server->addr,
+ &timeparms);
if (xprt == NULL) {
printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
goto out_fail;
@@ -1182,11 +1184,36 @@ static int nfs_compare_super(struct supe
{
struct nfs_server *server = data;
struct nfs_server *old = NFS_SB(sb);
+ struct sockaddr_in *old_sin, *server_sin;
+ struct sockaddr_in6 *old_sin6, *server_sin6;

- if (old->addr.sin_addr.s_addr != server->addr.sin_addr.s_addr)
- return 0;
- if (old->addr.sin_port != server->addr.sin_port)
- return 0;
+ switch ( server->addr.ss_family ) {
+ case AF_INET:
+ old_sin = (struct sockaddr_in *)&(old->addr);
+ server_sin = (struct sockaddr_in *)&(server->addr);
+
+ if (old_sin->sin_addr.s_addr != server_sin->sin_addr.s_addr)
+ return 0;
+ if (old_sin->sin_port != server_sin->sin_port)
+ return 0;
+ break;
+
+ case AF_INET6:
+ old_sin6 = (struct sockaddr_in6 *)&(old->addr);
+ server_sin6 = (struct sockaddr_in6 *)&(server->addr);
+
+ if (ipv6_addr_cmp(&(old_sin6->sin6_addr),
+ &(server_sin6->sin6_addr)))
+ return 0;
+ if (old_sin6->sin6_port != server_sin6->sin6_port)
+ return 0;
+ break;
+
+ default:
+ printk("NFS: %s unknown address family %d\n", __FUNCTION__,
+ server->addr.ss_family);
+ break;
+ }
return !memcmp(&old->fh, &server->fh, sizeof(struct nfs_fh));
}

@@ -1198,6 +1225,8 @@ static struct super_block *nfs_get_sb(st
struct super_block *s;
struct nfs_fh *root;
struct nfs_mount_data *data = raw_data;
+ struct sockaddr_in *sin = NULL;
+ struct sockaddr_in6 *sin6 = NULL;

if (!data) {
printk("nfs_read_super: missing data argument\n");
@@ -1236,10 +1265,29 @@ static struct super_block *nfs_get_sb(st
}
/* We now require that the mount process passes the remote address */
memcpy(&server->addr, &data->addr, sizeof(server->addr));
- if (server->addr.sin_addr.s_addr == INADDR_ANY) {
- printk("NFS: mount program didn't pass remote address!\n");
- kfree(server);
- return ERR_PTR(-EINVAL);
+ switch ( server->addr.ss_family ) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(server->addr);
+
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ printk("NFS: mount program didn't pass remote IPv4 address!\n");
+ kfree(server);
+ return ERR_PTR(-EINVAL);
+ }
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&(server->addr);
+
+ if (ipv6_addr_any(&sin6->sin6_addr)) {
+ printk("NFS: mount program didn't pass remote IPv6 address!\n");
+ kfree(server);
+ return ERR_PTR(-EINVAL);
+ }
+ break;
+ default:
+ printk("NFS: %s unknown address family %d\n", __FUNCTION__,
+ server->addr.ss_family);
+ break;
}

s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
@@ -1331,7 +1379,8 @@ static int nfs4_fill_super(struct super_
}

/* Now create transport and client */
- xprt = xprt_create_proto(proto, &server->addr, &timeparms);
+ xprt = xprt_create_proto(proto, (struct sockaddr *)&server->addr,
+ &timeparms);
if (xprt == NULL) {
printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
goto out_fail;
@@ -1422,6 +1471,8 @@ static struct super_block *nfs4_get_sb(s
struct super_block *s;
struct nfs4_mount_data *data = raw_data;
void *p;
+ struct sockaddr_in *sin = NULL;
+ struct sockaddr_in6 *sin6 = NULL;

if (!data) {
printk("nfs_read_super: missing data argument\n");
@@ -1462,11 +1513,33 @@ static struct super_block *nfs4_get_sb(s
s = ERR_PTR(-EFAULT);
goto out_free;
}
- if (server->addr.sin_family != AF_INET ||
- server->addr.sin_addr.s_addr == INADDR_ANY) {
- printk("NFS: mount program didn't pass remote IP address!\n");
+
+ switch ( server->addr.ss_family ) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)&(server->addr);
+
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ printk("NFS: mount program didn't pass remote IPv4 address!\n");
+ s = ERR_PTR(-EINVAL);
+ goto out_free;
+ }
+ break;
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&(server->addr);
+
+ if (ipv6_addr_any(&sin6->sin6_addr)) {
+ printk("NFS: mount program didn't pass remote IPv6 address!\n");
+ s = ERR_PTR(-EINVAL);
+ goto out_free;
+ }
+ break;
+
+ default:
+ printk("NFS: mount program didn't pass remote IP address and/or address family!\n");
s = ERR_PTR(-EINVAL);
goto out_free;
+ break;
}

s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
diff -Naurp linux-2.5.66/fs/nfs/mount_clnt.c linux-2.5.66-NFS_IPV6/fs/nfs/mount_clnt.c
--- linux-2.5.66/fs/nfs/mount_clnt.c 2003-03-24 13:59:56.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/fs/nfs/mount_clnt.c 2003-04-07 17:37:42.000000000 -0700
@@ -29,8 +29,7 @@
#define MOUNT_UMNT 3
*/

-static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
- int, int);
+static struct rpc_clnt * mnt_create(char *, struct sockaddr *, int, int);
struct rpc_program mnt_program;

struct mnt_fhstatus {
@@ -42,7 +41,7 @@ struct mnt_fhstatus {
* Obtain an NFS file handle for the given host and path
*/
int
-nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
+nfsroot_mount(struct sockaddr *addr, char *path, struct nfs_fh *fh,
int version, int protocol)
{
struct rpc_clnt *mnt_clnt;
@@ -66,8 +65,7 @@ nfsroot_mount(struct sockaddr_in *addr,
}

static struct rpc_clnt *
-mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
- int protocol)
+mnt_create(char *hostname, struct sockaddr *srvaddr, int version, int protocol)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
diff -Naurp linux-2.5.66/include/linux/nfs_fs.h linux-2.5.66-NFS_IPV6/include/linux/nfs_fs.h
--- linux-2.5.66/include/linux/nfs_fs.h 2003-03-24 14:00:17.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/include/linux/nfs_fs.h 2003-04-07 17:40:03.000000000 -0700
@@ -375,8 +375,7 @@ extern void nfs_readdata_release(struct
* linux/fs/mount_clnt.c
* (Used only by nfsroot module)
*/
-extern int nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
- int, int);
+extern int nfsroot_mount(struct sockaddr *, char *, struct nfs_fh *, int, int);

/*
* inline functions
diff -Naurp linux-2.5.66/include/linux/nfs_fs_sb.h linux-2.5.66-NFS_IPV6/include/linux/nfs_fs_sb.h
--- linux-2.5.66/include/linux/nfs_fs_sb.h 2003-03-24 14:01:53.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/include/linux/nfs_fs_sb.h 2003-04-07 17:40:24.000000000 -0700
@@ -26,7 +26,7 @@ struct nfs_server {
unsigned int namelen;
char * hostname; /* remote hostname */
struct nfs_fh fh;
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
#if CONFIG_NFS_V4
/* Our own IP address, as a null-terminated string.
* This is used to generate the clientid, and the callback address.
diff -Naurp linux-2.5.66/include/linux/nfs.h linux-2.5.66-NFS_IPV6/include/linux/nfs.h
--- linux-2.5.66/include/linux/nfs.h 2003-03-24 14:01:14.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/include/linux/nfs.h 2003-04-01 15:10:16.000000000 -0800
@@ -8,6 +8,11 @@
#define _LINUX_NFS_H

#include <linux/sunrpc/msg_prot.h>
+#ifdef CONFIG_NFS_IPV6
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#endif

#define NFS_PROGRAM 100003
#define NFS_PORT 2049
@@ -116,6 +121,17 @@ enum nfs_ftype {
NFFIFO = 8
};

+#ifdef CONFIG_NFS_IPV6
+/* IP address information */
+struct nfs_addr {
+ sa_family_t family;
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } addr_u;
+};
+
+#endif
#if defined(__KERNEL__)
/*
* This is the kernel NFS client file handle representation
diff -Naurp linux-2.5.66/include/linux/nfs_mount.h linux-2.5.66-NFS_IPV6/include/linux/nfs_mount.h
--- linux-2.5.66/include/linux/nfs_mount.h 2003-03-24 13:59:54.000000000 -0800
+++ linux-2.5.66-NFS_IPV6/include/linux/nfs_mount.h 2003-04-10 16:37:33.000000000 -0700
@@ -20,7 +20,11 @@
* mount-to-kernel version compatibility. Some of these aren't used yet
* but here they are anyway.
*/
+#ifdef CONFIG_NFS_IPV6
+#define NFS_MOUNT_VERSION 5
+#else
#define NFS_MOUNT_VERSION 4
+#endif

struct nfs_mount_data {
int version; /* 1 */
@@ -35,12 +39,19 @@ struct nfs_mount_data {
int acregmax; /* 1 */
int acdirmin; /* 1 */
int acdirmax; /* 1 */
+#ifdef CONFIG_NFS_IPV6
+ struct sockaddr_in old_addr; /* 1 */
+#else
struct sockaddr_in addr; /* 1 */
+#endif
char hostname[256]; /* 1 */
int namlen; /* 2 */
unsigned int bsize; /* 3 */
struct nfs3_fh root; /* 4 */
int pseudoflavor; /* 4 */
+#ifdef CONFIG_NFS_IPV6
+ struct sockaddr_storage addr; /* 5 */
+#endif
};

/* bits in the flags field */

--
Bruce Allan
Linux Technology Center
IBM Corporation, Beaverton OR



-------------------------------------------------------
This SF.net email is sponsored by: Etnus, makers of TotalView, The debugger
for complex code. Debugging C/C++ programs can leave you feeling lost and
disoriented. TotalView can help you find your way. Available on major UNIX
and Linux platforms. Try it free. http://www.etnus.com
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs