aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2024-03-20 22:29:51 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-04-12 19:25:27 +0000
commit260d7b58547e150e3751bb786e97b15ff049f2e8 (patch)
tree61d3b1f80f98c0c88690d36f89b9b364451dd128
parentbf5956c185a13d77ef4466e4dec846f5fbd9dd2e (diff)
NFS: Request use of TCP_USE_DDP for in-kernel TCP sockets
Since this is an optimization, ignore failures to enable the option. For the server side, defer enabling DDP until the first non-NULLPROC RPC is received. This allows TLS handling (which uses NULLPROC RPCs) to enable TLS offload first. Reviewed by: rmacklem Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D44002 (cherry picked from commit a16ff32f04b5b891a2d9b0427a2fd9c48e866da3)
-rw-r--r--sys/rpc/clnt_rc.c8
-rw-r--r--sys/rpc/svc.c20
-rw-r--r--sys/rpc/svc.h1
3 files changed, 29 insertions, 0 deletions
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c
index fbd471ea6f5e..73a9e2631b7b 100644
--- a/sys/rpc/clnt_rc.c
+++ b/sys/rpc/clnt_rc.c
@@ -43,6 +43,8 @@
#include <sys/time.h>
#include <sys/uio.h>
+#include <netinet/tcp.h>
+
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#include <rpc/krpc.h>
@@ -213,6 +215,12 @@ clnt_reconnect_connect(CLIENT *cl)
goto out;
}
}
+ if (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);
diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c
index 848e719a7cca..6d19a0b1ea7d 100644
--- a/sys/rpc/svc.c
+++ b/sys/rpc/svc.c
@@ -54,6 +54,7 @@ static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC";
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/protosw.h>
#include <sys/queue.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
@@ -61,6 +62,8 @@ static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC";
#include <sys/sx.h>
#include <sys/ucred.h>
+#include <netinet/tcp.h>
+
#include <rpc/rpc.h>
#include <rpc/rpcb_clnt.h>
#include <rpc/replay.h>
@@ -992,6 +995,23 @@ svc_getreq(SVCXPRT *xprt, struct svc_req **rqstp_ret)
}
/*
+ * Defer enabling DDP until the first non-NULLPROC RPC
+ * is received to allow STARTTLS authentication to
+ * enable TLS offload first.
+ */
+ if (xprt->xp_doneddp == 0 && r->rq_proc != NULLPROC &&
+ atomic_cmpset_int(&xprt->xp_doneddp, 0, 1)) {
+ if (xprt->xp_socket->so_proto->pr_protocol ==
+ IPPROTO_TCP) {
+ int optval = 1;
+
+ (void)so_setsockopt(xprt->xp_socket,
+ IPPROTO_TCP, TCP_USE_DDP, &optval,
+ sizeof(optval));
+ }
+ }
+
+ /*
* Everything checks out, return request to caller.
*/
*rqstp_ret = r;
diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h
index 9eaf972c097b..b240e75afdb0 100644
--- a/sys/rpc/svc.h
+++ b/sys/rpc/svc.h
@@ -188,6 +188,7 @@ typedef struct __rpc_svcxprt {
int xp_ngrps; /* Cred. from TLS cert. */
uid_t xp_uid;
gid_t *xp_gidp;
+ int xp_doneddp;
#else
int xp_fd;
u_short xp_port; /* associated port number */