git: 260d7b58547e - stable/14 - NFS: Request use of TCP_USE_DDP for in-kernel TCP sockets

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 12 Apr 2024 21:31:30 UTC
The branch stable/14 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=260d7b58547e150e3751bb786e97b15ff049f2e8

commit 260d7b58547e150e3751bb786e97b15ff049f2e8
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-03-20 22:29:51 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-04-12 19:25:27 +0000

    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)
---
 sys/rpc/clnt_rc.c |  8 ++++++++
 sys/rpc/svc.c     | 20 ++++++++++++++++++++
 sys/rpc/svc.h     |  1 +
 3 files changed, 29 insertions(+)

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>
@@ -991,6 +994,23 @@ svc_getreq(SVCXPRT *xprt, struct svc_req **rqstp_ret)
 			goto call_done;
 		}
 
+		/*
+		 * 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.
 		 */
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 */