Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Feb 2020 19:51:04 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r358038 - projects/nfs-over-tls/sys/rpc
Message-ID:  <202002171951.01HJp4QN053954@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Mon Feb 17 19:51:04 2020
New Revision: 358038
URL: https://svnweb.freebsd.org/changeset/base/358038

Log:
  Update the krpc for nfs-over-tls.

Modified:
  projects/nfs-over-tls/sys/rpc/clnt_rc.c
  projects/nfs-over-tls/sys/rpc/clnt_stat.h
  projects/nfs-over-tls/sys/rpc/clnt_vc.c
  projects/nfs-over-tls/sys/rpc/krpc.h
  projects/nfs-over-tls/sys/rpc/rpc_generic.c

Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_rc.c	Mon Feb 17 19:40:26 2020	(r358037)
+++ projects/nfs-over-tls/sys/rpc/clnt_rc.c	Mon Feb 17 19:51:04 2020	(r358038)
@@ -199,11 +199,7 @@ printf("at rpctls_connect\n");
 			stat = rpctls_connect(newclient, so);
 printf("aft rpctls_connect=%d\n", stat);
 			if (stat != RPC_SUCCESS) {
-				if (stat != RPC_SYSTEMERROR)
-					stat = rpc_createerr.cf_stat =
-					    RPC_TLSCONNECT;
-				else
-					stat = rpc_createerr.cf_stat = stat;
+				stat = rpc_createerr.cf_stat = stat;
 				rpc_createerr.cf_error.re_errno = 0;
 				CLNT_CLOSE(newclient);
 				CLNT_RELEASE(newclient);
@@ -228,6 +224,8 @@ printf("aft rpctls_connect=%d\n", stat);
 	CLNT_CONTROL(newclient, CLSET_RETRY_TIMEOUT, &rc->rc_retry);
 	CLNT_CONTROL(newclient, CLSET_WAITCHAN, rc->rc_waitchan);
 	CLNT_CONTROL(newclient, CLSET_INTERRUPTIBLE, &rc->rc_intr);
+	if (rc->rc_tls != 0)
+		CLNT_CONTROL(newclient, CLSET_TLS, &one);
 	if (rc->rc_backchannel != NULL)
 		CLNT_CONTROL(newclient, CLSET_BACKCHANNEL, rc->rc_backchannel);
 	stat = RPC_SUCCESS;

Modified: projects/nfs-over-tls/sys/rpc/clnt_stat.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_stat.h	Mon Feb 17 19:40:26 2020	(r358037)
+++ projects/nfs-over-tls/sys/rpc/clnt_stat.h	Mon Feb 17 19:51:04 2020	(r358038)
@@ -73,11 +73,7 @@ enum clnt_stat {
 	RPC_STALERACHANDLE = 25,
 	RPC_CANTCONNECT = 26,		/* couldn't make connection (cots) */
 	RPC_XPRTFAILED = 27,		/* received discon from remote (cots) */
-	RPC_CANTCREATESTREAM = 28,	/* can't push rpc module (cots) */
-	/*
-	 * TLS errors
-	 */
-	RPC_TLSCONNECT = 29		/* can't do TLS handshake */
+	RPC_CANTCREATESTREAM = 28	/* can't push rpc module (cots) */
 };
 
 #ifdef __cplusplus

Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_vc.c	Mon Feb 17 19:40:26 2020	(r358037)
+++ projects/nfs-over-tls/sys/rpc/clnt_vc.c	Mon Feb 17 19:51:04 2020	(r358038)
@@ -57,9 +57,12 @@ __FBSDID("$FreeBSD$");
  * Now go hang yourself.
  */
 
+#include "opt_kern_tls.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/ktls.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
@@ -82,6 +85,10 @@ __FBSDID("$FreeBSD$");
 #include <rpc/rpc_com.h>
 #include <rpc/krpc.h>
 
+#ifdef KERN_TLS
+extern u_int ktls_maxlen;
+#endif
+
 struct cmessage {
         struct cmsghdr cmsg;
         struct cmsgcred cmcred;
@@ -303,7 +310,7 @@ clnt_vc_call(
 	uint32_t xid;
 	struct mbuf *mreq = NULL, *results;
 	struct ct_request *cr;
-	int error, trycnt;
+	int error, maxextsiz, trycnt;
 
 	cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK);
 
@@ -409,6 +416,17 @@ call_again:
 	TAILQ_INSERT_TAIL(&ct->ct_pending, cr, cr_link);
 	mtx_unlock(&ct->ct_lock);
 
+	if (ct->ct_tls) {
+		/*
+		 * Copy the mbuf chain to a chain of ext_pgs mbuf(s)
+		 * as required by KERN_TLS.
+		 */
+		maxextsiz = TLS_MAX_MSG_SIZE_V10_2;
+#ifdef KERN_TLS
+		maxextsiz = min(maxextsiz, ktls_maxlen);
+#endif
+		mreq = _rpc_copym_into_ext_pgs(mreq, maxextsiz);
+	}
 	/*
 	 * sosend consumes mreq.
 	 */
@@ -424,6 +442,7 @@ call_again:
 		TAILQ_REMOVE(&ct->ct_pending, cr, cr_link);
 		/* Sleep for 1 clock tick before trying the sosend() again. */
 		msleep(&fake_wchan, &ct->ct_lock, 0, "rpclpsnd", 1);
+printf("TRY AGAIN!!\n");
 		goto call_again;
 	}
 
@@ -729,8 +748,14 @@ clnt_vc_control(CLIENT *cl, u_int request, void *info)
 		xprt = (SVCXPRT *)info;
 		if (ct->ct_backchannelxprt == NULL) {
 			xprt->xp_p2 = ct;
+			if (ct->ct_tls)
+				xprt->xp_tls = TRUE;
 			ct->ct_backchannelxprt = xprt;
 		}
+		break;
+
+	case CLSET_TLS:
+		ct->ct_tls = TRUE;
 		break;
 
 	case CLSET_BLOCKRCV:

Modified: projects/nfs-over-tls/sys/rpc/krpc.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/krpc.h	Mon Feb 17 19:40:26 2020	(r358037)
+++ projects/nfs-over-tls/sys/rpc/krpc.h	Mon Feb 17 19:51:04 2020	(r358038)
@@ -42,6 +42,7 @@
 void clnt_bck_svccall(void *, struct mbuf *, uint32_t);
 enum clnt_stat clnt_bck_call(CLIENT *, struct rpc_callextra *, rpcproc_t,
     struct mbuf *, struct mbuf **, struct timeval, SVCXPRT *);
+struct mbuf *_rpc_copym_into_ext_pgs(struct mbuf *, int);
 
 /*
  * A pending RPC request which awaits a reply. Requests which have
@@ -102,6 +103,7 @@ struct ct_data {
 	struct ct_request_list ct_pending;
 	int		ct_upcallrefs;	/* Ref cnt of upcalls in prog. */
 	SVCXPRT		*ct_backchannelxprt; /* xprt for backchannel */
+	bool_t		ct_tls;		/* Enable RPC-over-TLS support. */
 	bool_t		ct_dontrcv;	/* TRUE to block receiving */
 };
 

