diff options
Diffstat (limited to 'src/udev/net')
-rw-r--r-- | src/udev/net/ethtool-util.c | 23 | ||||
-rw-r--r-- | src/udev/net/ethtool-util.h | 1 | ||||
-rw-r--r-- | src/udev/net/link-config.c | 40 | ||||
-rw-r--r-- | src/udev/net/link-config.h | 2 |
4 files changed, 57 insertions, 9 deletions
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c index c644f91d02..aaba94c2fb 100644 --- a/src/udev/net/ethtool-util.c +++ b/src/udev/net/ethtool-util.c @@ -63,6 +63,29 @@ int ethtool_connect(int *ret) { return 0; } +int ethtool_get_driver(int fd, const char *ifname, char **ret) { + struct ifreq ifr; + struct ethtool_drvinfo ecmd; + int r; + + zero(ecmd); + ecmd.cmd = ETHTOOL_GDRVINFO; + + zero(ifr); + strscpy(ifr.ifr_name, IFNAMSIZ, ifname); + ifr.ifr_data = (void *)&ecmd; + + r = ioctl(fd, SIOCETHTOOL, &ifr); + if (r < 0) + return -errno; + + *ret = strdup(ecmd.driver); + if (!*ret) + return -ENOMEM; + + return 0; +} + int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex duplex) { struct ifreq ifr; diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h index c8638f22ec..f44de5076a 100644 --- a/src/udev/net/ethtool-util.h +++ b/src/udev/net/ethtool-util.h @@ -42,6 +42,7 @@ typedef enum WakeOnLan { int ethtool_connect(int *ret); +int ethtool_get_driver(int fd, const char *ifname, char **ret); int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex duplex); int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index e8389c9be0..40b1d7f7bc 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -90,16 +90,17 @@ int link_config_ctx_new(link_config_ctx **ret) { static int link_config_ctx_connect(link_config_ctx *ctx) { int r; - if (ctx->ethtool_fd >= 0 && ctx->rtnl) - return 0; - - r = ethtool_connect(&ctx->ethtool_fd); - if (r < 0) - return r; + if (ctx->ethtool_fd == -1) { + r = ethtool_connect(&ctx->ethtool_fd); + if (r < 0) + return r; + } - r = sd_rtnl_open(&ctx->rtnl, 0); - if (r < 0) - return r; + if (!ctx->rtnl) { + r = sd_rtnl_open(&ctx->rtnl, 0); + if (r < 0) + return r; + } return 0; } @@ -442,6 +443,27 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev return 0; } +int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) { + const char *name; + char *driver; + int r; + + r = link_config_ctx_connect(ctx); + if (r < 0) + return r; + + name = udev_device_get_sysname(device); + if (!name) + return -EINVAL; + + r = ethtool_get_driver(ctx->ethtool_fd, name, &driver); + if (r < 0) + return r; + + *ret = driver; + return 0; +} + static const char* const mac_policy_table[] = { [MACPOLICY_PERSISTENT] = "persistent", [MACPOLICY_RANDOM] = "random" diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index 9d2eaff37c..24fdb87e4c 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -83,6 +83,8 @@ bool link_config_should_reload(link_config_ctx *ctx); int link_config_get(link_config_ctx *ctx, struct udev_device *device, struct link_config **ret); int link_config_apply(link_config_ctx *ctx, struct link_config *config, struct udev_device *device, const char **name); +int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret); + const char *name_policy_to_string(NamePolicy p) _const_; NamePolicy name_policy_from_string(const char *p) _pure_; |