mac80211: rework mac address allocation
authorFelix Fietkau <nbd@openwrt.org>
Wed, 17 Apr 2013 15:36:57 +0000 (15:36 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 17 Apr 2013 15:36:57 +0000 (15:36 +0000)
If the first byte is available in the address mask, use only that one -
set the local bit and xor it with the id << 2. This ensures that there
are no hardware BSSID & BSSID-mask conflicts with devices that have
almost the same MAC address with just a small offset. The MAC address
conflict has been observed in a deployment with some devices from the
same batch when running with multiple interfaces.

If only some bits of the last byte are available, xor the id onto the
last MAC address byte (relevant mostly for Ralink devices).

In other cases (should not happen at this point), use the previous MAC
address offset calculation but without the local bit.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 36353

package/mac80211/files/lib/wifi/mac80211.sh

index 4c214e84c5f3ace8cb9ed75f75a119127ef1677a..bb972114281c995e13608dfc2111e1b17e5550eb 100644 (file)
@@ -270,19 +270,33 @@ get_freq() {
 }
 
 mac80211_generate_mac() {
-       local off="$1"
-       local mac="$2"
+       local id="$1"
+       local ref="$2"
        local mask="$3"
-       local oIFS="$IFS"; IFS=":"; set -- $mac; IFS="$oIFS"
 
-       local b2mask=0x00
-       [ $off -gt 0 ] &&
-               [ "$mask" = "00:00:00:00:00:00" -o $(( 0x${mask%%:*} & 0x2 )) -gt 0 ] && b2mask=0x02
+       [ "$mask" = "00:00:00:00:00:00" ] && mask="ff:ff:ff:ff:ff:ff";
+       local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
 
-       printf "%02x:%s:%s:%s:%02x:%02x" \
-               $(( 0x$1 | $b2mask )) $2 $3 $4 \
-               $(( (0x$5 + ($off / 0x100)) % 0x100 )) \
-               $(( (0x$6 + $off) % 0x100 ))
+       local mask1=$1
+       local mask6=$6
+
+       local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
+       [ "$((0x$mask1))" -gt 0 ] && {
+               b1=$(((0x$1 | 0x2) ^ ($id << 2)))
+               printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
+               return
+       }
+
+       [ "$((0x$mask6))" -lt 255 ] && {
+               printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
+               return
+       }
+
+       off2=$(( (0x$6 + $id) / 0x100 ))
+       printf "%s:%s:%s:%s:%02x:%02x" \
+               $1 $2 $3 $4 \
+               $(( (0x$5 + $off2) % 0x100 )) \
+               $(( (0x$6 + $id) % 0x100 ))
 }
 
 enable_mac80211() {