git: 9b27a22ac696 - main - unix: factor unp_connectat_peer() out of unp_connectat()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 10 Aug 2026 17:40:35 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=9b27a22ac69632d50e3561fd15ca710c022f3e70

commit 9b27a22ac69632d50e3561fd15ca710c022f3e70
Author:     John Ericson <John.Ericson@Obsidian.Systems>
AuthorDate: 2026-08-10 15:04:27 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-10 17:31:21 +0000

    unix: factor unp_connectat_peer() out of unp_connectat()
    
    Move the "resolve a connectat(2) target to a referenced peer socket"
    half of `unp_connectat()` -- the `namei()` lookup and `unp_vnode_peer()`
    call -- into a helper, leaving `unp_connectat()` with the connection state
    machine plus a single `unp_connect_peer()`.
    
    This is where the next change grows the ways a peer can be named; keeping
    it a helper up front keeps that change focused on the new resolution
    logic.
    
    No functional change intended.
    
    Signed-off-by: John Ericson <John.Ericson@Obsidian.Systems>
    Assisted-by: Claude Code (Claude Opus 4.8 and Fable 5)
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D58462
---
 sys/kern/uipc_usrreq.c | 53 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 418c43a8ac85..60b0f3b8706e 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -296,6 +296,8 @@ static int	unp_connectat(int, struct socket *, struct sockaddr *,
 		    struct thread *, struct socket **);
 static int	unp_connect_peer(struct socket *, struct unpcb *,
 		    struct sockaddr **, struct thread *, bool);
+static int	unp_connectat_peer(struct thread *, int, const char *,
+		    struct socket **);
 static int	unp_vnode_peer(struct vnode *, struct thread *,
 		    struct socket **);
 static void	unp_connect2(struct socket *, struct socket *, bool);
@@ -2934,10 +2936,8 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam,
 {
 	struct socket *so2;
 	struct unpcb *unp;
-	struct nameidata nd;
 	char buf[SOCK_MAXADDRLEN];
 	struct sockaddr *sa;
-	cap_rights_t rights;
 	const char *path;
 	int error, len;
 	bool connreq;
@@ -2994,22 +2994,7 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam,
 		sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
 	else
 		sa = NULL;
-	NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF |
-	    (fd == AT_FDCWD ? 0 : EMPTYPATH), UIO_SYSSPACE, buf, fd,
-	    cap_rights_init_one(&rights, CAP_CONNECTAT));
-	error = namei(&nd);
-	if (error)
-		goto out;
-	NDFREE_PNBUF(&nd);
-
-	/*
-	 * Resolve the vnode to a referenced peer socket and drop the vnode
-	 * before connecting: the reference keeps the peer stable, so no vnode
-	 * lock is held across unp_connect_peer() (which matters for the
-	 * return_locked datagram fast path).
-	 */
-	error = unp_vnode_peer(nd.ni_vp, td, &so2);
-	vput(nd.ni_vp);
+	error = unp_connectat_peer(td, fd, buf, &so2);
 	if (error != 0)
 		goto out;
 	error = unp_connect_peer(so, sotounpcb(so2), &sa, td,
@@ -3031,6 +3016,38 @@ out:
 	return (error);
 }
 
+/*
+ * Resolve a connectat(2) target -- descriptor 'fd' and the pathname in 'buf' --
+ * to a referenced peer unix socket in '*so2p'.  The caller must release it with
+ * sorele().
+ */
+static int
+unp_connectat_peer(struct thread *td, int fd, const char *buf,
+    struct socket **so2p)
+{
+	struct nameidata nd;
+	cap_rights_t rights;
+	int error;
+
+	NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF |
+	    (fd == AT_FDCWD ? 0 : EMPTYPATH), UIO_SYSSPACE, buf, fd,
+	    cap_rights_init_one(&rights, CAP_CONNECTAT));
+	error = namei(&nd);
+	if (error != 0)
+		return (error);
+	NDFREE_PNBUF(&nd);
+
+	/*
+	 * Resolve the vnode to a referenced peer socket and drop the vnode
+	 * before connecting: the reference keeps the peer stable, so no vnode
+	 * lock is held across unp_connect_peer() (which matters for the
+	 * return_locked datagram fast path).
+	 */
+	error = unp_vnode_peer(nd.ni_vp, td, so2p);
+	vput(nd.ni_vp);
+	return (error);
+}
+
 /*
  * Resolve locked vnode 'vp' to the unix-domain socket it names and return a
  * referenced peer socket in '*so2p'.  As the connect(2)-time resolution, this