[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.
diff --git a/src/platform/Linux/ConfigurationManagerImpl.cpp b/src/platform/Linux/ConfigurationManagerImpl.cpp
index 90d0e78..e371095 100644
--- a/src/platform/Linux/ConfigurationManagerImpl.cpp
+++ b/src/platform/Linux/ConfigurationManagerImpl.cpp
@@ -129,31 +129,46 @@
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<size_t>(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<size_t>(mac->sll_halen, kExpectedBufMinSize));
+ }
+ else
{
error = CHIP_ERROR_NO_ENDPOINT;
}
+ freeifaddrs(addresses);
+
exit:
return error;
}