Modified: projects/nfs-over-tls/sys/rpc/rpc_generic.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/rpc_generic.c	Mon Feb 17 19:40:26 2020	(r358037)
+++ projects/nfs-over-tls/sys/rpc/rpc_generic.c	Mon Feb 17 19:51:04 2020	(r358038)
@@ -64,7 +64,12 @@ __FBSDID("$FreeBSD$");
 #include <rpc/rpcsec_gss.h>
 
 #include <rpc/rpc_com.h>
+#include <rpc/krpc.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
 extern	u_long sb_max_adj;	/* not defined in socketvar.h */
 
 #if __FreeBSD_version < 700000
@@ -866,6 +871,100 @@ out:
 		free(sa, M_SONAME);
 
 	return (error);
+}
+
+/*
+ * Make sure an mbuf list is made up entirely of ext_pgs mbufs.
+ * This is needed for sosend() when KERN_TLS is being used.
+ * (There might also be a performance improvement for certain
+ *  network interfaces that handle ext_pgs mbufs efficiently.)
+ * It expects at least one non-ext_pgs mbuf followed by zero
+ * or more ext_pgs mbufs.  It does not handle the case where
+ * non-ext_pgs mbuf(s) follow ext_pgs ones.
+ * It also performs sanity checks on the resultant list.
+ * The "mp" argument list is consumed.
+ * The "maxextsiz" argument is the upper bound on the data
+ * size for each mbuf (usually 16K for KERN_TLS).
+ */
+struct mbuf *
+_rpc_copym_into_ext_pgs(struct mbuf *mp, int maxextsiz)
+{
+	struct mbuf *m, *m2, *m3, *mhead;
+	int tlen;
+
+	KASSERT((mp->m_flags & (M_EXT | M_NOMAP)) !=
+	    (M_EXT | M_NOMAP), ("_rpc_copym_into_ext_pgs:"
+	    " first mbuf is an ext_pgs"));
+	/*
+	 * Find the last non-ext_pgs mbuf and the total
+	 * length of the non-ext_pgs mbuf(s).
+	 * The first mbuf must always be a non-ext_pgs
+	 * mbuf.
+	 */
+	tlen = mp->m_len;
+	m2 = mp;
+	for (m = mp->m_next; m != NULL; m = m->m_next) {
+		if ((m->m_flags & (M_EXT | M_NOMAP)) ==
+		    (M_EXT | M_NOMAP))
+			break;
+		tlen += m->m_len;
+		m2 = m;
+	}
+
+	/*
+	 * Copy the non-ext_pgs mbuf(s) into an ext_pgs
+	 * mbuf list.
+	 */
+	m2->m_next = NULL;
+	mhead = mb_copym_ext_pgs(mp, tlen, maxextsiz, M_WAITOK,
+	    true, mb_free_mext_pgs, &m2);
+
+	/*
+	 * Link the ext_pgs list onto the newly copied
+	 * list and free up the non-ext_pgs mbuf(s).
+	 */
+	mhead->m_pkthdr.len = mp->m_pkthdr.len;
+	m2->m_next = m;
+	m_freem(mp);
+
+	/*
+	 * Sanity check the resultant mbuf list.  Check for and
+	 * remove any 0 length mbufs in the list, since the
+	 * KERN_TLS code does not expect any 0 length mbuf(s)
+	 * in the list.
+	 */
+	m3 = NULL;
+	m2 = mhead;
+	tlen = 0;
+	while (m2 != NULL) {
+		KASSERT(m2->m_len >= 0, ("_rpc_copym_into_ext_pgs:"
+		    " negative m_len"));
+		KASSERT((m2->m_flags & (M_EXT | M_NOMAP)) ==
+		    (M_EXT | M_NOMAP), ("_rpc_copym_into_ext_pgs:"
+			    " non-nomap mbuf in list"));
+		if (m2->m_len == 0) {
+			if (m3 != NULL)
+				m3->m_next = m2->m_next;
+			else
+				m = m2->m_next;
+			m2->m_next = NULL;
+			m_free(m2);
+			if (m3 != NULL)
+				m2 = m3->m_next;
+			else
+				m2 = m;
+		} else {
+			MBUF_EXT_PGS_ASSERT_SANITY(
+			    m2->m_ext.ext_pgs);
+			m3 = m2;
+			tlen += m2->m_len;
+			m2 = m2->m_next;
+		}
+	}
+	KASSERT(tlen == mhead->m_pkthdr.len,
+	    ("_rpc_copym_into_ext_pgs: tlen=%d pkthdrlen=%d",
+	    tlen, mhead->m_pkthdr.len));
+	return (mhead);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002171951.01HJp4QN053954>