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>