From: Vincent Bernat Date: Sun, 7 Aug 2016 09:47:03 +0000 (+0200) Subject: priv: don't use monitor for ethtool except for old kernels X-Git-Tag: 0.9.5~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c98fe72dcd86ad11c6dec24bbaac64023cb4a59;p=thirdparty%2Flldpd.git priv: don't use monitor for ethtool except for old kernels Since 2.6.37, we don't need any privilege for ethtool GSET. Not using the monitor will increase performance. --- diff --git a/src/daemon/interfaces-linux.c b/src/daemon/interfaces-linux.c index 06423e03..28611de9 100644 --- a/src/daemon/interfaces-linux.c +++ b/src/daemon/interfaces-linux.c @@ -340,7 +340,7 @@ iflinux_macphy(struct lldpd_hardware *hardware) log_debug("interfaces", "ask ethtool for the appropriate MAC/PHY for %s", hardware->h_ifname); - if (priv_ethtool(hardware->h_ifname, ðc, sizeof(struct ethtool_cmd)) == 0) { + if (priv_ethtool(hardware->h_ifname, ðc) == 0) { port->p_macphy.autoneg_support = (ethc.supported & SUPPORTED_Autoneg) ? 1 : 0; port->p_macphy.autoneg_enabled = (ethc.autoneg == AUTONEG_DISABLE) ? 0 : 1; for (j=0; advertised_ethtool_to_rfc3636[j][0]; j++) { diff --git a/src/daemon/lldpd.h b/src/daemon/lldpd.h index 9eaf2c59..19091d2d 100644 --- a/src/daemon/lldpd.h +++ b/src/daemon/lldpd.h @@ -37,6 +37,10 @@ #include #include +#ifdef HOST_OS_LINUX +# include +#endif + #if HAVE_VFORK_H # include #endif @@ -55,6 +59,8 @@ # include "protocols/edp.h" #endif + + #include "../compat/compat.h" #include "../marshal.h" #include "../log.h" @@ -200,8 +206,10 @@ char *priv_gethostname(void); #ifdef HOST_OS_LINUX int priv_open(char*); void asroot_open(void); -int priv_ethtool(char*, void*, size_t); +int priv_ethtool(char*, struct ethtool_cmd*); +# ifdef ENABLE_OLDIES void asroot_ethtool(void); +# endif #endif int priv_iface_init(int, char *); int asroot_iface_init_os(int, char *, int *); diff --git a/src/daemon/priv-linux.c b/src/daemon/priv-linux.c index f550a0c7..a1f7e597 100644 --- a/src/daemon/priv-linux.c +++ b/src/daemon/priv-linux.c @@ -53,12 +53,33 @@ priv_open(char *file) return receive_fd(PRIV_UNPRIVILEGED); } +static int +asroot_ethtool_real(const char *ifname, struct ethtool_cmd *ethc) { + int rc, sock = -1; + struct ifreq ifr = { + .ifr_data = (caddr_t)ethc + }; + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + memset(ethc, 0, sizeof(struct ethtool_cmd)); + ethc->cmd = ETHTOOL_GSET; + if (((rc = sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) || + (rc = ioctl(sock, SIOCETHTOOL, &ifr)) != 0) { + if (sock != -1) close(sock); + return rc; + } + close(sock); + return rc; +} + /* Proxy for ethtool ioctl (GSET only). Not needed since - * 0fdc100bdc4b7ab61ed632962c76dfe539047296 (2.6.37) */ + * 0fdc100bdc4b7ab61ed632962c76dfe539047296 (2.6.37). */ int -priv_ethtool(char *ifname, void *ethc, size_t length) +priv_ethtool(char *ifname, struct ethtool_cmd *ethc) { - int rc, len; + int rc; +#ifdef ENABLE_OLDIES + int len; enum priv_cmd cmd = PRIV_ETHTOOL; must_write(PRIV_UNPRIVILEGED, &cmd, sizeof(enum priv_cmd)); len = strlen(ifname); @@ -68,7 +89,10 @@ priv_ethtool(char *ifname, void *ethc, size_t length) must_read(PRIV_UNPRIVILEGED, &rc, sizeof(int)); if (rc != 0) return rc; - must_read(PRIV_UNPRIVILEGED, ethc, length); + must_read(PRIV_UNPRIVILEGED, ethc, sizeof(struct ethtool_cmd)); +#else + rc = asroot_ethtool_real(ifname, ethc); +#endif return rc; } @@ -132,12 +156,12 @@ asroot_open() close(fd); } +#ifdef ENABLE_OLDIES void asroot_ethtool() { - struct ifreq ifr = {}; - struct ethtool_cmd ethc = {}; - int len, rc, sock = -1; + struct ethtool_cmd ethc; + int len, rc; char *ifname; must_read(PRIV_PRIVILEGED, &len, sizeof(int)); @@ -145,20 +169,13 @@ asroot_ethtool() fatal("privsep", NULL); must_read(PRIV_PRIVILEGED, ifname, len); ifname[len] = '\0'; - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + rc = asroot_ethtool_real(ifname, ðc); free(ifname); - ifr.ifr_data = (caddr_t)ðc; - ethc.cmd = ETHTOOL_GSET; - if (((rc = sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) || - (rc = ioctl(sock, SIOCETHTOOL, &ifr)) != 0) { - if (sock != -1) close(sock); - must_write(PRIV_PRIVILEGED, &rc, sizeof(int)); - return; - } - close(sock); must_write(PRIV_PRIVILEGED, &rc, sizeof(int)); + if (rc == -1) return; must_write(PRIV_PRIVILEGED, ðc, sizeof(struct ethtool_cmd)); } +#endif int asroot_iface_init_os(int ifindex, char *name, int *fd) diff --git a/src/daemon/priv.c b/src/daemon/priv.c index f03c90aa..1c37f326 100644 --- a/src/daemon/priv.c +++ b/src/daemon/priv.c @@ -387,7 +387,9 @@ static struct dispatch_actions actions[] = { {PRIV_GET_HOSTNAME, asroot_gethostname}, #ifdef HOST_OS_LINUX {PRIV_OPEN, asroot_open}, +# ifdef ENABLE_OLDIES {PRIV_ETHTOOL, asroot_ethtool}, +# endif #endif {PRIV_IFACE_INIT, asroot_iface_init}, {PRIV_IFACE_MULTICAST, asroot_iface_multicast},