Setting Persistent MAC on BPI-R3

I have a number of devices running OpenWRT on the BPI-R3, all of which operate off of the eMMC. I use the MAC address to manage inventory on my side, but if the end user resets the device, it also resets the MAC address. This is problematic because I can no longer identify the device.

I've noticed that /sys/block/mmcblk0/device/cid contains an ID that is persistent for a device. I could derive a MAC address from it, but the /sys/class/net/eth0/address file is read-only, right? Also, I can't find where the random MAC address is set on the first boot after the reset. Any pointers on how I can write a custom MAC ID based on the eMMC ID would be appreciated.

I could do something like this:


cid=$(cat /sys/block/mmcblk0/device/cid)
mac_part=$(echo $cid | tail -c 13)
formatted_mac=$(echo $mac_part | sed 's/\(..\)/\1:/g;s/:$//')

And set the formatted_mac as eth0 mac in the uci-default script, but it seems kinda dirty because the other macs (wifi/etc) seem to be derived from the original eth0 mac (that was randomly generated)

I found a commit for the R3-Mini some time ago that mentioned that the random MAC address is derived and stored by U-Boot - I assume this matches the behavior of the R3, but I haven't checked that:

addr=$(cat /sys/class/net/eth0/address)

It's just getting the mac from that location isn't it? I'm curious to know what is setting the mac at /sys/class/net/eth0/address in the first place

Please read my message and the commit message - it's U-Boot, not Linux/OpenWrt that stores it!

Ah I somehow missed both the messages! Peeking at the u-boot code, it doesn't look like it's an easy way out in the u-boot code, I probably will have to resort to this script in a uci-default script:

if [ ! -f /sys/block/mmcblk0/device/cid ] || [ ! -s /sys/block/mmcblk0/device/cid ]; then
    echo "CID file mangled or missing"
    exit 1
    cid=$(cat /sys/block/mmcblk0/device/cid)

    if [ ${#cid} -ne 32 ]; then
        echo "Invalid CID length: ${#cid} characters. Expected 32 characters."
        exit 1

    mac_part=$(echo $cid | tail -c 13)
    formatted_mac=$(echo $mac_part | sed 's/\(..\)/\1:/g;s/:$//')

    set_or_add_mac_address() {
        local device=$1
        local mac=$2
        local index=$(uci show network | grep -oE "@device\[.*\].name='$device'" | cut -d'[' -f2 | cut -d']' -f1)
        if [ -n "$index" ]; then
            echo "Device $device already exists, setting MAC address at index $index."
            uci set network.@device[$index].macaddr="$mac"
            echo "Creating device $device and setting MAC address."
            uci add network device
            uci set network.@device[-1].name="$device"
            uci set network.@device[-1].macaddr="$mac"

    last_byte_dec=$(printf "%d" "0x$last_byte")

    new_last_byte_eth1=$(printf '%02X' $(( (last_byte_dec + 1) % 256 )))

    new_last_byte_wan=$(printf '%02X' $(( (last_byte_dec + 2) % 256 )))
    set_or_add_mac_address "eth0" "$formatted_mac"
    set_or_add_mac_address "eth1" "$mac_eth1"
    set_or_add_mac_address "wan" "$mac_wan"

    uci commit network
    /etc/init.d/network reload

I'm still not sure if it's a good idea or not