X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fnet%2Fethtool-util.c;h=ec67126b21b1995ce01bddb453260afe9b076a30;hb=baade8cc237c37bd8905d86ec6e9c7872d4abe03;hp=c644f91d02d749b9e41f400ea411652a4390bf48;hpb=0a2c2294265d1d4552af3e7a92df0d4560deb818;p=elogind.git diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c index c644f91d0..ec67126b2 100644 --- a/src/udev/net/ethtool-util.c +++ b/src/udev/net/ethtool-util.c @@ -31,7 +31,7 @@ #include "log.h" #include "conf-parser.h" -static const char* const duplex_table[] = { +static const char* const duplex_table[_DUP_MAX] = { [DUP_FULL] = "full", [DUP_HALF] = "half" }; @@ -39,7 +39,7 @@ static const char* const duplex_table[] = { DEFINE_STRING_TABLE_LOOKUP(duplex, Duplex); DEFINE_CONFIG_PARSE_ENUM(config_parse_duplex, duplex, Duplex, "Failed to parse duplex setting"); -static const char* const wol_table[] = { +static const char* const wol_table[_WOL_MAX] = { [WOL_PHY] = "phy", [WOL_MAGIC] = "magic", [WOL_OFF] = "off" @@ -63,24 +63,59 @@ int ethtool_connect(int *ret) { return 0; } -int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex duplex) +int ethtool_get_driver(int *fd, const char *ifname, char **ret) { + struct ethtool_drvinfo ecmd = { + .cmd = ETHTOOL_GDRVINFO + }; + struct ifreq ifr = { + .ifr_data = (void*) &ecmd + }; + char *d; + int r; + + if (*fd < 0) { + r = ethtool_connect(fd); + if (r < 0) + return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); + } + + strscpy(ifr.ifr_name, IFNAMSIZ, ifname); + + r = ioctl(*fd, SIOCETHTOOL, &ifr); + if (r < 0) + return -errno; + + d = strdup(ecmd.driver); + if (!d) + return -ENOMEM; + + *ret = d; + return 0; +} + +int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex) { - struct ifreq ifr; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { + .cmd = ETHTOOL_GSET + }; + struct ifreq ifr = { + .ifr_data = (void*) &ecmd + }; bool need_update = false; int r; if (speed == 0 && duplex == _DUP_INVALID) return 0; - zero(ecmd); - ecmd.cmd = ETHTOOL_GSET; + if (*fd < 0) { + r = ethtool_connect(fd); + if (r < 0) + return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); + } - zero(ifr); strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - ifr.ifr_data = (void *)&ecmd; - r = ioctl(fd, SIOCETHTOOL, &ifr); + r = ioctl(*fd, SIOCETHTOOL, &ifr); if (r < 0) return -errno; @@ -109,7 +144,7 @@ int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex dup if (need_update) { ecmd.cmd = ETHTOOL_SSET; - r = ioctl(fd, SIOCETHTOOL, &ifr); + r = ioctl(*fd, SIOCETHTOOL, &ifr); if (r < 0) return -errno; } @@ -117,23 +152,28 @@ int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex dup return 0; } -int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol) { - struct ifreq ifr; - struct ethtool_wolinfo ecmd; +int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) { + struct ethtool_wolinfo ecmd = { + .cmd = ETHTOOL_GWOL + }; + struct ifreq ifr = { + .ifr_data = (void*) &ecmd + }; bool need_update = false; int r; if (wol == _WOL_INVALID) return 0; - zero(ecmd); - ecmd.cmd = ETHTOOL_GWOL; + if (*fd < 0) { + r = ethtool_connect(fd); + if (r < 0) + return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); + } - zero(ifr); strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - ifr.ifr_data = (void *)&ecmd; - r = ioctl(fd, SIOCETHTOOL, &ifr); + r = ioctl(*fd, SIOCETHTOOL, &ifr); if (r < 0) return -errno; @@ -163,7 +203,7 @@ int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol) { if (need_update) { ecmd.cmd = ETHTOOL_SWOL; - r = ioctl(fd, SIOCETHTOOL, &ifr); + r = ioctl(*fd, SIOCETHTOOL, &ifr); if (r < 0) return -errno; }