From nobody Sat Apr 1 21:25:03 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ppqtm3Cg8z43NGv; Sat, 1 Apr 2023 21:25:04 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ppqtl73kkz4TL4; Sat, 1 Apr 2023 21:25:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680384304; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kLTSRYtAcURWms8oJ6xPpMsgQJeZ6GLuliS1EdtkHlw=; b=C65ttzyx/lhX/SzhB/wUNLPKp+NMNTPy0QWa1vwfg6QFWP0lCc8VFAj2xiyXVBcl5qJis1 3Ro+bRsvahjEvCxZXvn0UpzPChFiElmpK9TAnXIDuhNyVFFS5V4RXxwDFPkHldcR0pjeUW ROsTU21dkjhSQrmNS75N0UYqb2FJySLmR9xP0RiYqA/iG4UggvhfHZkT7l7BJjebrOFn52 bbaleLkqcrH1BqgB12KHNEi/O4c1n/Mu3Pm46cxexKvG7l2jRD2l8/URnpFnsh7eS72FIU sSt5RNe4HEEBfruJ9bh99y3lPkSuXql8EydqNu+viv6+DRJ5oh5myjWX1AnlYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680384304; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kLTSRYtAcURWms8oJ6xPpMsgQJeZ6GLuliS1EdtkHlw=; b=hZxYqGvhjlvpjWwbOvh1HjmMkT57Ju5y09DIghuKmgJVZgfoiSuxYzJDvoML/Oc/iqihvn 67av384H4VbnPzgrdr0eCI/6gQL8ZM4pLVcPNGpSd3hFAl3jExneY3+38yXyMDblBQxMcm fLCFZ5olwAL4+IC5QJ9is9NPmHklXXAJSqNJ+mcTomcUoJNJko3GZh8jR9bvocXr4lVPnW IXK0wXrYN7fdepzfr7OpINo8FWHfsdyJVELM/jKMk9v8nMv+pSUorPMy2ZIHJhn+f91yvl +efHfFQgPHZcDEUzu2WIA2XALCG/Yo5u7Ww5k/R/PXkx4seX7gFi3v3Lis5ciw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1680384304; a=rsa-sha256; cv=none; b=SPaL2rwqGqWx5piI7j8AQligh4/OEGxC/BUDCJiV9tri3eQ+tG5MzMX0KyxMx7SjkUJIBu YhZlwYOFOXjpSuMX5Vy4cfDOs9HG9MwsBIdTmI+9kMz6xwp4BI2jfoSKLIH3iObjy6HY9m 6w0IeOKCAkxvIVPbjyEfig1fcsXhFdSISXoIPDjDVmK7Qhg7OOMQ8FrwsxkJMSqa3P+8C3 LzDSsdN3aDwgioKlqsV6iKs01KvRttxtlkuQyesjy6TkZyWFWjtjzZAr+Cc/+XtqUHgrTU xmjmYDKCuByWZ9qf5SMI9vmjA5RSQDXDsopeVmpghBNHN8Jx1CyLVUXH+swlIA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Ppqtl61jRzqk4; Sat, 1 Apr 2023 21:25:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 331LP3ID094169; Sat, 1 Apr 2023 21:25:03 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 331LP3OO094168; Sat, 1 Apr 2023 21:25:03 GMT (envelope-from git) Date: Sat, 1 Apr 2023 21:25:03 GMT Message-Id: <202304012125.331LP3OO094168@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Rick Macklem Subject: git: f4179ad46fa4 - main - nfscommon: Add support for an NFSv4 operation bitmap List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f4179ad46fa4ff717557e5485072c004e6054416 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f4179ad46fa4ff717557e5485072c004e6054416 commit f4179ad46fa4ff717557e5485072c004e6054416 Author: Rick Macklem AuthorDate: 2023-04-01 21:22:26 +0000 Commit: Rick Macklem CommitDate: 2023-04-01 21:22:26 +0000 nfscommon: Add support for an NFSv4 operation bitmap NFSv4.1/4.2 uses operation bitmaps for various operations, such as the SP4_MACH_CRED case for ExchangeID. This patch adds support for operation bitmaps so that support for SP4_MACH_CRED can be added to the NFSv4.1/4.2 server in a future commit. This commit should not change any NFSv4.1/4.2 semantics. MFC after: 3 months --- sys/fs/nfs/nfs.h | 31 ++++++++++++ sys/fs/nfs/nfs_commonsubs.c | 62 +++++++++++++++++++++++ sys/fs/nfs/nfs_var.h | 2 + sys/fs/nfs/nfsproto.h | 120 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index eac318512a35..9d0a2d8191b2 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -344,6 +344,7 @@ struct nfsreferral { #define LCL_RECLAIMONEFS 0x00080000 #define LCL_NFSV42 0x00100000 #define LCL_TLSCB 0x00200000 +#define LCL_MACHCRED 0x00400000 #define LCL_GSS LCL_KERBV /* Or of all mechs */ @@ -552,6 +553,34 @@ typedef struct { (b)->bits[2] = NFSATTRBIT_REFERRAL2; \ } while (0) +/* + * Here is the definition of the operation bits array and macros that + * manipulate it. + * THE MACROS MUST BE MANUALLY MODIFIED IF NFSOPBIT_MAXWORDS CHANGES!! + * It is (NFSV42_NOPS + 31) / 32. + */ +#define NFSOPBIT_MAXWORDS 3 + +typedef struct { + uint32_t bits[NFSOPBIT_MAXWORDS]; +} nfsopbit_t; + +#define NFSZERO_OPBIT(b) do { \ + (b)->bits[0] = 0; \ + (b)->bits[1] = 0; \ + (b)->bits[2] = 0; \ +} while (0) + +#define NFSSET_OPBIT(t, f) do { \ + (t)->bits[0] = (f)->bits[0]; \ + (t)->bits[1] = (f)->bits[1]; \ + (t)->bits[2] = (f)->bits[2]; \ +} while (0) + +#define NFSISSET_OPBIT(b, p) ((b)->bits[(p) / 32] & (1 << ((p) % 32))) +#define NFSSETBIT_OPBIT(b, p) ((b)->bits[(p) / 32] |= (1 << ((p) % 32))) +#define NFSCLRBIT_OPBIT(b, p) ((b)->bits[(p) / 32] &= ~(1 << ((p) % 32))) + /* * Store uid, gid creds that were used when the stateid was acquired. * The RPC layer allows NFS_MAXGRPS + 1 groups to go out on the wire, @@ -687,6 +716,7 @@ struct nfsrv_descript { int nd_bextpg; /* Current ext_pgs page */ int nd_bextpgsiz; /* Bytes left in page */ int nd_maxextsiz; /* Max ext_pgs mbuf size */ + nfsopbit_t nd_allowops; /* Allowed ops ND_MACHCRED */ }; #define nd_princlen nd_gssnamelen @@ -736,6 +766,7 @@ struct nfsrv_descript { #define ND_EXTLSCERT 0x10000000000 #define ND_EXTLSCERTUSER 0x20000000000 #define ND_ERELOOKUP 0x40000000000 +#define ND_MACHCRED 0x80000000000 /* * ND_GSS should be the "or" of all GSS type authentications. diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 48798087b177..81bd2beba749 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -1222,6 +1222,47 @@ nfsmout: return (error); } +/* + * Get operation bits from an mbuf list. + * Returns EBADRPC for a parsing error, 0 otherwise. + */ +int +nfsrv_getopbits(struct nfsrv_descript *nd, nfsopbit_t *opbitp, int *cntp) +{ + uint32_t *tl; + int cnt, i, outcnt; + int error = 0; + + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + cnt = fxdr_unsigned(int, *tl); + if (cnt < 0) { + error = NFSERR_BADXDR; + goto nfsmout; + } + if (cnt > NFSOPBIT_MAXWORDS) + outcnt = NFSOPBIT_MAXWORDS; + else + outcnt = cnt; + NFSZERO_OPBIT(opbitp); + if (outcnt > 0) { + NFSM_DISSECT(tl, uint32_t *, outcnt * NFSX_UNSIGNED); + for (i = 0; i < outcnt; i++) + opbitp->bits[i] = fxdr_unsigned(uint32_t, *tl++); + } + for (i = 0; i < (cnt - outcnt); i++) { + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (*tl != 0) { + error = NFSERR_BADXDR; + goto nfsmout; + } + } + if (cntp != NULL) + *cntp = NFSX_UNSIGNED + (cnt * NFSX_UNSIGNED); +nfsmout: + NFSEXITCODE2(error, nd); + return (error); +} + /* * Get the attributes for V4. * If the compare flag is true, test for any attribute changes, @@ -3142,6 +3183,27 @@ nfsrv_putattrbit(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp) return (bytesize); } +/* + * Put the operation bits onto an mbuf list. + * Return the number of bytes of output generated. + */ +int +nfsrv_putopbit(struct nfsrv_descript *nd, nfsopbit_t *opbitp) +{ + uint32_t *tl; + int cnt, i, bytesize; + + for (cnt = NFSOPBIT_MAXWORDS; cnt > 0; cnt--) + if (opbitp->bits[cnt - 1]) + break; + bytesize = (cnt + 1) * NFSX_UNSIGNED; + NFSM_BUILD(tl, uint32_t *, bytesize); + *tl++ = txdr_unsigned(cnt); + for (i = 0; i < cnt; i++) + *tl++ = txdr_unsigned(opbitp->bits[i]); + return (bytesize); +} + /* * Convert a uid to a string. * If the lookup fails, just output the digits. diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 55396bfb0902..ad1eb73b1090 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -337,6 +337,7 @@ int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, bool, int *, int *, NFSPROC_T *); int nfsrv_getattrbits(struct nfsrv_descript *, nfsattrbit_t *, int *, int *); +int nfsrv_getopbits(struct nfsrv_descript *, nfsopbit_t *, int *); int nfsv4_loadattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, struct nfsfh **, fhandle_t *, int, struct nfsv3_pathconf *, struct statfs *, struct nfsstatfs *, @@ -391,6 +392,7 @@ int nfsd_excred(struct nfsrv_descript *, struct nfsexstuff *, struct ucred *, bool); int nfsrv_mtofh(struct nfsrv_descript *, struct nfsrvfh *); int nfsrv_putattrbit(struct nfsrv_descript *, nfsattrbit_t *); +int nfsrv_putopbit(struct nfsrv_descript *, nfsopbit_t *); void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int, struct nfsvattr *); int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *, diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index ceecc63a7732..0d36ee84642a 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -1427,6 +1427,126 @@ struct nfsv3_sattr { #define NFSATTRBIT_REFERRAL1 NFSATTRBM_MOUNTEDONFILEID #define NFSATTRBIT_REFERRAL2 0 +/* Bits for the operations bitmaps. */ +#define NFSV4OPBM_ACCESS 0x00000008 +#define NFSV4OPBM_CLOSE 0x00000010 +#define NFSV4OPBM_COMMIT 0x00000020 +#define NFSV4OPBM_CREATE 0x00000040 +#define NFSV4OPBM_DELEGPURGE 0x00000080 +#define NFSV4OPBM_DELEGRETURN 0x00000100 +#define NFSV4OPBM_GETATTR 0x00000200 +#define NFSV4OPBM_GETFH 0x00000400 +#define NFSV4OPBM_LINK 0x00000800 +#define NFSV4OPBM_LOCK 0x00001000 +#define NFSV4OPBM_LOCKT 0x00002000 +#define NFSV4OPBM_LOCKU 0x00004000 +#define NFSV4OPBM_LOOKUP 0x00008000 +#define NFSV4OPBM_LOOKUPP 0x00010000 +#define NFSV4OPBM_NVERIFY 0x00020000 +#define NFSV4OPBM_OPEN 0x00040000 +#define NFSV4OPBM_OPENATTR 0x00080000 +#define NFSV4OPBM_OPENCONFIRM 0x00100000 +#define NFSV4OPBM_OPENDOWNGRADE 0x00200000 +#define NFSV4OPBM_PUTFH 0x00400000 +#define NFSV4OPBM_PUTPUBFH 0x00800000 +#define NFSV4OPBM_PUTROOTFH 0x01000000 +#define NFSV4OPBM_READ 0x02000000 +#define NFSV4OPBM_READDIR 0x04000000 +#define NFSV4OPBM_READLINK 0x08000000 +#define NFSV4OPBM_REMOVE 0x10000000 +#define NFSV4OPBM_RENAME 0x20000000 +#define NFSV4OPBM_RENEW 0x40000000 +#define NFSV4OPBM_RESTOREFH 0x80000000 +#define NFSV4OPBM_SAVEFH 0x00000001 +#define NFSV4OPBM_SECINFO 0x00000002 +#define NFSV4OPBM_SETATTR 0x00000004 +#define NFSV4OPBM_SETCLIENTID 0x00000008 +#define NFSV4OPBM_SETCLIENTIDCFRM 0x00000010 +#define NFSV4OPBM_VERIFY 0x00000020 +#define NFSV4OPBM_WRITE 0x00000040 +#define NFSV4OPBM_RELEASELCKOWN 0x00000080 +#define NFSV4OPBM_BACKCHANNELCTL 0x00000100 +#define NFSV4OPBM_BINDCONNTOSESS 0x00000200 +#define NFSV4OPBM_EXCHANGEID 0x00000400 +#define NFSV4OPBM_CREATESESSION 0x00000800 +#define NFSV4OPBM_DESTROYSESSION 0x00001000 +#define NFSV4OPBM_FREESTATEID 0x00002000 +#define NFSV4OPBM_GETDIRDELEG 0x00004000 +#define NFSV4OPBM_GETDEVINFO 0x00008000 +#define NFSV4OPBM_GETDEVLIST 0x00010000 +#define NFSV4OPBM_LAYOUTCOMMIT 0x00020000 +#define NFSV4OPBM_LAYOUTGET 0x00040000 +#define NFSV4OPBM_LAYOUTRETURN 0x00080000 +#define NFSV4OPBM_SECINFONONAME 0x00100000 +#define NFSV4OPBM_SEQUENCE 0x00200000 +#define NFSV4OPBM_SETSSV 0x00400000 +#define NFSV4OPBM_TESTSTATEID 0x00800000 +#define NFSV4OPBM_WANTDELEG 0x01000000 +#define NFSV4OPBM_DESTROYCLIENTID 0x02000000 +#define NFSV4OPBM_RECLAIMCOMPL 0x04000000 +#define NFSV4OPBM_ALLOCATE 0x08000000 +#define NFSV4OPBM_COPY 0x10000000 +#define NFSV4OPBM_COPYNOTIFY 0x20000000 +#define NFSV4OPBM_DEALLOCATE 0x40000000 +#define NFSV4OPBM_IOADVISE 0x80000000 +#define NFSV4OPBM_LAYOUTERROR 0x00000001 +#define NFSV4OPBM_LAYOUTSTATS 0x00000002 +#define NFSV4OPBM_OFFLOADCANCEL 0x00000004 +#define NFSV4OPBM_OFFLOADSTATUS 0x00000008 +#define NFSV4OPBM_READPLUS 0x00000010 +#define NFSV4OPBM_SEEK 0x00000020 +#define NFSV4OPBM_WRITESAME 0x00000040 +#define NFSV4OPBM_CLONE 0x00000080 +#define NFSV4OPBM_GETXATTR 0x00000100 +#define NFSV4OPBM_SETXATTR 0x00000200 +#define NFSV4OPBM_LISTXATTRS 0x00000400 +#define NFSV4OPBM_REMOVEXATTR 0x00000800 + +/* + * The set of must and allow operations for SP4_MACH_CRED. These are + * the operations requested by the Linux NFSv4.1/4.2 client. + * The must list is also the same ones listed in the RFC. + */ +#define NFSOPBIT_MUST0 NFSV4OP_DELEGPURGE + +#define NFSOPBIT_MUST1 \ + (NFSV4OPBM_BINDCONNTOSESS | \ + NFSV4OPBM_EXCHANGEID | \ + NFSV4OPBM_CREATESESSION | \ + NFSV4OPBM_DESTROYSESSION | \ + NFSV4OPBM_DESTROYCLIENTID) + +#define NFSOPBIT_MUST2 0x0 + +#define NFSOPBIT_CLRNOTMUST(b) do { \ + (b)->bits[0] &= NFSOPBIT_MUST0; \ + (b)->bits[1] &= NFSOPBIT_MUST1; \ + (b)->bits[2] &= NFSOPBIT_MUST2; \ + } while (0) + +#define NFSOPBIT_ALLOWED0 \ + (NFSV4OPBM_CLOSE | \ + NFSV4OPBM_COMMIT | \ + NFSV4OPBM_DELEGRETURN | \ + NFSV4OPBM_LOCKU | \ + NFSV4OPBM_OPENDOWNGRADE) + +#define NFSOPBIT_ALLOWED1 \ + (NFSV4OPBM_SECINFO | \ + NFSV4OPBM_WRITE | \ + NFSV4OPBM_FREESTATEID | \ + NFSV4OPBM_LAYOUTRETURN | \ + NFSV4OPBM_SECINFONONAME | \ + NFSV4OPBM_TESTSTATEID) + +#define NFSOPBIT_ALLOWED2 0x0 + +#define NFSOPBIT_CLRNOTALLOWED(b) do { \ + (b)->bits[0] &= NFSOPBIT_ALLOWED0; \ + (b)->bits[1] &= NFSOPBIT_ALLOWED1; \ + (b)->bits[2] &= NFSOPBIT_ALLOWED2; \ + } while (0) + /* * Structure for data handled by the statfs rpc. Since some fields are * u_int64_t, this cannot be used for copying data on/off the wire, due