]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
priv: don't use monitor for ethtool except for old kernels
authorVincent Bernat <vincent@bernat.im>
Sun, 7 Aug 2016 09:47:03 +0000 (11:47 +0200)
committerVincent Bernat <vincent@bernat.im>
Sun, 7 Aug 2016 09:47:43 +0000 (11:47 +0200)
Since 2.6.37, we don't need any privilege for ethtool GSET. Not using
the monitor will increase performance.

src/daemon/interfaces-linux.c
src/daemon/lldpd.h
src/daemon/priv-linux.c
src/daemon/priv.c

index 06423e03178eb03eac0262dd94bd9e9fc3081ecf..28611de94c2faa12419899e199d80b94461b93ca 100644 (file)
@@ -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, &ethc, sizeof(struct ethtool_cmd)) == 0) {
+       if (priv_ethtool(hardware->h_ifname, &ethc) == 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++) {
index 9eaf2c5938b027fe6c625a0358e916556a071d81..19091d2db19812a00de6e770d6199319fea6d898 100644 (file)
 #include <netinet/in.h>
 #include <sys/un.h>
 
+#ifdef HOST_OS_LINUX
+# include <linux/ethtool.h>
+#endif
+
 #if HAVE_VFORK_H
 # include <vfork.h>
 #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 *);
index f550a0c79820f8774a6b899216f7ad208da6061e..a1f7e597343ec8736b69be9e94858d551dfc524c 100644 (file)
@@ -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, &ethc);
        free(ifname);
-       ifr.ifr_data = (caddr_t)&ethc;
-       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, &ethc, sizeof(struct ethtool_cmd));
 }
+#endif
 
 int
 asroot_iface_init_os(int ifindex, char *name, int *fd)
index f03c90aa1e30834ff6d03decbd7b940b64df1f23..1c37f32655ae5182af52eab11f8d913c703aeccd 100644 (file)
@@ -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},