NFSD: Ignore client's source port on RDMA transports
authorChuck Lever <chuck.lever@oracle.com>
Mon, 19 May 2014 17:40:22 +0000 (13:40 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 22 May 2014 19:55:48 +0000 (15:55 -0400)
An NFS/RDMA client's source port is meaningless for RDMA transports.
The transport layer typically sets the source port value on the
connection to a random ephemeral port.

Currently, NFS server administrators must specify the "insecure"
export option to enable clients to access exports via RDMA.

But this means NFS clients can access such an export via IP using an
ephemeral port, which may not be desirable.

This patch eliminates the need to specify the "insecure" export
option to allow NFS/RDMA clients access to an export.

BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=250
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
include/linux/sunrpc/svc_xprt.h
net/sunrpc/svc_xprt.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_transport.c

index b05963f09ebf7b499902973a2707fad9aaa471e0..0cec1b94c67056abb21bdb277e9c0580b3d35f64 100644 (file)
@@ -24,6 +24,7 @@ struct svc_xprt_ops {
        void            (*xpo_release_rqst)(struct svc_rqst *);
        void            (*xpo_detach)(struct svc_xprt *);
        void            (*xpo_free)(struct svc_xprt *);
+       int             (*xpo_secure_port)(struct svc_rqst *);
 };
 
 struct svc_xprt_class {
index 06c6ff0cb9114200d88cb85e0c98af35670932f8..614956f1777e42a95b2f0d605fa4e6eeb2d8fdd2 100644 (file)
@@ -793,7 +793,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 
        clear_bit(XPT_OLD, &xprt->xpt_flags);
 
-       rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
+       rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
        rqstp->rq_chandle.defer = svc_defer;
 
        if (serv->sv_stats)
index 43bcb4699d69b377825531a21937df021bb958eb..0cb34f5d58dc61f7dbab6e6883c6b545b5b64eec 100644 (file)
@@ -400,6 +400,12 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
        release_sock(sock->sk);
 #endif
 }
+
+static int svc_sock_secure_port(struct svc_rqst *rqstp)
+{
+       return svc_port_is_privileged(svc_addr(rqstp));
+}
+
 /*
  * INET callback when data has been received on the socket.
  */
@@ -678,6 +684,7 @@ static struct svc_xprt_ops svc_udp_ops = {
        .xpo_prep_reply_hdr = svc_udp_prep_reply_hdr,
        .xpo_has_wspace = svc_udp_has_wspace,
        .xpo_accept = svc_udp_accept,
+       .xpo_secure_port = svc_sock_secure_port,
 };
 
 static struct svc_xprt_class svc_udp_class = {
@@ -1234,6 +1241,7 @@ static struct svc_xprt_ops svc_tcp_bc_ops = {
        .xpo_detach = svc_bc_tcp_sock_detach,
        .xpo_free = svc_bc_sock_free,
        .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
+       .xpo_secure_port = svc_sock_secure_port,
 };
 
 static struct svc_xprt_class svc_tcp_bc_class = {
@@ -1272,6 +1280,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
        .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
        .xpo_has_wspace = svc_tcp_has_wspace,
        .xpo_accept = svc_tcp_accept,
+       .xpo_secure_port = svc_sock_secure_port,
 };
 
 static struct svc_xprt_class svc_tcp_class = {
index 25688fa2207f96a495a11e2ff8577032d24ff294..02db8d9cc994163b876f84b4cc5cdf0e39b5ebc0 100644 (file)
@@ -65,6 +65,7 @@ static void dto_tasklet_func(unsigned long data);
 static void svc_rdma_detach(struct svc_xprt *xprt);
 static void svc_rdma_free(struct svc_xprt *xprt);
 static int svc_rdma_has_wspace(struct svc_xprt *xprt);
+static int svc_rdma_secure_port(struct svc_rqst *);
 static void rq_cq_reap(struct svcxprt_rdma *xprt);
 static void sq_cq_reap(struct svcxprt_rdma *xprt);
 
@@ -82,6 +83,7 @@ static struct svc_xprt_ops svc_rdma_ops = {
        .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
        .xpo_has_wspace = svc_rdma_has_wspace,
        .xpo_accept = svc_rdma_accept,
+       .xpo_secure_port = svc_rdma_secure_port,
 };
 
 struct svc_xprt_class svc_rdma_class = {
@@ -1207,6 +1209,11 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
        return 1;
 }
 
+static int svc_rdma_secure_port(struct svc_rqst *rqstp)
+{
+       return 1;
+}
+
 /*
  * Attempt to register the kvec representing the RPC memory with the
  * device.