]> git.ipfire.org Git - telemetry.git/commitdiff
daemon: Create a single, global Netlink Route socket
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 28 Nov 2025 17:58:19 +0000 (17:58 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 28 Nov 2025 17:58:19 +0000 (17:58 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/daemon.c
src/daemon/daemon.h
src/daemon/source.c
src/daemon/source.h
src/daemon/sources/interfaces.c
src/daemon/sources/legacy-gateway-latency4.c

index 4bc1943957e73b3e673d322465122ac4b11bbab6..801f1024ee83a581942ae053e98ae48f48599f60 100644 (file)
 #include <systemd/sd-daemon.h>
 #include <systemd/sd-event.h>
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+#  include <netlink/route/route.h>
+#  include <netlink/socket.h>
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
 #include "bus.h"
 #include "ctx.h"
 #include "daemon.h"
@@ -71,6 +78,15 @@ struct td_daemon {
 
        // udev
        struct udev* udev;
+
+       // Netlink Sockets
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+       struct {
+               struct nl_sock* route;
+       } nl_sockets;
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
 };
 
 static int td_daemon_init(sd_event_source* source, void* data) {
@@ -242,6 +258,14 @@ static int td_daemon_setup_udev(td_daemon* self) {
 }
 
 static void td_daemon_free(td_daemon* self) {
+       // Free Netlink Sockets
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+       if (self->nl_sockets.route)
+               nl_socket_free(self->nl_sockets.route);
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
        if (self->events.memory_pressure)
                sd_event_source_unref(self->events.memory_pressure);
        if (self->events.sigchld)
@@ -394,6 +418,42 @@ int td_daemon_flush_source(
        return td_queue_flush_source(self->queue, source, object);
 }
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+struct nl_sock* td_daemon_get_nl_route_socket(td_daemon* self) {
+       int r;
+
+       // Create socket if not already done
+       if (!self->nl_sockets.route) {
+               // Allocate a new socket
+               self->nl_sockets.route = nl_socket_alloc();
+               if (!self->nl_sockets.route) {
+                       ERROR(self->ctx, "Failed to allocate a new Netlink socket: %m\n");
+                       goto ERROR;
+               }
+
+               // Select routing
+               r = nl_connect(self->nl_sockets.route, NETLINK_ROUTE);
+               if (r < 0) {
+                       ERROR(self->ctx, "Failed to select routing: %s\n", nl_geterror(r));
+                       errno = ENOTSUP;
+                       goto ERROR;
+               }
+       }
+
+       return self->nl_sockets.route;
+
+ERROR:
+       if (self->nl_sockets.route) {
+               nl_socket_free(self->nl_sockets.route);
+               self->nl_sockets.route = NULL;
+       }
+
+       return NULL;
+}
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
 static int td_daemon_bus_version(sd_bus* bus, const char* path, const char* interface,
                const char* property, sd_bus_message* reply, void* data, sd_bus_error* error) {
        return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
index a34e71274c2291b70194df638e4653d99ae2e39d..574af63cd5461f0ec1751bf7285a50f797abdbde 100644 (file)
 #include <libudev.h>
 #include <systemd/sd-event.h>
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+#  include <netlink/socket.h>
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
+
 typedef struct td_daemon td_daemon;
 
 #include "bus.h"
@@ -51,6 +58,12 @@ int td_daemon_submit_metrics(td_daemon* self, td_metrics* metrics);
 int td_daemon_flush_source(
        td_daemon* self, td_source* source, const char* object);
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+struct nl_sock* td_daemon_get_nl_route_socket(td_daemon* self);
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
 // Bus
 extern const td_bus_implementation daemon_bus_impl;
 
index 6cbbe2ea3466022f1a53d8663e360caade166c85..678ca5b2879ad3ccd6983046a9f0a653dbd46d6b 100644 (file)
@@ -547,6 +547,10 @@ struct udev* td_source_get_udev(td_source* self) {
        return td_daemon_get_udev(self->daemon);
 }
 
+struct nl_sock* td_source_get_nl_route_socket(td_source* self) {
+       return td_daemon_get_nl_route_socket(self->daemon);
+}
+
 unsigned int td_source_num_data_sources(td_source* self) {
        unsigned int num_sources = 0;
 
index e66b881241efaea8b0d44cdbf5ba18d4df4d88d1..9df02fcb06b6b37513e595ce7778db9a7d5e84b7 100644 (file)
 
 #include <libudev.h>
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+#  include <netlink/socket.h>
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
 typedef struct td_source td_source;
 
 #include "args.h"
@@ -85,6 +91,12 @@ int td_source_disable(td_source* self);
 
 struct udev* td_source_get_udev(td_source* self);
 
+#ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_ROUTE
+struct nl_sock* td_source_get_nl_route_socket(td_source* self);
+# endif /* HAVE_LIBNL3_ROUTE */
+#endif /* HAVE_LIBNL3 */
+
 unsigned int td_source_num_data_sources(td_source* self);
 const td_rrd_ds* td_source_get_data_sources(td_source* self);
 
index 263f990c1c3d25f47ab763e32cd74dbc8f6ba3cd..a2183136b24b3ef283bc36015e7d309372b18df8 100644 (file)
 #include "../time.h"
 #include "interfaces.h"
 
-// Netlink Socket
-static struct nl_sock* sock = NULL;
-
 typedef struct interfaces_stats {
        const char* field;
        rtnl_link_stat_id_t id;
 }  interfaces_stats;
 
-static int interfaces_init(td_ctx* ctx, td_source* source) {
-       int r;
-
-       // Don't open the socket again
-       if (sock)
-               return 0;
-
-       // Create a new netlink socket
-       sock = nl_socket_alloc();
-       if (!sock) {
-               ERROR(ctx, "Failed to create a netlink socket: %m\n");
-               r = -errno;
-               goto ERROR;
-       }
-
-       // Select routing
-       r = nl_connect(sock, NETLINK_ROUTE);
-       if (r < 0) {
-               ERROR(ctx, "Failed to select routing: %s\n", nl_geterror(r));
-               r = -ENOTSUP;
-               goto ERROR;
-       }
-
-       // Success
-       return 0;
-
-ERROR:
-       if (sock) {
-               nl_socket_free(sock);
-               sock = NULL;
-       }
-
-       return r;
-}
-
-static int interfaces_free(td_ctx* ctx) {
-       if (sock) {
-               nl_socket_free(sock);
-               sock = NULL;
-       }
-
-       return 0;
-}
-
 static const interfaces_stats stats[] = {
        // Packets Received/Sent
        { "rx_packets", RTNL_LINK_RX_PACKETS },
@@ -188,6 +141,11 @@ static int interfaces_heartbeat(td_ctx* ctx, td_source* source) {
        struct nl_cache* links = NULL;
        int r;
 
+       // Fetch the Netlink socket
+       struct nl_sock* sock = td_source_get_nl_route_socket(source);
+       if (!sock)
+               return -errno;
+
        // Fetch the links
        r = rtnl_link_alloc_cache(sock, AF_UNSPEC, &links);
        if (r < 0) {
@@ -272,7 +230,5 @@ const td_source_impl interfaces_source = {
        },
 
        // Methods
-       .init      = interfaces_init,
-       .free      = interfaces_free,
        .heartbeat = interfaces_heartbeat,
 };
index 5226becdf099d4ebed709a1dd64004c807f8bc8d..2040d486ac70f3cba28e28bc110f38236a4a8283 100644 (file)
@@ -34,9 +34,8 @@
 #include "../time.h"
 #include "legacy-gateway-latency4.h"
 
-static int fetch_default_gateway(td_ctx* ctx,
+static int fetch_default_gateway(td_ctx* ctx, td_source* source,
                char* address, size_t length, unsigned int* type) {
-       struct nl_sock* sock = NULL;
        struct nl_cache* routes = NULL;
        struct rtnl_route* route = NULL;
        struct nl_cache* links = NULL;
@@ -46,21 +45,10 @@ static int fetch_default_gateway(td_ctx* ctx,
        int ifindex = -1;
        int r;
 
-       // Create a new netlink socket
-       sock = nl_socket_alloc();
-       if (!sock) {
-               ERROR(ctx, "Failed to create a netlink socket: %m\n");
-               r = -errno;
-               goto ERROR;
-       }
-
-       // Select routing
-       r = nl_connect(sock, NETLINK_ROUTE);
-       if (r < 0) {
-               ERROR(ctx, "Failed to select routing: %s\n", nl_geterror(r));
-               r = -ENOTSUP;
-               goto ERROR;
-       }
+       // Fetch the Netlink socket
+       struct nl_sock* sock = td_source_get_nl_route_socket(source);
+       if (!sock)
+               return -errno;
 
        // Fetch the route cache
        r = rtnl_route_alloc_cache(sock, AF_INET, 0, &routes);
@@ -125,8 +113,6 @@ ERROR:
                nl_cache_free(routes);
        if (links)
                nl_cache_free(links);
-       if (sock)
-                nl_socket_free(sock);
 
        return r;
 }
@@ -216,7 +202,7 @@ static int legacy_gateway_latency4_heartbeat(td_ctx* ctx, td_source* source) {
        int r;
 
        // Fetch the IP address of the default gateway
-       r = fetch_default_gateway(ctx, address, sizeof(address), &type);
+       r = fetch_default_gateway(ctx, source, address, sizeof(address), &type);
        if (r < 0)
                return r;