Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jul 2020 01:57:20 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r363298 - in projects/nfs-over-tls/sys/fs: nfs nfsclient nfsserver
Message-ID:  <202007180157.06I1vKHA068919@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sat Jul 18 01:57:20 2020
New Revision: 363298
URL: https://svnweb.freebsd.org/changeset/base/363298

Log:
  Add support for TLS for NFSv4.0 callback connections, plus disable ext_pgs
  mbufs for write requests.
  
  The first change simply modifies the code so that the server sets a flag
  to tell the server to do server->client connects using TLS, if the client
  is using TLS connections. This only affects NFSv4.0, since that is the
  only version that does server->client TCP connections.
  
  The second change is an interesting bugfix.
  When the ext_pgs mbuf list is passed into sosend() and TLS is enabled, the
  data in encrypted in the pages (at least for the software case).
  As such, keeping a copy (m_copym() that refcounts the pages) to do a resend
  does not work (the resent data may already be encrypted in the pages).
  Disabling generating the data to be written in ext_pgs mbufs fixes the
  problem, since the code generates a list of mbuf clusters and these are
  "real copied" to the ext_pgs unmapped pages.
  
  It may be possible to generate ext_pgs mbufs for the hardware offload
  cases, but I do not know this yet?

Modified:
  projects/nfs-over-tls/sys/fs/nfs/nfs.h
  projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c
  projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c
  projects/nfs-over-tls/sys/fs/nfs/nfs_var.h
  projects/nfs-over-tls/sys/fs/nfs/nfsport.h
  projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c
  projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c
  projects/nfs-over-tls/sys/fs/nfsclient/nfs_clvfsops.c
  projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c
  projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: projects/nfs-over-tls/sys/fs/nfs/nfs.h
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs.h	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs.h	Sat Jul 18 01:57:20 2020	(r363298)
@@ -336,6 +336,7 @@ struct nfsreferral {
 #define	LCL_DONEBINDCONN	0x00040000
 #define	LCL_RECLAIMONEFS	0x00080000
 #define	LCL_NFSV42		0x00100000
+#define	LCL_TLSCB		0x00200000
 
 #define	LCL_GSS		LCL_KERBV	/* Or of all mechs */
 

Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -167,7 +167,7 @@ static int nfsv2_procid[NFS_V3NPROCS] = {
  */
 int
 newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
-    struct ucred *cred, NFSPROC_T *p, int callback_retry_mult)
+    struct ucred *cred, NFSPROC_T *p, int callback_retry_mult, bool dotls)
 {
 	int rcvreserve, sndreserve;
 	int pktscale, pktscalesav;
@@ -376,6 +376,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq
 		} else {
 			retries = NFSV4_CALLBACKRETRY * callback_retry_mult;
 		}
+		if (dotls)
+			CLNT_CONTROL(client, CLSET_TLS, &one);
 	}
 	CLNT_CONTROL(client, CLSET_RETRIES, &retries);
 
@@ -588,7 +590,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmo
 	 * and let clnt_reconnect_create handle reconnects.
 	 */
 	if (nrp->nr_client == NULL)
-		newnfs_connect(nmp, nrp, cred, td, 0);
+		newnfs_connect(nmp, nrp, cred, td, 0, false);
 
 	/*
 	 * For a client side mount, nmp is != NULL and clp == NULL. For

Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -3615,7 +3615,7 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPRO
  	}
 	rp->nr_vers = RPCNFSUSERD_VERS;
 	if (error == 0)
-		error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0);
+		error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0, false);
 	if (error == 0) {
 		NFSLOCKNAMEID();
 		nfsrv_nfsuserd = RUNNING;

Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_var.h	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_var.h	Sat Jul 18 01:57:20 2020	(r363298)
@@ -766,7 +766,7 @@ int newnfs_request(struct nfsrv_descript *, struct nfs
     struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *,
     struct nfsclsession *);
 int newnfs_connect(struct nfsmount *, struct nfssockreq *,
-    struct ucred *, NFSPROC_T *, int);
+    struct ucred *, NFSPROC_T *, int, bool);
 void newnfs_disconnect(struct nfssockreq *);
 int newnfs_sigintr(struct nfsmount *, NFSPROC_T *);
 

Modified: projects/nfs-over-tls/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfsport.h	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfs/nfsport.h	Sat Jul 18 01:57:20 2020	(r363298)
@@ -111,11 +111,11 @@
 #include <vm/uma.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pageout.h>
 #include <vm/vm_param.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
 #include <nfs/nfssvc.h>
 #include "opt_nfs.h"
 #include "opt_ufs.h"

Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -74,6 +74,8 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *ui
 	mp = mp2 = nd->nd_mb;
 	mcp = nd->nd_bpos;
 	while (siz > 0) {
+		KASSERT((nd->nd_flag & ND_EXTPG) != 0 || mcp ==
+		    mtod(mp, char *) + mp->m_len, ("nfsm_uiombuf: mcp wrong"));
 		left = uiop->uio_iov->iov_len;
 		uiocp = uiop->uio_iov->iov_base;
 		if (left > siz)
@@ -156,10 +158,6 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *ui
  * copies a uio scatter/gather list to an mbuf chain.
  * This version returns the mbuf list and does not use "nd".
  * NOTE: can ony handle iovcnt == 1
- * This function is used to create an mbuf list for doing writing to
- * mirrored flexfile DSs.
- * It cannot be modified to optionally support ext_pgs mbufs until
- * nfsm_copym() is converted to work for ext_pgs mbufs.
  */
 struct mbuf *
 nfsm_uiombuflist(struct uio *uiop, int siz, struct mbuf **mbp, char **cpp)

Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -1793,12 +1793,8 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iom
 	struct nfsrv_descript *nd = &nfsd;
 	nfsattrbit_t attrbits;
 	off_t tmp_off;
