svn commit: r358038 - projects/nfs-over-tls/sys/rpc
Rick Macklem
rmacklem at FreeBSD.org
Mon Feb 17 19:51:05 UTC 2020
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);
}
/*
More information about the svn-src-projects
mailing list