Skip to content

Commit

Permalink
nfs/nfsd/sunrpc: enforce transport requirements for NFSv4
Browse files Browse the repository at this point in the history
NFSv4 requires a transport "that is specified to avoid network
congestion" (RFC 7530, section 3.1, paragraph 2).  In practical terms,
that means that you should not run NFSv4 over UDP. The server has never
enforced that requirement, however.

This patchset fixes this by adding a new flag to the svc_version that
states that it has these transport requirements. With that, we can check
that the transport has XPT_CONG_CTRL set before processing an RPC. If it
doesn't we reject it with RPC_PROG_MISMATCH.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
  • Loading branch information
jtlayton authored and J. Bruce Fields committed Feb 24, 2017
1 parent 362142b commit 5283b03
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
2 changes: 2 additions & 0 deletions fs/nfs/callback_xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ struct svc_version nfs4_callback_version1 = {
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
.vs_dispatch = NULL,
.vs_hidden = true,
.vs_need_cong_ctrl = true,
};

struct svc_version nfs4_callback_version4 = {
Expand All @@ -1093,4 +1094,5 @@ struct svc_version nfs4_callback_version4 = {
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
.vs_dispatch = NULL,
.vs_hidden = true,
.vs_need_cong_ctrl = true,
};
13 changes: 7 additions & 6 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2537,12 +2537,13 @@ static struct svc_procedure nfsd_procedures4[2] = {
};

struct svc_version nfsd_version4 = {
.vs_vers = 4,
.vs_nproc = 2,
.vs_proc = nfsd_procedures4,
.vs_dispatch = nfsd_dispatch,
.vs_xdrsize = NFS4_SVC_XDRSIZE,
.vs_rpcb_optnl = true,
.vs_vers = 4,
.vs_nproc = 2,
.vs_proc = nfsd_procedures4,
.vs_dispatch = nfsd_dispatch,
.vs_xdrsize = NFS4_SVC_XDRSIZE,
.vs_rpcb_optnl = true,
.vs_need_cong_ctrl = true,
};

/*
Expand Down
3 changes: 3 additions & 0 deletions include/linux/sunrpc/svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ struct svc_version {
/* Don't care if the rpcbind registration fails */
bool vs_rpcb_optnl;

/* Need xprt with congestion control */
bool vs_need_cong_ctrl;

/* Override dispatch function (e.g. when caching replies).
* A return value of 0 means drop the request.
* vs_dispatch == NULL means use default dispatcher.
Expand Down
15 changes: 15 additions & 0 deletions net/sunrpc/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,21 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
!(versp = progp->pg_vers[vers]))
goto err_bad_vers;

/*
* Some protocol versions (namely NFSv4) require some form of
* congestion control. (See RFC 7530 section 3.1 paragraph 2)
* In other words, UDP is not allowed. We mark those when setting
* up the svc_xprt, and verify that here.
*
* The spec is not very clear about what error should be returned
* when someone tries to access a server that is listening on UDP
* for lower versions. RPC_PROG_MISMATCH seems to be the closest
* fit.
*/
if (versp->vs_need_cong_ctrl &&
!test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags))
goto err_bad_vers;

procp = versp->vs_proc + proc;
if (proc >= versp->vs_nproc || !procp->pc_func)
goto err_bad_proc;
Expand Down

0 comments on commit 5283b03

Please sign in to comment.