[PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Here is a second missing part of the IPv6 support in NFS server code concerning knfd syscall interface. It updates write_getfd and write_getfd to accept IPv6 addresses. Applies on a kernel including ip_map cache modifications Tests: tested with only IPv4 network and basic nfs ops (mount, file creation and modification) Signed-off-by: Aurelien Charbon <[EMAIL PROTECTED]> --- nfsctl.c | 41 ++--- 1 file changed, 30 insertions(+), 11 deletions(-) diff -p -u -r -N linux-2.6.23-ipmap-cache/fs/nfsd/nfsctl.c linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.23-ipmap-cache/fs/nfsd/nfsctl.c2007-10-11 15:23:07.0 +0200 +++ linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c2007-10-12 10:49:31.0 +0200 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -228,9 +228,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +sin = &sin6_storage; +switch (data->gd_addr.sa_family) { +case AF_INET6: +sin = (struct sockaddr_in6 *)&data->gd_addr; +in6 = sin->sin6_addr; +break; +case AF_INET: +/* Map v4 address into v6 structure */ +ipv6_addr_v4map(((struct sockaddr_in *)&data->gd_addr)->sin_addr, in6); +break; +default: goto out; -sin = (struct sockaddr_in *)&data->gd_addr; +} + if (data->gd_maxlen > NFS3_FHSIZE) data->gd_maxlen = NFS3_FHSIZE; @@ -238,9 +249,6 @@ static ssize_t write_getfs(struct file * exp_readlock(); -/* IPv6 address mapping */ -ipv6_addr_v4map(sin->sin_addr, in6); - if (!(clp = auth_unix_lookup(in6))) err = -EPERM; else { @@ -257,7 +265,7 @@ static ssize_t write_getfs(struct file * static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin, sin6_storage; struct in6_addr in6; struct auth_domain *clp; int err = 0; @@ -268,18 +276,29 @@ static ssize_t write_getfd(struct file * return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +if (data->gd_addr.sa_family != AF_INET && +data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; -sin = (struct sockaddr_in *)&data->gd_addr; +sin = &sin6_storage; exp_readlock(); -/* IPv6 address mapping */ -ipv6_addr_v4map(sin->sin_addr, in6); +switch (data->gd_addr.sa_family) { +case AF_INET: +/* IPv6 address mapping */ +ipv6_addr_v4map(((struct sockaddr_in *)&data->gd_addr)->sin_addr, in6); +break; +case AF_INET6: +sin = (struct sockaddr_in6 *)&data->gd_addr; +in6 = sin->sin6_addr; +break; +default: +BUG(); +} if (!(clp = auth_unix_lookup(in6))) err = -EPERM; diff -p -u -r -N linux-2.6.23-ipmap-cache/net/sunrpc/svcauth_unix.c linux-2.6.23-nfsctl/net/sunrpc/svcauth_unix.c --- linux-2.6.23-ipmap-cache/net/sunrpc/svcauth_unix.c2007-10-12 10:47:27.0 +0200 +++ linux-2.6.23-nfsctl/net/sunrpc/svcauth_unix.c2007-10-12 10:03:56.0 +0200 @@ -677,7 +677,7 @@ svcauth_unix_set_client(struct svc_rqst case AF_INET: sin = svc_addr_in(rqstp); sin6 = &sin6_storage; -ipv6_addr_set(&sin6->sin6_addr, 0, 0, +ipv6_addr_set(&sin6->sin6_addr, 0, 0, htonl(0x), sin->sin_addr.s_addr); break; case AF_INET6: -- Aurelien Charbon Bull SAS Echirolles - France http://www.bullopensource.org/ diff -p -u -r -N linux-2.6.23-ipmap-cache/fs/nfsd/nfsctl.c linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.23-ipmap-cache/fs/nfsd/nfsctl.c 2007-10-11 15:23:07.0 +0200 +++ linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c 2007-10-12 10:49:31.0 +0200 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; - struct sockaddr_in *sin; + struct sockaddr_in6 *sin, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -228,9 +228,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + sin = &sin6_storage; + switch (data->gd_addr.sa_family) { + case AF_INET6: + sin = (struct sockaddr_in6 *)&
[PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Here is a second missing part of the IPv6 support in NFS server code concerning knfd syscall interface. It updates write_getfd and write_getfd to accept IPv6 addresses. I've updated it according to Brian's comments, and removed some unused code. Applies on a kernel including ip_map cache modifications Tests: tested with only IPv4 network and basic nfs ops (mount, file creation and modification) Signed-off-by: Aurelien Charbon <[EMAIL PROTECTED]> --- diff -p -u -r -N linux-2.6.23-ipmap/fs/nfsd/nfsctl.c linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.23-ipmap/fs/nfsd/nfsctl.c2007-10-22 10:32:51.0 +0200 +++ linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c2007-10-22 11:06:13.0 +0200 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -229,9 +229,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +switch (data->gd_addr.sa_family) { +case AF_INET6: +sin6 = &sin6_storage; +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &(sin6->sin6_addr)); +break; +case AF_INET: +/* Map v4 address into v6 structure */ +ipv6_addr_set(&in6, 0, 0, htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); +break; +default: goto out; -sin = (struct sockaddr_in *)&data->gd_addr; +} + if (data->gd_maxlen > NFS3_FHSIZE) data->gd_maxlen = NFS3_FHSIZE; @@ -239,10 +250,7 @@ static ssize_t write_getfs(struct file * exp_readlock(); -/* IPv6 address mapping */ -ipv6_addr_set(&in6, 0, 0, htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); - -if (!(clp = auth_unix_lookup(in6))) +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); @@ -258,7 +266,7 @@ static ssize_t write_getfs(struct file * static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh fh; @@ -269,20 +277,30 @@ static ssize_t write_getfd(struct file * return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +if (data->gd_addr.sa_family != AF_INET && data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; -sin = (struct sockaddr_in *)&data->gd_addr; exp_readlock(); - -/* IPv6 address mapping */ -ipv6_addr_set(&in6, 0, 0, htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); -if (!(clp = auth_unix_lookup(in6))) +switch (data->gd_addr.sa_family) { +case AF_INET: +/* IPv6 address mapping */ +ipv6_addr_set(&in6, 0, 0, htonl(0x), ((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr); +break; +case AF_INET6: +sin6 = &sin6_storage; +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &(sin6->sin6_addr)); +break; +default: +BUG(); +} + +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); -- Aurelien Charbon Linux NFSv4 team Bull SAS Echirolles - France http://nfsv4.bullopensource.org/ diff -p -u -r -N linux-2.6.23-ipmap/fs/nfsd/nfsctl.c linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.23-ipmap/fs/nfsd/nfsctl.c 2007-10-22 10:32:51.0 +0200 +++ linux-2.6.23-nfsctl/fs/nfsd/nfsctl.c 2007-10-22 11:06:13.0 +0200 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; - struct sockaddr_in *sin; + struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -229,9 +229,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + switch (data->gd_addr.sa_family) { + case AF_INET6: + sin6 = &sin6_storage; + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &(sin6->sin6_addr)); + break; + case AF_INET: + /* Map v4 address into v6 structure */ + ipv6_addr_set(&in6, 0,
[PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Here is a second missing part of the IPv6 support in NFS server code concerning knfd syscall interface. It updates write_getfd and write_getfd to accept IPv6 addresses. Applies on a kernel including ip_map cache modifications Tests: tested with only IPv4 network and basic nfs ops (mount, file creation and modification) Signed-off-by: Aurelien Charbon <[EMAIL PROTECTED]> --- diff -p -u -r -N linux-2.6.24-rc1-ipmap/fs/nfsd/nfsctl.c linux-2.6.24-rc1-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.24-rc1-ipmap/fs/nfsd/nfsctl.c2007-10-30 17:15:45.0 +0100 +++ linux-2.6.24-rc1-nfsctl/fs/nfsd/nfsctl.c2007-10-30 17:21:36.0 +0100 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -229,9 +229,21 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +switch (data->gd_addr.sa_family) { +case AF_INET6: +sin6 = &sin6_storage; +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &sin6->sin6_addr); +break; +case AF_INET: +/* Map v4 address into v6 structure */ +ipv6_addr_set(&in6, 0, 0, +htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); +break; +default: goto out; -sin = (struct sockaddr_in *)&data->gd_addr; +} + if (data->gd_maxlen > NFS3_FHSIZE) data->gd_maxlen = NFS3_FHSIZE; @@ -239,11 +251,7 @@ static ssize_t write_getfs(struct file * exp_readlock(); -/* IPv6 address mapping */ -ipv6_addr_set(&in6, 0, 0, -htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); - -if (!(clp = auth_unix_lookup(in6))) +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); @@ -259,7 +267,7 @@ static ssize_t write_getfs(struct file * static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh fh; @@ -270,20 +278,31 @@ static ssize_t write_getfd(struct file * return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +if (data->gd_addr.sa_family != AF_INET && data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; -sin = (struct sockaddr_in *)&data->gd_addr; exp_readlock(); - -/* IPv6 address mapping */ -ipv6_addr_set(&in6, 0, 0, htonl(0x), (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr)); -if (!(clp = auth_unix_lookup(in6))) +switch (data->gd_addr.sa_family) { +case AF_INET: +/* IPv6 address mapping */ +ipv6_addr_set(&in6, 0, 0, htonl(0x), +((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr); +break; +case AF_INET6: +sin6 = &sin6_storage; +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &sin6->sin6_addr); +break; +default: +BUG(); +} + +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); -- Aurelien Charbon Linux NFSv4 team Bull SAS Echirolles - France http://nfsv4.bullopensource.org/ diff -p -u -r -N linux-2.6.24-rc1-ipmap/fs/nfsd/nfsctl.c linux-2.6.24-rc1-nfsctl/fs/nfsd/nfsctl.c --- linux-2.6.24-rc1-ipmap/fs/nfsd/nfsctl.c 2007-10-30 17:15:45.0 +0100 +++ linux-2.6.24-rc1-nfsctl/fs/nfsd/nfsctl.c 2007-10-30 17:21:36.0 +0100 @@ -219,7 +219,7 @@ static ssize_t write_unexport(struct fil static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; - struct sockaddr_in *sin; + struct sockaddr_in6 *sin6, sin6_storage; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; @@ -229,9 +229,21 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + switch (data->gd_addr.sa_family) { + case AF_INET6: + sin6 = &sin6_storage; + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &sin6->sin6_addr); + break; + case AF_INET: + /* Map v4 address into v6 structure */ + ipv6_addr_set(&in6, 0, 0, +htonl(0xFF
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Hi Aurelien, Comments in-line. Aurélien Charbon wrote: Here is a second missing part of the IPv6 support in NFS server code concerning knfd syscall interface. -struct sockaddr_in *sin; +struct sockaddr_in6 *sin, sin6_storage; Nit, should call this sin6 now. @@ -228,9 +228,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +sin = &sin6_storage; This should be moved in the AF_INET case. +switch (data->gd_addr.sa_family) { +case AF_INET6: +sin = (struct sockaddr_in6 *)&data->gd_addr; +in6 = sin->sin6_addr; in6 is a structure, not a pointer. If you want it do this you have to use ipv6_addr_copy(). +case AF_INET: +/* Map v4 address into v6 structure */ +ipv6_addr_v4map(((struct sockaddr_in *)&data->gd_addr)->sin_addr, in6); ipv6_addr_set(...) @@ -257,7 +265,7 @@ static ssize_t write_getfs(struct file * static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; -struct sockaddr_in *sin; +struct sockaddr_in6 *sin, sin6_storage; Nit, sin -> sin6. @@ -268,18 +276,29 @@ static ssize_t write_getfd(struct file * return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +if (data->gd_addr.sa_family != AF_INET && +data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; -sin = (struct sockaddr_in *)&data->gd_addr; +sin = &sin6_storage; Move in AF_INET case. -/* IPv6 address mapping */ -ipv6_addr_v4map(sin->sin_addr, in6); +switch (data->gd_addr.sa_family) { +case AF_INET: +/* IPv6 address mapping */ +ipv6_addr_v4map(((struct sockaddr_in *)&data->gd_addr)->sin_addr, in6); Use ipv6_set_addr(...) +break; +case AF_INET6: +sin = (struct sockaddr_in6 *)&data->gd_addr; +in6 = sin->sin6_addr; Must use ipv6_addr_copy() here too. -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Hi Aurelien, Again, a few more comments. I might just modify these in my own tree and send out a patch that combines both into one, it might be less work. @@ -229,9 +229,20 @@ static ssize_t write_getfs(struct file * return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + switch (data->gd_addr.sa_family) { + case AF_INET6: + sin6 = &sin6_storage; This should be: in6 = &sin6_storage; + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &(sin6->sin6_addr)); Extra () here. - if (!(clp = auth_unix_lookup(in6))) + switch (data->gd_addr.sa_family) { + case AF_INET: + /* IPv6 address mapping */ + ipv6_addr_set(&in6, 0, 0, htonl(0x), ((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr); + break; + case AF_INET6: + sin6 = &sin6_storage; This should be: in6 = &sin6_storage; + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &(sin6->sin6_addr)); Extra () here. -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Hi Aurelien, This is a combination of your two patches into one, cleaned-up with all my complaints. I also added an ipv6_addr_set_v4mapped() inline after someone else here convinced me it gets rid of a lot of cruft from the code. The DCCP, etc. code can be cleaned-up later if this gets accepted. I have only compile-tested this, hoping you can test the functionality. -Brian Add IPv6 support to NFS server ip_map caching code and knfsd syscall interface - write_getfs() and write_getfd() will now accept IPv6 addresses. Signed-off-by: Brian Haley <[EMAIL PROTECTED]> diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 66d0aeb..c47ba77 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -35,6 +35,7 @@ #include #include #include +#include #define NFSDDBG_FACILITY NFSDDBG_EXPORT @@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp) { struct auth_domain *dom; int i, err; + struct in6_addr in6; /* First, consistency check. */ err = -EINVAL; @@ -1574,9 +1576,10 @@ exp_addclient(struct nfsctl_client *ncp) goto out_unlock; /* Insert client into hashtable. */ - for (i = 0; i < ncp->cl_naddr; i++) - auth_unix_add_addr(ncp->cl_addrlist[i], dom); - + for (i = 0; i < ncp->cl_naddr; i++) { + ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &in6); + auth_unix_add_addr(&in6, dom); + } auth_unix_forget_old(dom); auth_domain_put(dom); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 77dc989..5cb5f0d 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -37,6 +37,7 @@ #include #include +#include /* * We have a single directory with 9 nodes in it. @@ -219,24 +220,37 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; + struct in6_addr in6; if (size < sizeof(*data)) return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + switch (data->gd_addr.sa_family) { + case AF_INET: + sin = (struct sockaddr_in *)&data->gd_addr; + ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &sin6->sin6_addr); + break; + default: goto out; - sin = (struct sockaddr_in *)&data->gd_addr; + } + if (data->gd_maxlen > NFS3_FHSIZE) data->gd_maxlen = NFS3_FHSIZE; res = (struct knfsd_fh*)buf; exp_readlock(); - if (!(clp = auth_unix_lookup(sin->sin_addr))) + + if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); @@ -253,25 +267,41 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; struct auth_domain *clp; int err = 0; struct knfsd_fh fh; char *res; + struct in6_addr in6; if (size < sizeof(*data)) return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; - if (data->gd_addr.sa_family != AF_INET) + if (data->gd_addr.sa_family != AF_INET && + data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; - sin = (struct sockaddr_in *)&data->gd_addr; exp_readlock(); - if (!(clp = auth_unix_lookup(sin->sin_addr))) + + switch (data->gd_addr.sa_family) { + case AF_INET: + sin = (struct sockaddr_in *)&data->gd_addr; + ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&data->gd_addr; + ipv6_addr_copy(&in6, &sin6->sin6_addr); + break; + default: + goto out; + } + + if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index 22e1ef8..64ecb93 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -15,6 +15,7 @@ #include #include #include +#include #define SVC_CRED_NGROUPS 32 struct svc_cred { @@ -120,10 +121,10 @@ extern void svc_auth_unregister(rpc_authflavor_t flavor); extern struct auth_domain *unix_domain_find(char *name); extern void auth_domain_put(struct auth_domain *item); -extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom); +extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom); extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new); extern struct auth_domain *auth_domain_find(char *name); -extern struct auth_domain *auth_unix_lookup(struct in_addr addr); +extern struct auth_domain *auth_unix_lookup(struct in6_addr *addr); extern int auth_unix_forget_old(struct auth_domain *dom); extern void svcauth_unix_purge(void); extern void svcauth_unix_info_release(void *); d
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
On Monday October 22, [EMAIL PROTECTED] wrote: > Here is a second missing part of the IPv6 support in NFS server code > concerning knfd syscall interface. > It updates write_getfd and write_getfd to accept IPv6 addresses. Sorry for not replying to this earlier - I saw the Oct 12 post and thought about it but didn't actually reply before getting distracted :-( I think this patch is unnecessary and hence not wanted. The getfs / getfs calls should be considered legacy calls. Adding functionality to them is not appropriate. IPv6 addresses should be handled only via the /proc/net/rpc/auth.unix.ip interface. Thanks, NeilBrown - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Aurélien Charbon wrote: Here is a second missing part of the IPv6 support in NFS server code concerning knfd syscall interface. It updates write_getfd and write_getfd to accept IPv6 addresses. Applies on a kernel including ip_map cache modifications Both patches still have bugs, I think the patch I sent yesterday fixed them all, so I would recommend using that instead. Of course Neil's comment possibly trumps all that anyways... -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Thank you Brian Sorry, I did not see what you sent. I have tested it with an IPv4 configuration. It's OK. So Neil, Bruce, you can take this one for review. fs/nfsd/export.c |9 ++- fs/nfsd/nfsctl.c | 42 -- include/linux/sunrpc/svcauth.h |5 + include/net/ipv6.h | 10 +++ net/sunrpc/svcauth_unix.c | 118 +++-- 5 files changed, 134 insertions(+), 50 deletions(-) Signed-off-by: Brian Haley <[EMAIL PROTECTED]> Signed-off-by: Aurelien Charbon <[EMAIL PROTECTED]> --- diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 66d0aeb..c47ba77 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -35,6 +35,7 @@ #include #include #include +#include #define NFSDDBG_FACILITYNFSDDBG_EXPORT @@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp) { struct auth_domain*dom; inti, err; +struct in6_addrin6; /* First, consistency check. */ err = -EINVAL; @@ -1574,9 +1576,10 @@ exp_addclient(struct nfsctl_client *ncp) goto out_unlock; /* Insert client into hashtable. */ -for (i = 0; i < ncp->cl_naddr; i++) -auth_unix_add_addr(ncp->cl_addrlist[i], dom); - +for (i = 0; i < ncp->cl_naddr; i++) { +ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &in6); +auth_unix_add_addr(&in6, dom); +} auth_unix_forget_old(dom); auth_domain_put(dom); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 77dc989..5cb5f0d 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -37,6 +37,7 @@ #include #include +#include /* *We have a single directory with 9 nodes in it. @@ -219,24 +220,37 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size) { struct nfsctl_fsparm *data; struct sockaddr_in *sin; +struct sockaddr_in6 *sin6; struct auth_domain *clp; int err = 0; struct knfsd_fh *res; +struct in6_addr in6; if (size < sizeof(*data)) return -EINVAL; data = (struct nfsctl_fsparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +switch (data->gd_addr.sa_family) { +case AF_INET: +sin = (struct sockaddr_in *)&data->gd_addr; +ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); +break; +case AF_INET6: +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &sin6->sin6_addr); +break; +default: goto out; -sin = (struct sockaddr_in *)&data->gd_addr; +} + if (data->gd_maxlen > NFS3_FHSIZE) data->gd_maxlen = NFS3_FHSIZE; res = (struct knfsd_fh*)buf; exp_readlock(); -if (!(clp = auth_unix_lookup(sin->sin_addr))) + +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); @@ -253,25 +267,41 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size) { struct nfsctl_fdparm *data; struct sockaddr_in *sin; +struct sockaddr_in6 *sin6; struct auth_domain *clp; int err = 0; struct knfsd_fh fh; char *res; +struct in6_addr in6; if (size < sizeof(*data)) return -EINVAL; data = (struct nfsctl_fdparm*)buf; err = -EPROTONOSUPPORT; -if (data->gd_addr.sa_family != AF_INET) +if (data->gd_addr.sa_family != AF_INET && +data->gd_addr.sa_family != AF_INET6) goto out; err = -EINVAL; if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) goto out; res = buf; -sin = (struct sockaddr_in *)&data->gd_addr; exp_readlock(); -if (!(clp = auth_unix_lookup(sin->sin_addr))) + +switch (data->gd_addr.sa_family) { +case AF_INET: +sin = (struct sockaddr_in *)&data->gd_addr; +ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); +break; +case AF_INET6: +sin6 = (struct sockaddr_in6 *)&data->gd_addr; +ipv6_addr_copy(&in6, &sin6->sin6_addr); +break; +default: +goto out; +} + +if (!(clp = auth_unix_lookup(&in6))) err = -EPERM; else { err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index 22e1ef8..64ecb93 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -15,6 +15,7 @@ #include #include #include +#include #define SVC_CRED_NGROUPS32 struct svc_cred { @@ -120,10 +121,10 @@ extern void svc_auth_unregister(rpc_authflavor_t flavor); extern struct auth_domain *unix_domain_find(char *name); extern void auth_domain_put(struct auth_domain *item); -extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom); +extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom); extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new); extern struct auth_domain *auth_domain_fi
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
On Wed, Oct 31, 2007 at 10:06:18AM +0100, Aurélien Charbon wrote: > Thank you Brian > Sorry, I did not see what you sent. > > I have tested it with an IPv4 configuration. It's OK. > So Neil, Bruce, you can take this one for review. Did you miss Neil's question about the nfsctl stuff? (Do we really need that, or would the changes to the ip_map cache be sufficient?)--b. > > fs/nfsd/export.c |9 ++- > fs/nfsd/nfsctl.c | 42 -- > include/linux/sunrpc/svcauth.h |5 + > include/net/ipv6.h | 10 +++ > net/sunrpc/svcauth_unix.c | 118 > +++-- > 5 files changed, 134 insertions(+), 50 deletions(-) > > Signed-off-by: Brian Haley <[EMAIL PROTECTED]> > Signed-off-by: Aurelien Charbon <[EMAIL PROTECTED]> > > --- > > diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c > index 66d0aeb..c47ba77 100644 > --- a/fs/nfsd/export.c > +++ b/fs/nfsd/export.c > @@ -35,6 +35,7 @@ > #include > #include > #include > +#include > #define NFSDDBG_FACILITYNFSDDBG_EXPORT > @@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp) > { > struct auth_domain*dom; > inti, err; > +struct in6_addrin6; > /* First, consistency check. */ > err = -EINVAL; > @@ -1574,9 +1576,10 @@ exp_addclient(struct nfsctl_client *ncp) > goto out_unlock; > /* Insert client into hashtable. */ > -for (i = 0; i < ncp->cl_naddr; i++) > -auth_unix_add_addr(ncp->cl_addrlist[i], dom); > - > +for (i = 0; i < ncp->cl_naddr; i++) { > +ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &in6); > +auth_unix_add_addr(&in6, dom); > +} > auth_unix_forget_old(dom); > auth_domain_put(dom); > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c > index 77dc989..5cb5f0d 100644 > --- a/fs/nfsd/nfsctl.c > +++ b/fs/nfsd/nfsctl.c > @@ -37,6 +37,7 @@ > #include > #include > +#include > /* > *We have a single directory with 9 nodes in it. > @@ -219,24 +220,37 @@ static ssize_t write_getfs(struct file *file, char > *buf, size_t size) > { > struct nfsctl_fsparm *data; > struct sockaddr_in *sin; > +struct sockaddr_in6 *sin6; > struct auth_domain *clp; > int err = 0; > struct knfsd_fh *res; > +struct in6_addr in6; > if (size < sizeof(*data)) > return -EINVAL; > data = (struct nfsctl_fsparm*)buf; > err = -EPROTONOSUPPORT; > -if (data->gd_addr.sa_family != AF_INET) > +switch (data->gd_addr.sa_family) { > +case AF_INET: > +sin = (struct sockaddr_in *)&data->gd_addr; > +ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); > +break; > +case AF_INET6: > +sin6 = (struct sockaddr_in6 *)&data->gd_addr; > +ipv6_addr_copy(&in6, &sin6->sin6_addr); > +break; > +default: > goto out; > -sin = (struct sockaddr_in *)&data->gd_addr; > +} > + > if (data->gd_maxlen > NFS3_FHSIZE) > data->gd_maxlen = NFS3_FHSIZE; > res = (struct knfsd_fh*)buf; > exp_readlock(); > -if (!(clp = auth_unix_lookup(sin->sin_addr))) > + > +if (!(clp = auth_unix_lookup(&in6))) > err = -EPERM; > else { > err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); > @@ -253,25 +267,41 @@ static ssize_t write_getfd(struct file *file, char > *buf, size_t size) > { > struct nfsctl_fdparm *data; > struct sockaddr_in *sin; > +struct sockaddr_in6 *sin6; > struct auth_domain *clp; > int err = 0; > struct knfsd_fh fh; > char *res; > +struct in6_addr in6; > if (size < sizeof(*data)) > return -EINVAL; > data = (struct nfsctl_fdparm*)buf; > err = -EPROTONOSUPPORT; > -if (data->gd_addr.sa_family != AF_INET) > +if (data->gd_addr.sa_family != AF_INET && > +data->gd_addr.sa_family != AF_INET6) > goto out; > err = -EINVAL; > if (data->gd_version < 2 || data->gd_version > NFSSVC_MAXVERS) > goto out; > res = buf; > -sin = (struct sockaddr_in *)&data->gd_addr; > exp_readlock(); > -if (!(clp = auth_unix_lookup(sin->sin_addr))) > + > +switch (data->gd_addr.sa_family) { > +case AF_INET: > +sin = (struct sockaddr_in *)&data->gd_addr; > +ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); > +break; > +case AF_INET6: > +sin6 = (struct sockaddr_in6 *)&data->gd_addr; > +ipv6_addr_copy(&in6, &sin6->sin6_addr); > +break; > +default: > +goto out; > +} > + > +if (!(clp = auth_unix_lookup(&in6))) > err = -EPERM; > else { > err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); > diff --git a/include/linux/sunrpc/svcauth.h > b/include/linux/sunrpc/svcauth.h > index 22e1ef8..64ecb93 100644 > --- a/include/linux/sunrpc/svcauth.h > +++ b/include/linux/sunrpc/svcauth.h > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > #define SVC_CRED_NGROUPS32 > struct svc
Re: [PATCH 2/2] NFS: handle IPv6 addresses in nfs ctl
Hi Neil, Thank you for the reply. Neil Brown wrote: I think this patch is unnecessary and hence not wanted. The getfs / getfs calls should be considered legacy calls. Adding functionality to them is not appropriate. I agree with that. But I don't think we really add functionality here. Modifications are just necessary to match the auth_unix_lookup new prototype. I don't see how we can avoid that. Aurélien -- Aurelien Charbon Linux NFSv4 team Bull SAS Echirolles - France http://nfsv4.bullopensource.org/ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html