git: e4c78de63e58 - main - netlink_snl: add snl_init_fd() to adopt an already open socket

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Fri, 30 Oct 2026 14:08:06 UTC
The branch main has been updated by kp:

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

commit e4c78de63e584617663a965fad2a4ce55f3d715a
Author:     Avinash Duduskar <avinash.duduskar@gmail.com>
AuthorDate: 2026-10-26 14:38:10 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-10-30 14:06:46 +0000

    netlink_snl: add snl_init_fd() to adopt an already open socket
    
    snl_init() always creates its own socket. Split out snl_init_fd(), which
    initialises the state on a descriptor the caller already holds, and make
    snl_init() open the socket and hand it over. The state owns the
    descriptor either way, including when initialisation fails, and
    snl_free() closes it; snl_clone() remains the way to borrow one.
    
    pfctl(8) needs this to run on a socket inherited from authpf(8).
    
    PR:             291981
    Signed-off-by:  Avinash Duduskar <avinash.duduskar@gmail.com>
    Reviewed by:    kp
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/2508
---
 share/man/man3/snl.3      | 18 +++++++++++++++++-
 sys/netlink/netlink_snl.h | 16 ++++++++++++----
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/share/man/man3/snl.3 b/share/man/man3/snl.3
index 04bae46691bf..b385f978b841 100644
--- a/share/man/man3/snl.3
+++ b/share/man/man3/snl.3
@@ -21,11 +21,12 @@
 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
-.Dd December 16, 2022
+.Dd October 26, 2026
 .Dt SNL 3
 .Os
 .Sh NAME
 .Nm snl_init ,
+.Nm snl_init_fd ,
 .Nm snl_free ,
 .Nm snl_read_message ,
 .Nm snl_send ,
@@ -52,6 +53,8 @@
 .In netlink/netlink_snl_route.h
 .Ft "bool"
 .Fn snl_init "struct snl_state *ss" "int netlink_family"
+.Ft "bool"
+.Fn snl_init_fd "struct snl_state *ss" "int fd"
 .Fn snl_free "struct snl_state *ss"
 .Ft "struct nlmsghdr *"
 .Fn snl_read_message "struct snl_state *ss"
@@ -101,6 +104,19 @@ Call
 with a pointer to the
 .Dv struct snl_state
 and the desired Netlink family to initialise the library instance.
+.Fn snl_init_fd
+initialises the instance on
+.Fa fd ,
+an already open Netlink socket.
+In both cases the instance owns the descriptor and
+.Fn snl_free
+closes it.
+Ownership passes with the call:
+if
+.Fn snl_init_fd
+fails,
+.Fa fd
+has already been closed.
 To free the library instance, call
 .Fn snl_free .
 .Pp
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
index 03c5a573da21..fad778ef9ce7 100644
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -269,13 +269,11 @@ snl_free(struct snl_state *ss)
 }
 
 static inline bool
-snl_init(struct snl_state *ss, int netlink_family)
+snl_init_fd(struct snl_state *ss, int fd)
 {
 	memset(ss, 0, sizeof(*ss));
 
-	ss->fd = socket(AF_NETLINK, SOCK_RAW, netlink_family);
-	if (ss->fd == -1)
-		return (false);
+	ss->fd = fd;
 	ss->init_done = true;
 
 	int val = 1;
@@ -307,6 +305,16 @@ snl_init(struct snl_state *ss, int netlink_family)
 	return (true);
 }
 
+static inline bool
+snl_init(struct snl_state *ss, int netlink_family)
+{
+	memset(ss, 0, sizeof(*ss));
+	ss->fd = socket(AF_NETLINK, SOCK_RAW, netlink_family);
+	if (ss->fd == -1)
+		return (false);
+	return (snl_init_fd(ss, ss->fd));
+}
+
 static inline bool
 snl_clone(struct snl_state *ss, const struct snl_state *orig)
 {