git: ddc7fd6641c3 - main - netlink: provide snl_clone() to create a secondary snl state

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Mon, 20 Jan 2025 21:15:47 UTC
The branch main has been updated by glebius:

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

commit ddc7fd6641c38a00d8d299d69ba57f0657f5eaac
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-01-20 21:15:39 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-01-20 21:15:39 +0000

    netlink: provide snl_clone() to create a secondary snl state
    
    The function will clone an existing snl_state().  The clone points at the
    same socket, but has a separate allocator.  Closing a clone frees the
    memory, but doesn't close the socket.  Such clones are handy in a
    multithreaded process that has a single socket with multiple writers and a
    serialized reader.  It can be easily extended to support multiple readers,
    too, but now there is no use.
    
    Reviewed by:            melifaro
    Differential Revision:  https://reviews.freebsd.org/D48568
---
 sys/netlink/netlink_snl.h | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
index 44967b6f444a..faaeebe52eac 100644
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -240,14 +240,13 @@ snl_clear_lb(struct snl_state *ss)
 static void
 snl_free(struct snl_state *ss)
 {
-	if (ss->init_done) {
+	if (ss->init_done)
 		close(ss->fd);
-		if (ss->buf != NULL)
-			free(ss->buf);
-		if (ss->lb != NULL) {
-			snl_clear_lb(ss);
-			lb_free(ss->lb);
-		}
+	if (ss->buf != NULL)
+		free(ss->buf);
+	if (ss->lb != NULL) {
+		snl_clear_lb(ss);
+		lb_free(ss->lb);
 	}
 }
 
@@ -290,6 +289,16 @@ snl_init(struct snl_state *ss, int netlink_family)
 	return (true);
 }
 
+static inline bool
+snl_clone(struct snl_state *ss, const struct snl_state *orig)
+{
+	*ss = (struct snl_state){
+		.fd = orig->fd,
+		.init_done = false,
+	};
+	return ((ss->lb = lb_init(SCRATCH_BUFFER_SIZE)) != NULL);
+}
+
 static inline bool
 snl_send(struct snl_state *ss, void *data, int sz)
 {