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 2f07f2b91c8fdef577ca93c998d5e6680437bc6a..16b9db9306283eaaaee63a116e627c3d8757d315 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 76e3a8282d2073210f1e6e10abe55139a965a69f..b9e81b1fef380deb3689918c2d3a8d81754757e8 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 be96c012be47bac2d2eb87246510b8cba835f824..eafadb7124d4fdc41dfe5d362f2cf951e20e3684 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 bcf1ca0e20682c48771717f85fcd4d942b3b3c5a..e11d118ab1756f82b6559e73097bec0ffb9f2407 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 99ca421323fcb523028a82f6823794ed17f48d45..2cc0d9896445d1582ea053b094bbd4e3c9cab8a0 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 77f2e6f291d590c1e411414c8e4b68b74112a409..6f2095f2f2bc404ab5b54c335a7a14a4b0bca059 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),
 	  }
 )