Skip to content
Snippets Groups Projects
Unverified Commit 2afe34ef authored by Matthias Schiffer's avatar Matthias Schiffer
Browse files

Use MAC addresses provided by WLAN drivers by default

Some drivers (mt76) don't support arbitrary MAC addresses. Use the
addresses provided by the driver (avoiding the primary address) by default,
but fall back to our has-based scheme when the driver doesn't provide
(enough) addresses.
parent c8bc4620
No related branches found
No related tags found
No related merge requests found
......@@ -25,7 +25,7 @@ local function configure_client(config, radio, index, suffix)
return
end
macaddr = util.generate_mac(3*(index-1))
macaddr = util.get_wlan_mac(radio, index, 1)
if not macaddr then
return
end
......
......@@ -23,6 +23,7 @@ local function escape_args(ret, arg0, ...)
end
local io = io
local os = os
local string = string
local tonumber = tonumber
......@@ -34,6 +35,8 @@ local hash = require 'hash'
local sysconfig = require 'gluon.sysconfig'
local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor()
local lutil = require 'luci.util'
local fs = require 'nixio.fs'
module 'gluon.util'
......@@ -71,6 +74,45 @@ function node_id()
return string.gsub(sysconfig.primary_mac, ':', '')
end
local function find_phy_by_path(path)
for phy in fs.glob('/sys/devices/' .. path .. '/ieee80211/phy*') do
return phy:match('([^/]+)$')
end
end
local function find_phy_by_macaddr(macaddr)
local addr = macaddr:lower()
for file in fs.glob('/sys/class/ieee80211/*/macaddress') do
if lutil.trim(fs.readfile(file)) == addr then
return file:match('([^/]+)/macaddress$')
end
end
end
local function find_phy(radio)
local config = uci:get_all('wireless', radio)
if not config or config.type ~= 'mac80211' then
return nil
elseif config.path then
return find_phy_by_path(config.path)
elseif config.macaddr then
return find_phy_by_macaddr(config.macaddr)
else
return nil
end
end
local function get_addresses(radio)
local phy = find_phy(radio)
if not phy then
return function() end
end
return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses')
end
-- Generates a (hopefully) unique MAC address
-- The parameter defines the ID to add to the mac addr
--
......@@ -83,7 +125,7 @@ end
-- 5: ibss1
-- 6: mesh-on-lan
-- 7: unused
function generate_mac(i)
local function generate_mac(i)
if i > 7 or i < 0 then return nil end -- max allowed id (0b111)
local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
......@@ -105,6 +147,27 @@ function generate_mac(i)
return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
end
function get_mac(index)
return generate_mac(3*(index-1))
end
function get_wlan_mac(radio, index, vif)
local primary = sysconfig.primary_mac:lower()
local i = 1
for addr in get_addresses(radio) do
if addr:lower() ~= primary then
if i == vif then
return addr
end
i = i + 1
end
end
return generate_mac(3*(index-1) + (vif-1))
end
-- Iterate over all radios defined in UCI calling
-- f(radio, index, site.wifiX) for each radio found while passing
-- site.wifi24 for 2.4 GHz devices and site.wifi5 for 5 GHz ones.
......
......@@ -5,6 +5,5 @@ local uci = require('luci.model.uci').cursor()
-- fix up duplicate mac addresses (for mesh-on-WAN)
uci:set('network', 'wan', 'macaddr', util.generate_mac(3))
uci:set('network', 'wan', 'macaddr', util.get_mac(2))
uci:save('network')
......@@ -33,7 +33,7 @@ local function configure_ibss(config, radio, index, suffix, disabled)
return
end
macaddr = util.generate_mac(3*(index-1)+2)
macaddr = util.get_wlan_mac(radio, index, 3)
if not macaddr then
return
end
......@@ -88,7 +88,7 @@ local function configure_mesh(config, radio, index, suffix, disabled)
return
end
macaddr = util.generate_mac(3*(index-1)+1)
macaddr = util.get_wlan_mac(radio, index, 2)
if not macaddr then
return
end
......
......@@ -18,7 +18,7 @@ uci:section('network', 'interface', 'mesh_lan', {
proto = 'batadv',
mesh = 'bat0',
mesh_no_rebroadcast = '1',
macaddr = util.generate_mac(6),
macaddr = util.get_mac(3),
})
if uci:get('network', 'mesh_lan', 'auto') == nil then
......
......@@ -127,7 +127,7 @@ uci:section('network', 'interface', 'mesh_vpn',
proto = 'batadv',
mesh = 'bat0',
mesh_no_rebroadcast = 1,
macaddr = util.generate_mac(0),
macaddr = util.get_mac(1),
}
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment