From 4a8f8ebb84529ce4d1d74782aabbf8ed9ce941e4 Mon Sep 17 00:00:00 2001 From: Peter Qiu <114182543+zqiu-nest@users.noreply.github.com> Date: Wed, 30 Nov 2022 03:32:25 -0500 Subject: [PATCH] [Linux] Prioritize interface matching for WiFi MAC address (#23813) Prefer interface matching the WiFi interface name when obtaining WiFi MAC address. Fallback to use first non-loopback interface if no match is found. --- .../Linux/ConfigurationManagerImpl.cpp | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/platform/Linux/ConfigurationManagerImpl.cpp b/src/platform/Linux/ConfigurationManagerImpl.cpp index 90d0e7817e46a3..e3710959e5a6f1 100644 --- a/src/platform/Linux/ConfigurationManagerImpl.cpp +++ b/src/platform/Linux/ConfigurationManagerImpl.cpp @@ -129,31 +129,46 @@ CHIP_ERROR ConfigurationManagerImpl::Init() CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf) { struct ifaddrs * addresses = nullptr; + struct sockaddr_ll * mac = nullptr; CHIP_ERROR error = CHIP_NO_ERROR; - bool found = false; // TODO: ideally the buffer size should have been passed as a span, however // for now use the size that is validated in GenericConfigurationManagerImpl.ipp constexpr size_t kExpectedBufMinSize = ConfigurationManager::kPrimaryMACAddressLength; memset(buf, 0, kExpectedBufMinSize); + // Prioritize address for interface matching the WiFi interface name + // specified in the config headers. Otherwise, use the address for the + // first non-loopback interface. VerifyOrExit(getifaddrs(&addresses) == 0, error = CHIP_ERROR_INTERNAL); for (auto addr = addresses; addr != nullptr; addr = addr->ifa_next) { - if ((addr->ifa_addr) && (addr->ifa_addr->sa_family == AF_PACKET) && strncmp(addr->ifa_name, "lo", IFNAMSIZ) != 0) + if ((addr->ifa_addr) && (addr->ifa_addr->sa_family == AF_PACKET)) { - struct sockaddr_ll * mac = (struct sockaddr_ll *) addr->ifa_addr; - memcpy(buf, mac->sll_addr, std::min(mac->sll_halen, kExpectedBufMinSize)); - found = true; - break; + if (strncmp(addr->ifa_name, CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME, IFNAMSIZ) == 0) + { + mac = (struct sockaddr_ll *) addr->ifa_addr; + break; + } + + if (strncmp(addr->ifa_name, "lo", IFNAMSIZ) != 0 && !mac) + { + mac = (struct sockaddr_ll *) addr->ifa_addr; + } } } - freeifaddrs(addresses); - if (!found) + + if (mac) + { + memcpy(buf, mac->sll_addr, std::min(mac->sll_halen, kExpectedBufMinSize)); + } + else { error = CHIP_ERROR_NO_ENDPOINT; } + freeifaddrs(addresses); + exit: return error; }