+/**
+ * Get permanent MAC from ethtool.
+ *
+ * Return 0 on success, -1 on error.
+ */
+static int
+iflinux_get_permanent_mac_ethtool(struct lldpd *cfg,
+ struct interfaces_device_list *interfaces,
+ struct interfaces_device *iface)
+{
+ struct ifreq ifr = {};
+ union {
+ struct ethtool_perm_addr addr;
+ /* cppcheck-suppress unusedStructMember */
+ char u8[sizeof(struct ethtool_perm_addr) + ETHER_ADDR_LEN];
+ } epaddr;
+
+ strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
+ epaddr.addr.cmd = ETHTOOL_GPERMADDR;
+ epaddr.addr.size = ETHER_ADDR_LEN;
+ ifr.ifr_data = (caddr_t)&epaddr.addr;
+ if (ioctl(cfg->g_sock, SIOCETHTOOL, &ifr) == -1) {
+ static int once = 0;
+ if (errno == EPERM && !once) {
+ log_warn("interfaces",
+ "no permission to get permanent MAC address for %s (requires 2.6.19+)",
+ iface->name);
+ once = 1;
+ return -1;
+ }
+ if (errno != EPERM)
+ log_warnx("interfaces", "cannot get permanent MAC address for %s",
+ iface->name);
+ return -1;
+ }
+ if (epaddr.addr.data[0] != 0 ||
+ epaddr.addr.data[1] != 0 ||
+ epaddr.addr.data[2] != 0 ||
+ epaddr.addr.data[3] != 0 ||
+ epaddr.addr.data[4] != 0 ||
+ epaddr.addr.data[5] != 0 ||
+ epaddr.addr.data[6] != 0) {
+ memcpy(iface->address, epaddr.addr.data, ETHER_ADDR_LEN);
+ return 0;
+ }
+ log_debug("interfaces", "cannot get permanent MAC for %s", iface->name);
+ return -1;
+}
+
+/**
+ * Get permanent MAC address for a bond device.
+ */