diff --git a/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless b/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless
index 8d5c7181f0e8f48dc3059c64a159bf85f13fbe4a..6fc8a72a51971126df9b2c0caf3cf0bc4abb9a8c 100755
--- a/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless
+++ b/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless
@@ -21,14 +21,16 @@ local function configure_client(config, radio, index, suffix)
 
   uci:delete('wireless', name)
 
-  if config then
+  macaddr = util.generate_mac(3*index)
+
+  if config and macaddr then
     uci:section('wireless', 'wifi-iface', name,
       {
         device = radio,
         network = 'client',
         mode = 'ap',
         ssid = config.ssid,
-        macaddr = util.generate_mac(2, index),
+        macaddr = macaddr,
         ifname = suffix and 'client' .. suffix,
         disabled = disabled,
       }
diff --git a/package/gluon-core/Makefile b/package/gluon-core/Makefile
index de54283ba7f993d436133b5bb585622f18d37dd5..725fb737517618ae95f894905f9ffbef8160a233 100644
--- a/package/gluon-core/Makefile
+++ b/package/gluon-core/Makefile
@@ -12,7 +12,7 @@ define Package/gluon-core
   SECTION:=gluon
   CATEGORY:=Gluon
   TITLE:=Base files of Gluon
-  DEPENDS:=+gluon-site +libgluonutil +lua-platform-info +luci-base +luci-lib-jsonc +odhcp6c +firewall
+  DEPENDS:=+gluon-site +libgluonutil +lua-platform-info +lua-hash +luci-base +luci-lib-jsonc +odhcp6c +firewall
 endef
 
 
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 d9df636f551df423ad3f91ee9d0cfd16fed189ce..72b6220d86f593a0ba6e07f81a28d763f5b9acbf 100644
--- a/package/gluon-core/files/usr/lib/lua/gluon/util.lua
+++ b/package/gluon-core/files/usr/lib/lua/gluon/util.lua
@@ -30,6 +30,7 @@ local ipairs = ipairs
 local table = table
 
 local nixio = require 'nixio'
+local hash = require 'hash'
 local sysconfig = require 'gluon.sysconfig'
 local site = require 'gluon.site_config'
 local uci = require('luci.model.uci').cursor()
@@ -71,22 +72,37 @@ function node_id()
 end
 
 -- Generates a (hopefully) unique MAC address
--- The first parameter defines the function and the second
--- parameter an ID to add to the MAC address
--- Functions and IDs defined so far:
--- (1, 0): WAN (for mesh-on-WAN)
--- (1, 1): LAN (for mesh-on-LAN)
--- (2, n): client interface for the n'th radio
--- (3, n): adhoc interface for n'th radio
--- (4, 0): mesh VPN
--- (5, n): mesh interface for n'th radio (802.11s)
-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
-  m3 = (tonumber(m3, 16)+i) % 0x100
-
-  return string.format('%02x:%02x:%02x:%s:%s:%s', m1, m2, m3, m4, m5, m6)
+-- The parameter defines the ID to add to the mac addr
+--
+-- IDs defined so far:
+-- 0: client0; mesh-vpn
+-- 1: mesh0
+-- 2: ibss0
+-- 3: client1; mesh-on-wan
+-- 4: mesh1
+-- 5: ibss1
+-- 6: mesh-on-lan
+-- 7: unused
+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)
+  local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)')
+
+  m1 = tonumber(m1, 16)
+  m6 = tonumber(m6, 16)
+
+  m1 = nixio.bit.bor(m1, 0x02)  -- set locally administered bit
+  m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
+
+  -- It's necessary that the first 45 bits of the mac do
+  -- not vary on a single hardware interface, since some chips are using
+  -- a hardware mac filter. (e.g 'ramips-rt305x')
+
+  m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
+  m6 = m6 + i                   -- add virtual interface id
+
+  return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
 end
 
 -- Iterate over all radios defined in UCI calling
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
index 00b1641472741357ee248b59ace36fb1e898e8ac..be96c012be47bac2d2eb87246510b8cba835f824 100755
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
+++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
@@ -5,6 +5,6 @@ local uci = require('luci.model.uci').cursor()
 
 
 -- fix up duplicate mac addresses (for mesh-on-WAN)
-uci:set('network', 'wan', 'macaddr', util.generate_mac(1, 0))
+uci:set('network', 'wan', 'macaddr', util.generate_mac(3))
 uci:save('network')
 
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
index a73912b863dadbe1934bc0e6597fa17579bd3ee7..05462c6fec2d7ae891f9e191329950a2416e1ff4 100755
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
+++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
@@ -29,7 +29,9 @@ local function configure_ibss(config, radio, index, suffix, disabled)
   uci:delete('network', name .. '_vlan')
   uci:delete('wireless', name)
 
-  if config then
+  macaddr = util.generate_mac(3*index+2)
+
+  if config and macaddr then
     if config.vlan then
       uci:section('network', 'interface', name,
         {
@@ -60,7 +62,7 @@ local function configure_ibss(config, radio, index, suffix, disabled)
         mode = 'adhoc',
         ssid = config.ssid,
         bssid = config.bssid,
-        macaddr = util.generate_mac(3, index),
+        macaddr = macaddr,
         mcast_rate = config.mcast_rate,
         ifname = suffix and 'ibss' .. suffix,
         disabled = disabled and 1 or 0,
@@ -77,7 +79,9 @@ local function configure_mesh(config, radio, index, suffix, disabled)
   uci:delete('network', name)
   uci:delete('wireless', name)
 
-  if config then
+  macaddr = util.generate_mac(3*index+1)
+
+  if config and macaddr then
     uci:section('network', 'interface', name,
       {
         proto = 'batadv',
@@ -92,7 +96,7 @@ local function configure_mesh(config, radio, index, suffix, disabled)
         mode = 'mesh',
         mesh_id = config.id,
         mesh_fwding = 0,
-        macaddr = util.generate_mac(5, index),
+        macaddr = macaddr,
         mcast_rate = config.mcast_rate,
         ifname = suffix and 'mesh' .. suffix,
         disabled = disabled and 1 or 0,
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan
index 27c1935bb66f0e92267e886566076a6e8af6055c..cbc9cd947a0e4526fad7b26af6a10c8444be4b33 100755
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan
+++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan
@@ -28,7 +28,7 @@ if sysconfig.lan_ifname and not uci:get('network', 'mesh_lan') then
               , proto   = 'batadv'
               , mesh    = 'bat0'
               , mesh_no_rebroadcast = '1'
-              , macaddr = util.generate_mac(1, 1)
+              , macaddr = util.generate_mac(6)
               , auto    = enable and 1 or 0
   })
 
diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd
index 902f1ccd25e4e1eb73f56590db76ba14b524e973..77f2e6f291d590c1e411414c8e4b68b74112a409 100755
--- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd
+++ b/package/gluon-mesh-vpn-fastd/files/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(4, 0),
+		  macaddr = util.generate_mac(0),
 	  }
 )