#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"
// 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) {
}
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)
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);
#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"
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;
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;
#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"
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);
#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 },
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) {
},
// Methods
- .init = interfaces_init,
- .free = interfaces_free,
.heartbeat = interfaces_heartbeat,
};
#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;
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);
nl_cache_free(routes);
if (links)
nl_cache_free(links);
- if (sock)
- nl_socket_free(sock);
return r;
}
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;