]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: add new builtin net_driver
authorLukas Nykryn <lnykryn@redhat.com>
Thu, 19 Oct 2023 08:38:06 +0000 (10:38 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 1 Nov 2023 16:00:19 +0000 (16:00 +0000)
Currently the ID_NET_DRIVER is set in net_setup_link builtin.
But this is called pretty late in the udev processing chain.

Right now in some custom rules it was workarounded by calling ethtool
binary directly, which is ugly.

So let's split this code to a separate builtin.

rules.d/50-udev-default.rules.in
src/udev/meson.build
src/udev/net/link-config.c
src/udev/net/link-config.h
src/udev/udev-builtin-net_driver.c [new file with mode: 0644]
src/udev/udev-builtin-net_setup_link.c
src/udev/udev-builtin.c
src/udev/udev-builtin.h

index eb9e239c706a760b9717256fe6f5115f8cb0d687..10234fd9e0bad107561a0025b5718a2083efb570 100644 (file)
@@ -26,6 +26,8 @@ ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
 # To keep the backward compatibility, let's set ID_PATH for them.
 SUBSYSTEM=="pci|usb|platform", IMPORT{builtin}="path_id"
 
+SUBSYSTEM=="net", IMPORT{builtin}="net_driver"
+
 ACTION!="add", GOTO="default_end"
 
 SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
index ac9a4c3ccae5fdedd63d66801c3c32ca5fbd40cb..824ec478039fa75ba2b1a6515cf90ef31ecf00d6 100644 (file)
@@ -32,6 +32,7 @@ libudevd_core_sources = files(
         'udev-builtin-hwdb.c',
         'udev-builtin-input_id.c',
         'udev-builtin-keyboard.c',
+        'udev-builtin-net_driver.c',
         'udev-builtin-net_id.c',
         'udev-builtin-net_setup_link.c',
         'udev-builtin-path_id.c',
index ff8fb24f6695385edff4497575ee0398aad20a93..910ec2709e5827da0e7f128f6730c12dd1f447a8 100644 (file)
@@ -364,7 +364,6 @@ Link *link_free(Link *link) {
 
         sd_device_unref(link->device);
         free(link->kind);
-        free(link->driver);
         strv_free(link->altnames);
         return mfree(link);
 }
@@ -417,8 +416,8 @@ int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, Link
                         log_link_debug_errno(link, r, "Failed to get permanent hardware address, ignoring: %m");
         }
 
-        r = ethtool_get_driver(&ctx->ethtool_fd, link->ifname, &link->driver);
-        if (r < 0)
+        r = sd_device_get_property_value(link->device, "ID_NET_DRIVER", &link->driver);
+        if (r < 0 && r != -ENOENT)
                 log_link_debug_errno(link, r, "Failed to get driver, ignoring: %m");
 
         *ret = TAKE_PTR(link);
index 713d41040a6b5d224f73bf4b9ed00d2339fdd1bb..bab9d12970a024a01ced97056fb73ee63b56dc4f 100644 (file)
@@ -34,7 +34,7 @@ typedef struct Link {
         sd_device_action_t action;
 
         char *kind;
-        char *driver;
+        const char *driver;
         uint16_t iftype;
         uint32_t flags;
         struct hw_addr_data hw_addr;
diff --git a/src/udev/udev-builtin-net_driver.c b/src/udev/udev-builtin-net_driver.c
new file mode 100644 (file)
index 0000000..f1642a4
--- /dev/null
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "device-util.h"
+#include "errno-util.h"
+#include "ethtool-util.h"
+#include "fd-util.h"
+#include "log.h"
+#include "string-util.h"
+#include "udev-builtin.h"
+
+static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv, bool test) {
+        sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
+        _cleanup_close_ int ethtool_fd = -EBADF;
+        _cleanup_free_ char *driver = NULL;
+        const char *sysname;
+        int r;
+
+        r = sd_device_get_sysname(dev, &sysname);
+        if (r < 0)
+                return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
+
+        r = ethtool_get_driver(&ethtool_fd, sysname, &driver);
+        if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
+                log_device_debug_errno(dev, r, "Querying driver name via ethtool API is not supported by device '%s', ignoring: %m", sysname);
+                return 0;
+        }
+        if (r == -ENODEV) {
+                log_device_debug_errno(dev, r, "Device already vanished, ignoring.");
+                return 0;
+        }
+        if (r < 0)
+                return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", sysname);
+
+        return udev_builtin_add_property(event->dev, test, "ID_NET_DRIVER", driver);
+}
+
+const UdevBuiltin udev_builtin_net_driver = {
+        .name = "net_driver",
+        .cmd = builtin_net_driver_set_driver,
+        .help = "Set driver for network device",
+        .run_once = true,
+};
index 5bc965f6d809e6b5331a2ed3a9a2ad8eee0eb986..a308a211fb0d99298ac9bc077536574633812497 100644 (file)
@@ -29,9 +29,6 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool
         if (r < 0)
                 return log_device_warning_errno(dev, r, "Failed to get link information: %m");
 
-        if (link->driver)
-                udev_builtin_add_property(dev, test, "ID_NET_DRIVER", link->driver);
-
         r = link_get_config(ctx, link);
         if (r < 0) {
                 if (r == -ENOENT) {
index a8dd656b00bf728bb64f38947cb10dd7b469cbef..bcc2018c6fb7d01f43f6b5ab77f9f5cd0bbcc73d 100644 (file)
@@ -22,6 +22,7 @@ static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = {
 #if HAVE_KMOD
         [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
 #endif
+        [UDEV_BUILTIN_NET_DRIVER] = &udev_builtin_net_driver,
         [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
         [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
         [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
index b2cf81ad312a8597b4781a7c8ab9db89416c9cbd..fcd41d615de4d63c72658c1990b7f1480a0e2a3e 100644 (file)
@@ -20,6 +20,7 @@ typedef enum UdevBuiltinCommand {
 #if HAVE_KMOD
         UDEV_BUILTIN_KMOD,
 #endif
+        UDEV_BUILTIN_NET_DRIVER,
         UDEV_BUILTIN_NET_ID,
         UDEV_BUILTIN_NET_LINK,
         UDEV_BUILTIN_PATH_ID,
@@ -64,6 +65,7 @@ extern const UdevBuiltin udev_builtin_keyboard;
 #if HAVE_KMOD
 extern const UdevBuiltin udev_builtin_kmod;
 #endif
+extern const UdevBuiltin udev_builtin_net_driver;
 extern const UdevBuiltin udev_builtin_net_id;
 extern const UdevBuiltin udev_builtin_net_setup_link;
 extern const UdevBuiltin udev_builtin_path_id;