-	bool use_ext;
 
 	KASSERT(uiop->uio_iovcnt == 1, ("nfs: writerpc iovcnt > 1"));
-	use_ext = false;
-	if (NFSHASTLS(nmp))
-		use_ext = true;
 	*attrflagp = 0;
 	tsiz = uiop->uio_resid;
 	tmp_off = uiop->uio_offset + tsiz;
@@ -1815,7 +1811,7 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iom
 		*attrflagp = 0;
 		len = (tsiz > wsize) ? wsize : tsiz;
 		nfscl_reqstart(nd, NFSPROC_WRITE, nmp, np->n_fhp->nfh_fh,
-		    np->n_fhp->nfh_len, NULL, NULL, 0, 0, use_ext);
+		    np->n_fhp->nfh_len, NULL, NULL, 0, 0, false);
 		if (nd->nd_flag & ND_NFSV4) {
 			nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID);
 			NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER+2*NFSX_UNSIGNED);
@@ -5624,7 +5620,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_in
 	 * unmount, but I did it anyhow.
 	 */
 	nrp->nr_cred = crhold(nmp->nm_sockreq.nr_cred);
-	error = newnfs_connect(nmp, nrp, NULL, p, 0);
+	error = newnfs_connect(nmp, nrp, NULL, p, 0, false);
 	NFSCL_DEBUG(3, "DS connect=%d\n", error);
 
 	dsp = NULL;

Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clvfsops.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clvfsops.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -714,7 +714,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp
 		    nmp->nm_soproto = argp->proto;
 		    if (nmp->nm_sotype == SOCK_DGRAM)
 			while (newnfs_connect(nmp, &nmp->nm_sockreq,
-			    cred, td, 0)) {
+			    cred, td, 0, false)) {
 				printf("newnfs_args: retrying connect\n");
 				(void) nfs_catnap(PSOCK, 0, "nfscon");
 			}
@@ -1543,7 +1543,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, stru
 		nmp->nm_sockreq.nr_vers = NFS_VER2;
 
 
-	if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
+	if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false)))
 		goto bad;
 	/* For NFSv4.1, get the clientid now. */
 	if (nmp->nm_minorvers > 0) {

Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <fs/nfs/nfsport.h>
 #include <sys/extattr.h>
 #include <sys/filio.h>
+#include <rpc/rpcsec_tls.h>
 
 /* Global vars */
 extern u_int32_t newnfs_false, newnfs_true;
@@ -3812,6 +3813,11 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused
 		clp->lc_uid = nd->nd_cred->cr_uid;
 		clp->lc_gid = nd->nd_cred->cr_gid;
 	}
+
+	/* If the client is using TLS, do so for the callback connection. */
+	if ((nd->nd_xprt->xp_tls & RPCTLS_FLAGS_HANDSHAKE) != 0)
+		clp->lc_flags |= LCL_TLSCB;
+
 	NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
 	clp->lc_program = fxdr_unsigned(u_int32_t, *tl);
 	error = nfsrv_getclientipaddr(nd, clp);

Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdstate.c	Sat Jul 18 00:14:43 2020	(r363297)
+++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdstate.c	Sat Jul 18 01:57:20 2020	(r363298)
@@ -4423,6 +4423,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, n
 	u_int32_t callback;
 	struct nfsdsession *sep = NULL;
 	uint64_t tval;
+	bool dotls;
 
 	nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO);
 	cred = newnfs_getcred();
@@ -4547,6 +4548,9 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, n
 	/*
 	 * Call newnfs_connect(), as required, and then newnfs_request().
 	 */
+	dotls = false;
+	if ((clp->lc_flags & LCL_TLSCB) != 0)
+		dotls = true;
 	(void) newnfs_sndlock(&clp->lc_req.nr_lock);
 	if (clp->lc_req.nr_client == NULL) {
 		if ((clp->lc_flags & LCL_NFSV41) != 0) {
@@ -4554,10 +4558,10 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, n
 			nfsrv_freesession(sep, NULL);
 		} else if (nd->nd_procnum == NFSV4PROC_CBNULL)
 			error = newnfs_connect(NULL, &clp->lc_req, cred,
-			    NULL, 1);
+			    NULL, 1, dotls);
 		else
 			error = newnfs_connect(NULL, &clp->lc_req, cred,
-			    NULL, 3);
+			    NULL, 3, dotls);
 	}
 	newnfs_sndunlock(&clp->lc_req.nr_lock);
 	NFSD_DEBUG(4, "aft sndunlock=%d\n", error);



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