svn commit: r363298 - in projects/nfs-over-tls/sys/fs: nfs nfsclient nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sat Jul 18 01:57:23 UTC 2020
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);
More information about the svn-src-projects
mailing list