diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2017-07-06 00:53:12 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2017-07-06 00:53:12 +0000 |
commit | 25d694a6fa5656da912e1d8d2f22571f4a06b6b2 (patch) | |
tree | 24b6f462b57d3801a6cfee4ea920e33ff42c764d /sys/fs/nfs | |
parent | 05370e9a994f06d77b88ee939b2fb1c492b4cf2f (diff) | |
download | src-25d694a6fa5656da912e1d8d2f22571f4a06b6b2.tar.gz src-25d694a6fa5656da912e1d8d2f22571f4a06b6b2.zip |
Add support for AF_LOCAL socket upcalls to the nfsuserd daemon.
This patch adds support for AF_LOCAL socket upcalls to an nfsuserd daemon
that supports them. A future patch to the nfsuserd daemon will use AF_LOCAL
sockets to avoid a problem when using upcalls to 127.0.0.1 if jails are
in use.
Suggested by: dfr
PR: 205193
Notes
Notes:
svn path=/head/; revision=320698
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r-- | sys/fs/nfs/nfs_commonkrpc.c | 2 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_commonport.c | 30 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_commonsubs.c | 29 | ||||
-rw-r--r-- | sys/fs/nfs/nfs_var.h | 2 |
4 files changed, 47 insertions, 16 deletions
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index b2c396254de2..5f4d68bc697a 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -199,6 +199,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, nconf = getnetconfigent("udp"); else nconf = getnetconfigent("tcp"); + else if (saddr->sa_family == AF_LOCAL) + nconf = getnetconfigent("local"); else if (nrp->nr_sotype == SOCK_DGRAM) nconf = getnetconfigent("udp6"); diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index 28c2d2d1d235..cebacaf6c531 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); */ #include <fs/nfs/nfsport.h> #include <sys/sysctl.h> +#include <rpc/rpc_com.h> #include <vm/vm.h> #include <vm/vm_object.h> #include <vm/vm_page.h> @@ -618,11 +619,30 @@ nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred) goto out; } else if (uap->flag & NFSSVC_NFSUSERDPORT) { u_short sockport; - - error = copyin(uap->argp, (caddr_t)&sockport, - sizeof (u_short)); - if (!error) - error = nfsrv_nfsuserdport(sockport, p); + struct sockaddr *sad; + struct sockaddr_un *sun; + + if ((uap->flag & NFSSVC_NEWSTRUCT) != 0) { + /* New nfsuserd using an AF_LOCAL socket. */ + sun = malloc(sizeof(struct sockaddr_un), M_SONAME, + M_WAITOK | M_ZERO); + error = copyinstr(uap->argp, sun->sun_path, + sizeof(sun->sun_path), NULL); + if (error != 0) { + free(sun, M_SONAME); + return (error); + } + sun->sun_family = AF_LOCAL; + sun->sun_len = SUN_LEN(sun); + sockport = 0; + sad = (struct sockaddr *)sun; + } else { + error = copyin(uap->argp, (caddr_t)&sockport, + sizeof (u_short)); + sad = NULL; + } + if (error == 0) + error = nfsrv_nfsuserdport(sad, sockport, p); } else if (uap->flag & NFSSVC_NFSUSERDDELPORT) { nfsrv_nfsuserddelport(); error = 0; diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 309553d0ef53..86819ac7f23b 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -3052,7 +3052,7 @@ nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len) * Set the port for the nfsuserd. */ APPLESTATIC int -nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) +nfsrv_nfsuserdport(struct sockaddr *sad, u_short port, NFSPROC_T *p) { struct nfssockreq *rp; struct sockaddr_in *ad; @@ -3062,6 +3062,7 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) if (nfsrv_nfsuserd) { NFSUNLOCKNAMEID(); error = EPERM; + NFSSOCKADDRFREE(sad); goto out; } nfsrv_nfsuserd = 1; @@ -3071,16 +3072,24 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p) */ rp = &nfsrv_nfsuserdsock; rp->nr_client = NULL; - rp->nr_sotype = SOCK_DGRAM; - rp->nr_soproto = IPPROTO_UDP; - rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST); rp->nr_cred = NULL; - NFSSOCKADDRALLOC(rp->nr_nam); - NFSSOCKADDRSIZE(rp->nr_nam, sizeof (struct sockaddr_in)); - ad = NFSSOCKADDR(rp->nr_nam, struct sockaddr_in *); - ad->sin_family = AF_INET; - ad->sin_addr.s_addr = htonl((u_int32_t)0x7f000001); /* 127.0.0.1 */ - ad->sin_port = port; + rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST); + if (sad != NULL) { + /* Use the AF_LOCAL socket address passed in. */ + rp->nr_sotype = SOCK_STREAM; + rp->nr_soproto = 0; + rp->nr_nam = sad; + } else { + /* Use the port# for a UDP socket (old nfsuserd). */ + rp->nr_sotype = SOCK_DGRAM; + rp->nr_soproto = IPPROTO_UDP; + NFSSOCKADDRALLOC(rp->nr_nam); + NFSSOCKADDRSIZE(rp->nr_nam, sizeof (struct sockaddr_in)); + ad = NFSSOCKADDR(rp->nr_nam, struct sockaddr_in *); + ad->sin_family = AF_INET; + ad->sin_addr.s_addr = htonl((u_int32_t)0x7f000001); + ad->sin_port = port; + } rp->nr_prog = RPCPROG_NFSUSERD; rp->nr_vers = RPCNFSUSERD_VERS; error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0); diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index ac023dcf451a..7c0008242bd8 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -128,7 +128,7 @@ int nfsrv_checksetattr(vnode_t, struct nfsrv_descript *, NFSPROC_T *); int nfsrv_checkgetattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, struct ucred *, NFSPROC_T *); -int nfsrv_nfsuserdport(u_short, NFSPROC_T *); +int nfsrv_nfsuserdport(struct sockaddr *, u_short, NFSPROC_T *); void nfsrv_nfsuserddelport(void); void nfsrv_throwawayallstate(NFSPROC_T *); int nfsrv_checksequence(struct nfsrv_descript *, uint32_t, uint32_t *, |