aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfs
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2017-07-06 00:53:12 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2017-07-06 00:53:12 +0000
commit25d694a6fa5656da912e1d8d2f22571f4a06b6b2 (patch)
tree24b6f462b57d3801a6cfee4ea920e33ff42c764d /sys/fs/nfs
parent05370e9a994f06d77b88ee939b2fb1c492b4cf2f (diff)
downloadsrc-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.c2
-rw-r--r--sys/fs/nfs/nfs_commonport.c30
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c29
-rw-r--r--sys/fs/nfs/nfs_var.h2
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 *,