From 3595c8eb578a60012e53515fabf24409b85dff47 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 20 Jul 2016 18:42:56 +0200 Subject: [PATCH] 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. --- .../upgrade/320-gluon-client-bridge-wireless | 2 +- .../luasrc/usr/lib/lua/gluon/util.lua | 65 ++++++++++++++++++- .../300-gluon-mesh-batman-adv-core-wan | 3 +- .../320-gluon-mesh-batman-adv-core-wireless | 4 +- ...340-gluon-mesh-batman-adv-core-mesh-on-lan | 2 +- .../lib/gluon/upgrade/400-mesh-vpn-fastd | 2 +- 6 files changed, 70 insertions(+), 8 deletions(-) diff --git a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless index 2f07f2b9..16b9db93 100755 --- a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless +++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless @@ -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 diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua index 76e3a828..b9e81b1f 100644 --- a/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua +++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua @@ -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. diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan index be96c012..eafadb71 100755 --- a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan @@ -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') - diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless index bcf1ca0e..e11d118a 100755 --- a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless @@ -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 diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan index 99ca4213..2cc0d989 100755 --- a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan @@ -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 diff --git a/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd index 77f2e6f2..6f2095f2 100755 --- a/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd +++ b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd @@ -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), } )