diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -550,6 +550,12 @@ NULL); if (so->so_type == SOCK_STREAM) svc_loss_reg(xprt, nfssvc_loss); + if (so->so_type == SOCK_STREAM) { + int optval; + + (void)so_setsockopt(so, IPPROTO_TCP, TCP_USE_DDP, + &optval, sizeof(optval)); + } SVC_RELEASE(xprt); } else error = EPERM; diff --git a/sys/rpc/clnt.h b/sys/rpc/clnt.h --- a/sys/rpc/clnt.h +++ b/sys/rpc/clnt.h @@ -362,6 +362,7 @@ void *arg; }; #define CLSET_RECONUPCALL 33 /* Reconnect upcall */ +#define CLSET_DDP 34 /* set TCP_USE_DDP for socket */ #endif diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -42,6 +42,8 @@ #include #include +#include + #include #include #include @@ -106,6 +108,7 @@ rc->rc_closed = FALSE; rc->rc_ucred = crdup(curthread->td_ucred); rc->rc_client = NULL; + rc->rc_ddp = false; rc->rc_tls = false; rc->rc_tlscertname = NULL; rc->rc_reconcall = NULL; @@ -212,6 +215,12 @@ goto out; } } + if (rc->rc_ddp && newclient != NULL) { + int optval = 1; + + (void)so_setsockopt(so, IPPROTO_TCP, TCP_USE_DDP, + &optval, sizeof(optval)); + } if (newclient != NULL && rc->rc_reconcall != NULL) (*rc->rc_reconcall)(newclient, rc->rc_reconarg, rc->rc_ucred); @@ -522,6 +531,10 @@ rc->rc_reconarg = upcp->arg; break; + case CLSET_DDP: + rc->rc_ddp = true; + break; + default: return (FALSE); } diff --git a/sys/rpc/krpc.h b/sys/rpc/krpc.h --- a/sys/rpc/krpc.h +++ b/sys/rpc/krpc.h @@ -77,6 +77,7 @@ CLIENT* rc_client; /* underlying RPC client */ struct rpc_err rc_err; void *rc_backchannel; + bool rc_ddp; bool rc_tls; /* Enable TLS on connection */ char *rc_tlscertname; void (*rc_reconcall)(CLIENT *, void *,