diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
index f4ad37a9c4454266d09967e341c26e9de236681a..7fce90149c142a1742446eb556c8676a62ff91e7 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
@@ -4,75 +4,136 @@ local sysconfig = require 'gluon.sysconfig'
 
 
 if sysconfig.primary_mac then
-  os.exit(0)
+	os.exit(0)
 end
 
 
-local util = require 'gluon.util'
 local platform = require 'gluon.platform'
+local util = require 'gluon.util'
 
 
-local try_files = {
-  '/sys/class/net/eth0/address'
-}
+local function sysfs(...)
+	local path = string.format(...)
+	return function()
+		local addr = util.readfile(path)
+		if addr then
+			return util.trim(addr)
+		end
+	end
+end
 
-if not (
-  util.contains({'x86', 'brcm2708'}, platform.get_target()) or
-  platform.match('ar71xx', 'mikrotik')
-) then
-  table.insert(try_files, 1, '/sys/class/ieee80211/phy0/macaddress')
+local function eth(index)
+	return sysfs('/sys/class/net/eth%d/address', index)
 end
 
-if platform.match('ar71xx', 'generic', {'tl-wdr3600', 'tl-wdr4300',
-                                        'tl-wr902ac-v1'}) then
-  table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
-elseif platform.match('ar71xx', 'generic', {'a40', 'a60',
-                                            'archer-c25-v1',
-                                            'archer-c60-v2',
-                                            'archer-c7-v4', 'archer-c7-v5',
-                                            'carambola2',
-                                            'koala',
-                                            'mr600', 'mr600v2',
-                                            'mr900', 'mr900v2',
-                                            'mr1750', 'mr1750v2',
-                                            'om2p', 'om2pv2', 'om2pv4',
-                                            'om2p-hs', 'om2p-hsv2', 'om2p-hsv3',
-                                            'om2p-hsv4',
-                                            'om2p-lc',
-                                            'om5p', 'om5p-an',
-                                            'om5p-ac', 'om5p-acv2',
-                                            'unifi-outdoor-plus',
-                                            'unifiac-lite', 'unifiac-pro'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('ar71xx', 'generic', {'archer-c5', 'archer-c58-v1',
-                                            'archer-c59-v1', 'archer-c60-v1',
-                                            'archer-c7'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth1/address')
-elseif platform.match('ar71xx', 'nand', {'hiveap-121'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('ath79', 'generic', {'ocedo,raccoon'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('ipq40xx', 'generic', {'avm,fritzbox-4040',
-                                             'openmesh,a42', 'openmesh,a62'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('ipq806x', 'generic', {'netgear,r7800'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth1/address')
-elseif platform.match('mpc85xx', 'p1020', {'aerohive,hiveap-330'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('mpc85xx', 'p1020', {'ocedo,panda'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth1/address')
-elseif platform.match('ramips', 'mt7620', {'miwifi-mini', 'tplink,c2-v1', 'c20-v1', 'c20i', 'c50'}) then
-  table.insert(try_files, 1, '/sys/class/net/eth0/address')
-elseif platform.match('ramips', 'mt7621', {'dir-860l-b1'}) then
-  table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
+local function phy(index)
+	return sysfs('/sys/class/ieee80211/phy%d/macaddress', index)
 end
 
 
-for _, file in ipairs(try_files) do
-  local addr = util.readfile(file)
+-- Entries are matched in the order they are listed
+local primary_addrs = {
+	{eth(0), {
+		{'x86'},
+		{'brcm2708'},
+		{'ar71xx', 'generic', {
+			'a40',
+			'a60',
+			'archer-c25-v1',
+			'archer-c60-v2',
+			'archer-c7-v4',
+			'archer-c7-v5',
+			'carambola2',
+			'koala',
+			'mr600',
+			'mr600v2',
+			'mr900',
+			'mr900v2',
+			'mr1750',
+			'mr1750v2',
+			'om2p',
+			'om2pv2',
+			'om2pv4',
+			'om2p-hs',
+			'om2p-hsv2',
+			'om2p-hsv3',
+			'om2p-hsv4',
+			'om2p-lc',
+			'om5p',
+			'om5p-an',
+			'om5p-ac',
+			'om5p-acv2',
+			'unifi-outdoor-plus',
+			'unifiac-lite',
+			'unifiac-pro',
+		}},
+		{'ar71xx', 'mikrotik'},
+		{'ar71xx', 'nand', {
+			'hiveap-121',
+		}},
+		{'ath79', 'generic', {
+			'ocedo,raccoon',
+		}},
+		{'ipq40xx', 'generic', {
+			'avm,fritzbox-4040',
+			'openmesh,a42',
+			'openmesh,a62',
+		}},
+		{'mpc85xx', 'p1020', {
+			'aerohive,hiveap-330',
+		}},
+		{'ramips', 'mt7620', {
+			'miwifi-mini', 'tplink,c2-v1', 'c20-v1', 'c20i', 'c50',
+		}},
+	}},
+	{eth(1), {
+		{'ar71xx', 'generic', {
+			'archer-c5',
+			'archer-c58-v1',
+			'archer-c59-v1',
+			'archer-c60-v1',
+			'archer-c7',
+		}},
+		{'ipq806x', 'generic', {
+			'netgear,r7800',
+		}},
+		{'mpc85xx', 'p1020', {
+			'ocedo,panda',
+		}},
+	}},
+	{phy(1), {
+		{'ar71xx', 'generic', {
+			'tl-wdr3600',
+			'tl-wdr4300',
+			'tl-wr902ac-v1',
+		}},
+		{'ramips', 'mt7621', {
+			'dir-860l-b1',
+		}},
+	}},
+	-- phy0 default
+	{phy(0), {
+		{}, -- matches everything
+	}},
+	-- eth0 fallback when phy0 does not exist
+	{eth(0), {
+		{}, -- matches everything
+	}},
+}
+
 
-  if addr then
-    sysconfig.primary_mac = util.trim(addr)
-    break
-  end
+for _, matcher in ipairs(primary_addrs) do
+	local f, matches = unpack(matcher)
+
+	for _, match in ipairs(matches) do
+		if platform.match(unpack(match)) then
+			local addr = f()
+			if addr then
+				sysconfig.primary_mac = addr
+				return
+			end
+		end
+	end
 end
+
+error('no primary MAC address found')
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
index a63e97cc7e620363ed2a8ace7770c680a4023372..41e06003354c2f5b287819818690c808a9003169 100644
--- a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
@@ -7,11 +7,11 @@ local M = setmetatable({}, {
 })
 
 function M.match(target, subtarget, boards)
-	if M.get_target() ~= target then
+	if target and M.get_target() ~= target then
 		return false
 	end
 
-	if M.get_subtarget() ~= subtarget then
+	if subtarget and M.get_subtarget() ~= subtarget then
 		return false
 	end