Skip to content

Commit 5283b03

Browse files
jtlaytonJ. Bruce Fields
authored andcommitted
nfs/nfsd/sunrpc: enforce transport requirements for NFSv4
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>
1 parent 362142b commit 5283b03

File tree

4 files changed

+27
-6
lines changed

4 files changed

+27
-6
lines changed

fs/nfs/callback_xdr.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ struct svc_version nfs4_callback_version1 = {
10841084
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
10851085
.vs_dispatch = NULL,
10861086
.vs_hidden = true,
1087+
.vs_need_cong_ctrl = true,
10871088
};
10881089

10891090
struct svc_version nfs4_callback_version4 = {
@@ -1093,4 +1094,5 @@ struct svc_version nfs4_callback_version4 = {
10931094
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
10941095
.vs_dispatch = NULL,
10951096
.vs_hidden = true,
1097+
.vs_need_cong_ctrl = true,
10961098
};

fs/nfsd/nfs4proc.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,12 +2537,13 @@ static struct svc_procedure nfsd_procedures4[2] = {
25372537
};
25382538

25392539
struct svc_version nfsd_version4 = {
2540-
.vs_vers = 4,
2541-
.vs_nproc = 2,
2542-
.vs_proc = nfsd_procedures4,
2543-
.vs_dispatch = nfsd_dispatch,
2544-
.vs_xdrsize = NFS4_SVC_XDRSIZE,
2545-
.vs_rpcb_optnl = true,
2540+
.vs_vers = 4,
2541+
.vs_nproc = 2,
2542+
.vs_proc = nfsd_procedures4,
2543+
.vs_dispatch = nfsd_dispatch,
2544+
.vs_xdrsize = NFS4_SVC_XDRSIZE,
2545+
.vs_rpcb_optnl = true,
2546+
.vs_need_cong_ctrl = true,
25462547
};
25472548

25482549
/*

include/linux/sunrpc/svc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ struct svc_version {
406406
/* Don't care if the rpcbind registration fails */
407407
bool vs_rpcb_optnl;
408408

409+
/* Need xprt with congestion control */
410+
bool vs_need_cong_ctrl;
411+
409412
/* Override dispatch function (e.g. when caching replies).
410413
* A return value of 0 means drop the request.
411414
* vs_dispatch == NULL means use default dispatcher.

net/sunrpc/svc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,21 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
11691169
!(versp = progp->pg_vers[vers]))
11701170
goto err_bad_vers;
11711171

1172+
/*
1173+
* Some protocol versions (namely NFSv4) require some form of
1174+
* congestion control. (See RFC 7530 section 3.1 paragraph 2)
1175+
* In other words, UDP is not allowed. We mark those when setting
1176+
* up the svc_xprt, and verify that here.
1177+
*
1178+
* The spec is not very clear about what error should be returned
1179+
* when someone tries to access a server that is listening on UDP
1180+
* for lower versions. RPC_PROG_MISMATCH seems to be the closest
1181+
* fit.
1182+
*/
1183+
if (versp->vs_need_cong_ctrl &&
1184+
!test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags))
1185+
goto err_bad_vers;
1186+
11721187
procp = versp->vs_proc + proc;
11731188
if (proc >= versp->vs_nproc || !procp->pc_func)
11741189
goto err_bad_proc;

0 commit comments

Comments
 (0)