From: Michael Tremer Date: Sat, 10 Jun 2023 11:29:22 +0000 (+0000) Subject: networkd: Handle any uevents for links X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Fnetwork.git;a=commitdiff_plain;h=40e2c8ca02fae3d175e8d49498a3b3b443b1c6ef networkd: Handle any uevents for links Signed-off-by: Michael Tremer --- diff --git a/src/networkd/devmon.c b/src/networkd/devmon.c index 0a8c26d4..c751985c 100644 --- a/src/networkd/devmon.c +++ b/src/networkd/devmon.c @@ -20,8 +20,75 @@ #include +#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; } diff --git a/src/networkd/link.c b/src/networkd/link.c index f172208e..b0d9e865 100644 --- a/src/networkd/link.c +++ b/src/networkd/link.c @@ -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) { diff --git a/src/networkd/link.h b/src/networkd/link.h index 36c7d9dd..c2f7b7e6 100644 --- a/src/networkd/link.h +++ b/src/networkd/link.h @@ -23,6 +23,8 @@ #include +#include + 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);