diff --git a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac index 25c13bac..28a68b57 100755 --- a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac +++ b/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac @@ -10,8 +10,9 @@ end local platform = require 'gluon.platform' -local fs = require 'nixio.fs' +local sys = require 'luci.sys' local util = require 'luci.util' +local nixio = require 'nixio' local try_files = { @@ -32,9 +33,15 @@ end for _, file in ipairs(try_files) do - local addr = fs.readfile(file) + local addr = nixio.fs.readfile(file) if addr then + if platform.match('ramips', 'rt305x', {'vocore'}) then + -- Hash the mac address since we need to iterate in the last bits for + -- the VIF. (This chip uses a hardware mac filter) + addr = util.hash_mac(addr) + end + sysconfig.primary_mac = util.trim(addr) break end diff --git a/package/gluon-core/files/usr/lib/lua/gluon/util.lua b/package/gluon-core/files/usr/lib/lua/gluon/util.lua index d9df636f..8294b740 100644 --- a/package/gluon-core/files/usr/lib/lua/gluon/util.lua +++ b/package/gluon-core/files/usr/lib/lua/gluon/util.lua @@ -31,6 +31,7 @@ local table = table local nixio = require 'nixio' local sysconfig = require 'gluon.sysconfig' +local platform = require 'gluon.platform' local site = require 'gluon.site_config' local uci = require('luci.model.uci').cursor() @@ -83,10 +84,34 @@ end function generate_mac(f, i) local m1, m2, m3, m4, m5, m6 = string.match(sysconfig.primary_mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)') m1 = nixio.bit.bor(tonumber(m1, 16), 0x02) - m2 = (tonumber(m2, 16)+f) % 0x100 + m2 = tonumber(m2, 16) m3 = (tonumber(m3, 16)+i) % 0x100 + m6 = tonumber(m6, 16) - return string.format('%02x:%02x:%02x:%s:%s:%s', m1, m2, m3, m4, m5, m6) + if platform.match('ramips', 'rt305x', {'vocore'}) then + -- We need to iterate in the last byte, since the vocore does + -- hardware mac filtering on the wlan interface. + m6 = (m6+f) % 0x100 + else + m2 = (m2+f) % 0x100 + end + + return string.format('%02x:%02x:%02x:%s:%s:%02x', m1, m2, m3, m4, m5, m6) +end + +-- Generates a mac hashed from the original +-- The last three bits will be zeroed, since these bits are +-- iterated on some devices for the VIF. +function hash_mac(original) + local hashed = string.sub(sys.exec('echo -n "' .. original .. '" | sha512sum'),0,12) + local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)') + local m1 = nixio.bit.bor(tonumber(m1, 16), 0x02) + local m6 = nixio.bit.band(tonumber(m6, 16), 0xF8) -- zero the last three bits + -- It's necessary that the upper bits of the mac do + -- not vary on a single interface, since they are using + -- a hardware mac filter. (e.g 'ramips-rt305x') + + return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6) end -- Iterate over all radios defined in UCI calling