X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fudev%2Fnet%2Fethtool-util.c;h=3ec245ecabc96b14b3e9582de3d61998653f109d;hp=0a4118c6ae43c0bf863bab7d0d8070116710c41d;hb=2c5859afecee81e345fc9526b1083bf79990ffb8;hpb=a501033335ed402c8f7e86fe41a15531ba69abd7 diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c index 0a4118c6a..3ec245eca 100644 --- a/src/udev/net/ethtool-util.c +++ b/src/udev/net/ethtool-util.c @@ -29,6 +29,24 @@ #include "strxcpyx.h" #include "util.h" #include "log.h" +#include "conf-parser.h" + +static const char* const duplex_table[_DUP_MAX] = { + [DUP_FULL] = "full", + [DUP_HALF] = "half" +}; + +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[_WOL_MAX] = { + [WOL_PHY] = "phy", + [WOL_MAGIC] = "magic", + [WOL_OFF] = "off" +}; + +DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan); +DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting"); int ethtool_connect(int *ret) { int fd; @@ -45,21 +63,45 @@ int ethtool_connect(int *ret) { return 0; } -int ethtool_set_speed(int fd, const char *ifname, const unsigned int speed, const char *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; + + 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; - bool need_update; + struct ethtool_cmd ecmd = { + .cmd = ETHTOOL_GSET + }; + struct ifreq ifr = { + .ifr_data = (void*) &ecmd + }; + bool need_update = false; int r; - if (speed == 0 && !duplex) + if (speed == 0 && duplex == _DUP_INVALID) return 0; - memset(&ecmd, 0x00, sizeof(struct ethtool_cmd)); - ecmd.cmd = ETHTOOL_GSET; - memset(&ifr, 0x00, sizeof(struct ifreq)); strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - ifr.ifr_data = (void *)&ecmd; r = ioctl(fd, SIOCETHTOOL, &ifr); if (r < 0) @@ -70,17 +112,21 @@ int ethtool_set_speed(int fd, const char *ifname, const unsigned int speed, cons need_update = true; } - if (duplex) { - if (streq(duplex, "half")) { + switch (duplex) { + case DUP_HALF: if (ecmd.duplex != DUPLEX_HALF) { ecmd.duplex = DUPLEX_HALF; need_update = true; } - } else if (streq(duplex, "full")) + break; + case DUP_FULL: if (ecmd.duplex != DUPLEX_FULL) { ecmd.duplex = DUPLEX_FULL; need_update = true; } + break; + default: + break; } if (need_update) { @@ -94,42 +140,47 @@ int ethtool_set_speed(int fd, const char *ifname, const unsigned int speed, cons return 0; } -int ethtool_set_wol(int fd, const char *ifname, const char *wol) { - struct ifreq ifr; - struct ethtool_wolinfo ecmd; - bool need_update; +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) + if (wol == _WOL_INVALID) return 0; - memset(&ecmd, 0x00, sizeof(struct ethtool_wolinfo)); - ecmd.cmd = ETHTOOL_GWOL; - memset(&ifr, 0x00, sizeof(struct ifreq)); strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - ifr.ifr_data = (void *)&ecmd; r = ioctl(fd, SIOCETHTOOL, &ifr); if (r < 0) return -errno; - if (streq(wol, "phy")) { - if (ecmd.wolopts != WAKE_PHY) { - ecmd.wolopts = WAKE_PHY; - need_update = true; - } - } else if (streq(wol, "magic")) { - if (ecmd.wolopts != WAKE_MAGIC) { - ecmd.wolopts = WAKE_MAGIC; - need_update = true; - } - } else if (streq(wol, "off")) { - if (ecmd.wolopts != 0) { - ecmd.wolopts = 0; - need_update = true; - } - } else - return -EINVAL; + switch (wol) { + case WOL_PHY: + if (ecmd.wolopts != WAKE_PHY) { + ecmd.wolopts = WAKE_PHY; + need_update = true; + } + break; + case WOL_MAGIC: + if (ecmd.wolopts != WAKE_MAGIC) { + ecmd.wolopts = WAKE_MAGIC; + need_update = true; + } + break; + case WOL_OFF: + if (ecmd.wolopts != 0) { + ecmd.wolopts = 0; + need_update = true; + } + break; + default: + break; + } if (need_update) { ecmd.cmd = ETHTOOL_SWOL;