From owner-svn-src-projects@freebsd.org Mon Feb 17 19:51:05 2020 Return-Path: Delivered-To: svn-src-projects@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 6EC31244F73 for ; Mon, 17 Feb 2020 19:51:05 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48Lvk12GRhz3xwl; Mon, 17 Feb 2020 19:51:05 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 474C2C377; Mon, 17 Feb 2020 19:51:05 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 01HJp50C053958; Mon, 17 Feb 2020 19:51:05 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 01HJp4QN053954; Mon, 17 Feb 2020 19:51:04 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <202002171951.01HJp4QN053954@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Mon, 17 Feb 2020 19:51:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r358038 - projects/nfs-over-tls/sys/rpc X-SVN-Group: projects X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: projects/nfs-over-tls/sys/rpc X-SVN-Commit-Revision: 358038 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Feb 2020 19:51:05 -0000 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 #include #include +#include #include #include #include @@ -82,6 +85,10 @@ __FBSDID("$FreeBSD$"); #include #include +#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 #include +#include +#include +#include +#include + 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); } /*