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) ...@@ -25,7 +25,7 @@ local function configure_client(config, radio, index, suffix)
return return
end end
macaddr = util.generate_mac(3*(index-1)) macaddr = util.get_wlan_mac(radio, index, 1)
if not macaddr then if not macaddr then
return return
end end
......
...@@ -23,6 +23,7 @@ local function escape_args(ret, arg0, ...) ...@@ -23,6 +23,7 @@ local function escape_args(ret, arg0, ...)
end end
local io = io
local os = os local os = os
local string = string local string = string
local tonumber = tonumber local tonumber = tonumber
...@@ -34,6 +35,8 @@ local hash = require 'hash' ...@@ -34,6 +35,8 @@ local hash = require 'hash'
local sysconfig = require 'gluon.sysconfig' local sysconfig = require 'gluon.sysconfig'
local site = require 'gluon.site_config' local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor() local uci = require('luci.model.uci').cursor()
local lutil = require 'luci.util'
local fs = require 'nixio.fs'
module 'gluon.util' module 'gluon.util'
...@@ -71,6 +74,45 @@ function node_id() ...@@ -71,6 +74,45 @@ function node_id()
return string.gsub(sysconfig.primary_mac, ':', '') return string.gsub(sysconfig.primary_mac, ':', '')
end 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 -- Generates a (hopefully) unique MAC address
-- The parameter defines the ID to add to the mac addr -- The parameter defines the ID to add to the mac addr
-- --
...@@ -83,7 +125,7 @@ end ...@@ -83,7 +125,7 @@ end
-- 5: ibss1 -- 5: ibss1
-- 6: mesh-on-lan -- 6: mesh-on-lan
-- 7: unused -- 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) 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) local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
...@@ -105,6 +147,27 @@ function generate_mac(i) ...@@ -105,6 +147,27 @@ function generate_mac(i)
return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6) return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
end 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 -- Iterate over all radios defined in UCI calling
-- f(radio, index, site.wifiX) for each radio found while passing -- 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. -- 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() ...@@ -5,6 +5,5 @@ local uci = require('luci.model.uci').cursor()
-- fix up duplicate mac addresses (for mesh-on-WAN) -- 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') uci:save('network')
...@@ -33,7 +33,7 @@ local function configure_ibss(config, radio, index, suffix, disabled) ...@@ -33,7 +33,7 @@ local function configure_ibss(config, radio, index, suffix, disabled)
return return
end end
macaddr = util.generate_mac(3*(index-1)+2) macaddr = util.get_wlan_mac(radio, index, 3)
if not macaddr then if not macaddr then
return return
end end
...@@ -88,7 +88,7 @@ local function configure_mesh(config, radio, index, suffix, disabled) ...@@ -88,7 +88,7 @@ local function configure_mesh(config, radio, index, suffix, disabled)
return return
end end
macaddr = util.generate_mac(3*(index-1)+1) macaddr = util.get_wlan_mac(radio, index, 2)
if not macaddr then if not macaddr then
return return
end end
......
...@@ -18,7 +18,7 @@ uci:section('network', 'interface', 'mesh_lan', { ...@@ -18,7 +18,7 @@ uci:section('network', 'interface', 'mesh_lan', {
proto = 'batadv', proto = 'batadv',
mesh = 'bat0', mesh = 'bat0',
mesh_no_rebroadcast = '1', mesh_no_rebroadcast = '1',
macaddr = util.generate_mac(6), macaddr = util.get_mac(3),
}) })
if uci:get('network', 'mesh_lan', 'auto') == nil then if uci:get('network', 'mesh_lan', 'auto') == nil then
......
...@@ -127,7 +127,7 @@ uci:section('network', 'interface', 'mesh_vpn', ...@@ -127,7 +127,7 @@ uci:section('network', 'interface', 'mesh_vpn',
proto = 'batadv', proto = 'batadv',
mesh = 'bat0', mesh = 'bat0',
mesh_no_rebroadcast = 1, 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