--- fs/nfs/nfs_commonsubs.c.sav	2018-03-07 20:40:48.321467000 -0500
+++ fs/nfs/nfs_commonsubs.c	2018-03-07 20:41:24.691182000 -0500
@@ -131,7 +131,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV41_
 	{ 0, 2, 1, 1, LK_EXCLUSIVE, 1, 0 },		/* Write */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 0 },		/* ReleaseLockOwner */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Backchannel Ctrl */
-	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Bind Conn to Sess */
+	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Bind Conn to Sess */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Exchange ID */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Create Session */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 0, 0 },		/* Destroy Session */
--- fs/nfs/nfs_var.h.sav	2018-03-07 21:14:57.576474000 -0500
+++ fs/nfs/nfs_var.h	2018-03-07 21:16:54.597802000 -0500
@@ -95,6 +95,7 @@ int nfsrv_getclient(nfsquad_t, int, stru
     nfsquad_t, uint32_t, struct nfsrv_descript *, NFSPROC_T *);
 int nfsrv_destroyclient(nfsquad_t, NFSPROC_T *);
 int nfsrv_destroysession(struct nfsrv_descript *, uint8_t *);
+int nfsrv_bindconnsess(uint8_t *, int *);
 int nfsrv_freestateid(struct nfsrv_descript *, nfsv4stateid_t *, NFSPROC_T *);
 int nfsrv_adminrevoke(struct nfsd_clid *, NFSPROC_T *);
 void nfsrv_dumpclients(struct nfsd_dumpclients *, int);
@@ -230,6 +231,8 @@ int nfsrvd_reclaimcomplete(struct nfsrv_
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_destroyclientid(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
+int nfsrvd_bindconnsess(struct nfsrv_descript *, int,
+    vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_destroysession(struct nfsrv_descript *, int,
     vnode_t, NFSPROC_T *, struct nfsexstuff *);
 int nfsrvd_freestateid(struct nfsrv_descript *, int,
--- fs/nfs/nfsproto.h.sav	2018-03-07 21:32:38.706155000 -0500
+++ fs/nfs/nfsproto.h	2018-03-07 21:38:13.053734000 -0500
@@ -648,6 +648,15 @@
 #define	NFSFLAYUTIL_DENSE		0x1
 #define	NFSFLAYUTIL_COMMIT_THRU_MDS	0x2
 
+/* Enum values for Bind Connection to Session. */
+#define	NFSCDFC4_FORE		0x1
+#define	NFSCDFC4_BACK		0x2
+#define	NFSCDFC4_FORE_OR_BOTH	0x3
+#define	NFSCDFC4_BACK_OR_BOTH	0x7
+#define	NFSCDFS4_FORE		0x1
+#define	NFSCDFS4_BACK		0x2
+#define	NFSCDFS4_BOTH		0x3
+
 /* Conversion macros */
 #define	vtonfsv2_mode(t,m) 						\
 		txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : 	\
--- fs/nfsserver/nfs_nfsdserv.c.sav	2018-03-07 20:42:20.347017000 -0500
+++ fs/nfsserver/nfs_nfsdserv.c	2018-03-07 21:43:33.067606000 -0500
@@ -4041,6 +4041,45 @@ nfsmout:
 }
 
 /*
+ * nfsv4 bind connection to session service
+ */
+APPLESTATIC int
+nfsrvd_bindconnsess(struct nfsrv_descript *nd, __unused int isdgram,
+    __unused vnode_t vp, NFSPROC_T *p, __unused struct nfsexstuff *exp)
+{
+	uint32_t *tl;
+	uint8_t sessid[NFSX_V4SESSIONID];
+	int error = 0, foreaft;
+
+	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+		nd->nd_repstat = NFSERR_WRONGSEC;
+		goto nfsmout;
+	}
+	NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED);
+	NFSBCOPY(tl, sessid, NFSX_V4SESSIONID);
+	tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED);
+	foreaft = fxdr_unsigned(int, *tl++);
+	if (*tl == newnfs_true) {
+		/* RDMA is not supported. */
+		nd->nd_repstat = NFSERR_NOTSUPP;
+		goto nfsmout;
+	}
+
+	nd->nd_repstat = nfsrv_bindconnsess(sessid, &foreaft);
+	if (nd->nd_repstat == 0) {
+		NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 *
+		    NFSX_UNSIGNED);
+		NFSBCOPY(sessid, tl, NFSX_V4SESSIONID);
+		tl += (NFSX_V4SESSIONID / NFSX_UNSIGNED);
+		*tl++ = txdr_unsigned(foreaft);
+		*tl = newnfs_false;
+	}
+nfsmout:
+	NFSEXITCODE2(error, nd);
+	return (error);
+}
+
+/*
  * nfsv4 destroy session service
  */
 APPLESTATIC int
--- fs/nfsserver/nfs_nfsdsocket.c.sav	2018-03-07 21:12:50.052562000 -0500
+++ fs/nfsserver/nfs_nfsdsocket.c	2018-03-07 21:14:21.247331000 -0500
@@ -176,7 +176,7 @@ int (*nfsrv4_ops0[NFSV41_NOPS])(struct n
 	nfsrvd_write,
 	nfsrvd_releaselckown,
 	nfsrvd_notsupp,
-	nfsrvd_notsupp,
+	nfsrvd_bindconnsess,
 	nfsrvd_exchangeid,
 	nfsrvd_createsession,
 	nfsrvd_destroysession,
--- fs/nfsserver/nfs_nfsdstate.c.sav	2018-03-07 21:17:08.050132000 -0500
+++ fs/nfsserver/nfs_nfsdstate.c	2018-03-07 21:39:29.296950000 -0500
@@ -5950,6 +5950,44 @@ nfsrv_destroysession(struct nfsrv_descri
 }
 
 /*
+ * Bind a connection to a session.
+ * For now, only certain variants are supported, since the current session
+ * structure can only handle a single backchannel entry, which will be
+ * applied to all connections if it is set.
+ */
+int
+nfsrv_bindconnsess(uint8_t *sessionid, int *foreaftp)
+{
+	struct nfssessionhash *shp;
+	struct nfsdsession *sep;
+	int error;
+
+	error = 0;
+	shp = NFSSESSIONHASH(sessionid);
+	NFSLOCKSESSION(shp);
+	sep = nfsrv_findsession(sessionid);
+	if (sep != NULL) {
+		if ((sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0) {
+			/* Can only handle backchannel cases. */
+			if (*foreaftp == NFSCDFC4_FORE_OR_BOTH ||
+			    *foreaftp == NFSCDFC4_BACK_OR_BOTH)
+				*foreaftp = NFSCDFS4_BOTH;
+			else
+				error = NFSERR_NOTSUPP;
+		} else {
+			if (*foreaftp == NFSCDFC4_FORE ||
+			    *foreaftp == NFSCDFC4_FORE_OR_BOTH)
+				*foreaftp = NFSCDFS4_FORE;
+			else
+				error = NFSERR_NOTSUPP;
+		}
+	} else
+		error = NFSERR_NOTSUPP;
+	NFSUNLOCKSESSION(shp);
+	return (error);
+}
+
+/*
  * Free up a session structure.
  */
 static int
