diff --git a/components/esp_hw_support/include/esp_mac.h b/components/esp_hw_support/include/esp_mac.h index 9d91d8cee4..0087c9a884 100644 --- a/components/esp_hw_support/include/esp_mac.h +++ b/components/esp_hw_support/include/esp_mac.h @@ -116,11 +116,12 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type); /** * @brief Derive local MAC address from universal MAC address. * - * This function derives a local MAC address from an universal MAC address. - * A `definition of local vs universal MAC address can be found on Wikipedia - * `. - * In ESP32, universal MAC address is generated from base MAC address in EFUSE or other external storage. - * Local MAC address is derived from the universal MAC address. + * This function copies a universal MAC address and then sets the U/L bit + * (bit 0x2) in the first octet, creating a locally administered MAC address. + * + * It's not recommended that the universal MAC address argument is already a + * locally administered MAC address, but in this case the first octet is XORed + * with 0x4 in order to create a different locally administered MAC address. * * @param local_mac Derived local MAC address, length: 6 bytes. * @param universal_mac Source universal MAC address, length: 6 bytes. diff --git a/components/esp_hw_support/mac_addr.c b/components/esp_hw_support/mac_addr.c index 81540b1129..81e80f5f3a 100644 --- a/components/esp_hw_support/mac_addr.c +++ b/components/esp_hw_support/mac_addr.c @@ -117,21 +117,20 @@ esp_err_t esp_efuse_mac_get_default(uint8_t* mac) esp_err_t esp_derive_local_mac(uint8_t* local_mac, const uint8_t* universal_mac) { - uint8_t idx; - if (local_mac == NULL || universal_mac == NULL) { ESP_LOGE(TAG, "mac address param is NULL"); return ESP_ERR_INVALID_ARG; } memcpy(local_mac, universal_mac, 6); - for (idx = 0; idx < 64; idx++) { - local_mac[0] = universal_mac[0] | 0x02; - local_mac[0] ^= idx << 2; - if (memcmp(local_mac, universal_mac, 6)) { - break; - } + const unsigned UL_BIT = 0x2; + local_mac[0] |= UL_BIT; + + if (local_mac[0] == universal_mac[0]) { + // universal_mac was already local, so flip this bit instead + // (this is kept to be compatible with the previous behaviour of this function) + local_mac[0] ^= 0x4; } return ESP_OK;