From 1a3ec37313fe6bd301dd4c08b8ddcc7aae7fe64d Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Tue, 1 Dec 2015 12:42:11 +0100 Subject: [PATCH] interfaces: use /proc/net/bonding as primary method --- NEWS | 2 +- src/daemon/interfaces-linux.c | 84 ++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/NEWS b/NEWS index bce629f3..0d2a8559 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,7 @@ lldpd (0.8.0) for "Best effort" to 0 to match 802.1D-2004. * Change: + Retrieve the permanent MAC address of an interface through - ethtool for Linux. Fallback to the old method when not available. + ethtool for Linux if /proc/net/bonding is not available. + Running lldpd with "-d" will keep the process in foreground but logs will still go to syslog. To log to the console, add at least one "-d". diff --git a/src/daemon/interfaces-linux.c b/src/daemon/interfaces-linux.c index 24805ca9..1e5ba9a4 100644 --- a/src/daemon/interfaces-linux.c +++ b/src/daemon/interfaces-linux.c @@ -231,8 +231,49 @@ iflinux_is_bond(struct lldpd *cfg, return 0; } +/* Get the permanent MAC address using ethtool as a fallback There is a slight + * difference with /proc/net/bonding method. The /proc/net/bonding method will + * retrieve the MAC address of the interface before it was added to the + * bond. The ethtool method will retrieve the real permanent MAC address. For + * some devices, there is no such address (for example, virtual devices like + * veth). */ static void -old_iflinux_get_permanent_mac(struct lldpd *cfg, +iflinux_get_permanent_mac_ethtool(struct lldpd *cfg, + struct interfaces_device_list *interfaces, + struct interfaces_device *iface) +{ + struct interfaces_device *master; + u_int8_t mac[ETHER_ADDR_LEN]; + + /* We could do that for any interface, but let's do that only for + * aggregates. */ + if ((master = iface->upper) == NULL || master->type != IFACE_BOND_T) + return; + + log_debug("interfaces", "get MAC address for %s", + iface->name); + + if (priv_iface_mac(iface->name, mac, ETHER_ADDR_LEN) != 0) { + log_warnx("interfaces", + "unable to get permanent MAC address for %s", + master->name); + return; + } + size_t i; + for (i = 0; i < ETHER_ADDR_LEN; i++) + if (mac[i] != 0) break; + if (i == ETHER_ADDR_LEN) { + log_warnx("interfaces", + "no permanent MAC address found for %s", + master->name); + return; + } + memcpy(iface->address, mac, + ETHER_ADDR_LEN); +} + +static void +iflinux_get_permanent_mac(struct lldpd *cfg, struct interfaces_device_list *interfaces, struct interfaces_device *iface) { @@ -263,9 +304,7 @@ old_iflinux_get_permanent_mac(struct lldpd *cfg, f = priv_open(path); } if (f < 0) { - log_warnx("interfaces", - "unable to find %s in /proc/net/bonding or /proc/self/net/bonding", - master->name); + iflinux_get_permanent_mac_ethtool(cfg, interfaces, iface); return; } if ((netbond = fdopen(f, "r")) == NULL) { @@ -318,43 +357,6 @@ old_iflinux_get_permanent_mac(struct lldpd *cfg, fclose(netbond); } -/* Get the permanent MAC address using ethtool. Fallback to /proc/net/bonding if - * not possible through ethtool. There is a slight difference between the two - * methods. The /proc/net/bonding method will retrieve the MAC address of the - * interface before it was added to the bond. The ethtool method will retrieve - * the real permanent MAC address. For some devices, there is no such address - * (for example, virtual devices like veth). */ -static void -iflinux_get_permanent_mac(struct lldpd *cfg, - struct interfaces_device_list *interfaces, - struct interfaces_device *iface) -{ - struct interfaces_device *master; - u_int8_t mac[ETHER_ADDR_LEN]; - - /* We could do that for any interface, but let's do that only for - * aggregates. */ - if ((master = iface->upper) == NULL || master->type != IFACE_BOND_T) - return; - - log_debug("interfaces", "get MAC address for %s", - iface->name); - - if (priv_iface_mac(iface->name, mac, ETHER_ADDR_LEN) != 0) { - old_iflinux_get_permanent_mac(cfg, interfaces, iface); - return; - } - size_t i; - for (i = 0; i < ETHER_ADDR_LEN; i++) - if (mac[i] != 0) break; - if (i == ETHER_ADDR_LEN) { - old_iflinux_get_permanent_mac(cfg, interfaces, iface); - return; - } - memcpy(iface->address, mac, - ETHER_ADDR_LEN); -} - /* Fill up MAC/PHY for a given hardware port */ static void iflinux_macphy(struct lldpd_hardware *hardware) -- 2.39.5