aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2025-01-20 21:15:39 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2025-01-20 21:15:39 +0000
commitddc7fd6641c38a00d8d299d69ba57f0657f5eaac (patch)
tree864efe5c83bd4c59a9b4d31115a20a0261d8bf6b
parentdae4eb623e862789533dca8b644ea531502a088f (diff)
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
-rw-r--r--sys/netlink/netlink_snl.h23
1 files 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);
}
}
@@ -291,6 +290,16 @@ snl_init(struct snl_state *ss, int netlink_family)
}
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)
{
return (send(ss->fd, data, sz, 0) == sz);