diff options
author | Aurélien Charbon <aurelien.charbon@ext.bull.net> | 2008-01-18 09:50:56 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-04-23 16:13:36 -0400 |
commit | f15364bd4cf8799a7677b6daeed7b67d9139d974 (patch) | |
tree | bef48016533d184ea171d4b64336a5ad65ebc18e /fs/nfsd | |
parent | d751a7cd0695554498f25d3026ca6710dbb3698f (diff) |
IPv6 support for NFS server export caches
This adds IPv6 support to the interfaces that are used to express nfsd
exports. All addressed are stored internally as IPv6; backwards
compatibility is maintained using mapped addresses.
Thanks to Bruce Fields, Brian Haley, Neil Brown and Hideaki Joshifuji
for comments
Signed-off-by: Aurelien Charbon <aurelien.charbon@bull.net>
Cc: Neil Brown <neilb@suse.de>
Cc: Brian Haley <brian.haley@hp.com>
Cc: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/export.c | 9 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 15 |
2 files changed, 19 insertions, 5 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 8a6f7c924c75..33bfcf09db46 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/lockd/bind.h> | 35 | #include <linux/lockd/bind.h> |
36 | #include <linux/sunrpc/msg_prot.h> | 36 | #include <linux/sunrpc/msg_prot.h> |
37 | #include <linux/sunrpc/gss_api.h> | 37 | #include <linux/sunrpc/gss_api.h> |
38 | #include <net/ipv6.h> | ||
38 | 39 | ||
39 | #define NFSDDBG_FACILITY NFSDDBG_EXPORT | 40 | #define NFSDDBG_FACILITY NFSDDBG_EXPORT |
40 | 41 | ||
@@ -1548,6 +1549,7 @@ exp_addclient(struct nfsctl_client *ncp) | |||
1548 | { | 1549 | { |
1549 | struct auth_domain *dom; | 1550 | struct auth_domain *dom; |
1550 | int i, err; | 1551 | int i, err; |
1552 | struct in6_addr addr6; | ||
1551 | 1553 | ||
1552 | /* First, consistency check. */ | 1554 | /* First, consistency check. */ |
1553 | err = -EINVAL; | 1555 | err = -EINVAL; |
@@ -1566,9 +1568,10 @@ exp_addclient(struct nfsctl_client *ncp) | |||
1566 | goto out_unlock; | 1568 | goto out_unlock; |
1567 | 1569 | ||
1568 | /* Insert client into hashtable. */ | 1570 | /* Insert client into hashtable. */ |
1569 | for (i = 0; i < ncp->cl_naddr; i++) | 1571 | for (i = 0; i < ncp->cl_naddr; i++) { |
1570 | auth_unix_add_addr(ncp->cl_addrlist[i], dom); | 1572 | ipv6_addr_set_v4mapped(ncp->cl_addrlist[i].s_addr, &addr6); |
1571 | 1573 | auth_unix_add_addr(&addr6, dom); | |
1574 | } | ||
1572 | auth_unix_forget_old(dom); | 1575 | auth_unix_forget_old(dom); |
1573 | auth_domain_put(dom); | 1576 | auth_domain_put(dom); |
1574 | 1577 | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 8516137cdbb0..9f038a4a148e 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/nfsd/syscall.h> | 37 | #include <linux/nfsd/syscall.h> |
38 | 38 | ||
39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
40 | #include <net/ipv6.h> | ||
40 | 41 | ||
41 | /* | 42 | /* |
42 | * We have a single directory with 9 nodes in it. | 43 | * We have a single directory with 9 nodes in it. |
@@ -222,6 +223,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size) | |||
222 | struct auth_domain *clp; | 223 | struct auth_domain *clp; |
223 | int err = 0; | 224 | int err = 0; |
224 | struct knfsd_fh *res; | 225 | struct knfsd_fh *res; |
226 | struct in6_addr in6; | ||
225 | 227 | ||
226 | if (size < sizeof(*data)) | 228 | if (size < sizeof(*data)) |
227 | return -EINVAL; | 229 | return -EINVAL; |
@@ -236,7 +238,11 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size) | |||
236 | res = (struct knfsd_fh*)buf; | 238 | res = (struct knfsd_fh*)buf; |
237 | 239 | ||
238 | exp_readlock(); | 240 | exp_readlock(); |
239 | if (!(clp = auth_unix_lookup(sin->sin_addr))) | 241 | |
242 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); | ||
243 | |||
244 | clp = auth_unix_lookup(&in6); | ||
245 | if (!clp) | ||
240 | err = -EPERM; | 246 | err = -EPERM; |
241 | else { | 247 | else { |
242 | err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); | 248 | err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); |
@@ -257,6 +263,7 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size) | |||
257 | int err = 0; | 263 | int err = 0; |
258 | struct knfsd_fh fh; | 264 | struct knfsd_fh fh; |
259 | char *res; | 265 | char *res; |
266 | struct in6_addr in6; | ||
260 | 267 | ||
261 | if (size < sizeof(*data)) | 268 | if (size < sizeof(*data)) |
262 | return -EINVAL; | 269 | return -EINVAL; |
@@ -271,7 +278,11 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size) | |||
271 | res = buf; | 278 | res = buf; |
272 | sin = (struct sockaddr_in *)&data->gd_addr; | 279 | sin = (struct sockaddr_in *)&data->gd_addr; |
273 | exp_readlock(); | 280 | exp_readlock(); |
274 | if (!(clp = auth_unix_lookup(sin->sin_addr))) | 281 | |
282 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &in6); | ||
283 | |||
284 | clp = auth_unix_lookup(&in6); | ||
285 | if (!clp) | ||
275 | err = -EPERM; | 286 | err = -EPERM; |
276 | else { | 287 | else { |
277 | err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); | 288 | err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); |