]> git.ipfire.org Git - people/ms/network.git/commitdiff
networkd: Handle any uevents for links
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 10 Jun 2023 11:29:22 +0000 (11:29 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 10 Jun 2023 11:30:41 +0000 (11:30 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/devmon.c
src/networkd/link.c
src/networkd/link.h

index 0a8c26d4ccd13f3ae150bd6f01034f4de1a71a65..c751985cc56133d86c97a8e8f892d3a67ae7b83a 100644 (file)
 
 #include <systemd/sd-device.h>
 
+#include "daemon.h"
 #include "devmon.h"
+#include "logging.h"
+
+static int nw_daemon_handle_uevent_net(nw_daemon* daemon,
+               sd_device* device, sd_device_action_t action) {
+       nw_link* link = NULL;
+       int ifindex;
+       int r;
+
+       // Fetch ifindex
+       r = sd_device_get_ifindex(device, &ifindex);
+       if (r < 0) {
+               ERROR("Could not get ifindex from uevent: %s\n", strerror(-r));
+               goto ERROR;
+       }
+
+       // Fetch the link
+       link = nw_daemon_get_link_by_ifindex(daemon, ifindex);
+       if (!link) {
+               DEBUG("Could not fetch link %d, ignoring\n", ifindex);
+               r = 0;
+               goto ERROR;
+       }
+
+       // Let the link handle its uevent
+       r = nw_link_handle_uevent(link, device, action);
+
+ERROR:
+       if (link)
+               nw_link_unref(link);
+
+       return r;
+}
 
 int nw_devmon_handle_uevent(sd_device_monitor* monitor, sd_device* device, void* data) {
+       sd_device_action_t action;
+       const char* subsystem = NULL;
+       int r;
+
+       // Fetch daemon
+       nw_daemon* daemon = (nw_daemon*)data;
+
+       // Fetch action
+       r = sd_device_get_action(device, &action);
+       if (r < 0) {
+               WARNING("Could not get uevent action, ignoring: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Fetch subsystem
+       r = sd_device_get_subsystem(device, &subsystem);
+       if (r < 0) {
+               ERROR("Could not get uevent subsystem, ignoring: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Handle any links
+       if (strcmp(subsystem, "net") == 0) {
+               r = nw_daemon_handle_uevent_net(daemon, device, action);
+
+       } else {
+               DEBUG("Received an uevent for an unhandled subsystem '%s', ignoring\n", subsystem);
+               return 0;
+       }
+
+       // Log if something went wrong
+       if (r < 0)
+               ERROR("Failed processing uevent: %s\n", strerror(-r));
+
        return 0;
 }
index f172208e8d5c6ab7ddf2c1a9a2245b3ee748b412..b0d9e86501c8f95c9b6504e2e79f70eb722899c8 100644 (file)
@@ -559,6 +559,25 @@ ERROR:
        return r;
 }
 
+// uevent
+
+int nw_link_handle_uevent(nw_link* link, sd_device* device, sd_device_action_t action) {
+       // We need to remove or replace the stored device as it is now outdated
+       if (link->device) {
+               sd_device_unref(link->device);
+
+               // If the device has been removed, we remove its reference
+               if (action == SD_DEVICE_REMOVE)
+                       link->device = NULL;
+
+               // Otherwise we just store the new one
+               else
+                       link->device = sd_device_ref(device);
+       }
+
+       return 0;
+}
+
 // JSON
 
 static int nw_link_device_to_json(nw_link* link, struct json_object* o) {
index 36c7d9dd6c29e4804bdf0df389f16b89e70014c9..c2f7b7e63d7dddaf67fe4e791a8113e8e1e908c7 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <linux/if_link.h>
 
+#include <systemd/sd-device.h>
+
 typedef struct nw_link nw_link;
 
 #include "daemon.h"
@@ -46,6 +48,9 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data);
 
 int nw_link_destroy(nw_link* link);
 
+// uevent
+int nw_link_handle_uevent(nw_link* link, sd_device* device, sd_device_action_t action);
+
 // JSON
 int nw_link_to_json(nw_link* link, struct json_object* o);