diff --git a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/400-mesh-vpn b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
similarity index 61%
rename from package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/400-mesh-vpn
rename to package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
index 6ab719db337fb4ec6861357919fe94892ad2a2c6..6475d70a3739f272e072bc26126d1d3ad838e117 100755
--- a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/400-mesh-vpn
+++ b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
@@ -62,15 +62,36 @@ uci:save('firewall')
 
 -- VPN migration
 local has_fastd = fs.access('/lib/gluon/mesh-vpn/fastd')
-local fastd_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
+local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
 
 local has_tunneldigger = fs.access('/lib/gluon/mesh-vpn/tunneldigger')
-local tunneldigger_enabled = uci:get_bool("tunneldigger", "mesh_vpn", "enabled")
-
-local enabled = fastd_enabled or tunneldigger_enabled or false
+local tunneldigger_enabled = uci:get('tunneldigger', 'mesh_vpn', 'enabled')
+
+local enabled
+
+-- If the installed VPN package has its enabled state set, keep the value
+if has_fastd and fastd_enabled then
+	enabled = fastd_enabled == '1'
+elseif has_tunneldigger and tunneldigger_enabled then
+	enabled = tunneldigger_enabled == '1'
+-- Otherwise, migrate the other package's value if any is set
+elseif fastd_enabled or tunneldigger_enabled then
+	enabled = fastd_enabled == '1' or tunneldigger_enabled == '1'
+-- If nothing is set, use the default
+else
+	enabled = site.mesh_vpn.enabled or false
+end
 
-uci:set("fastd", "mesh_vpn", "enabled", has_fastd and enabled)
-uci:save("fastd")
+if has_fastd then
+	uci:set('fastd', 'mesh_vpn', 'enabled', enabled)
+else
+	uci:delete('fastd', 'mesh_vpn')
+end
+uci:save('fastd')
 
-uci:set("tunneldigger", "mesh_vpn", "enabled", has_tunneldigger and enabled)
-uci:save("tunneldigger")
+if has_tunneldigger then
+	uci:set('tunneldigger', 'mesh_vpn', 'enabled', enabled)
+else
+	uci:delete('tunneldigger', 'mesh_vpn')
+end
+uci:save('tunneldigger')
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 91e2d1fbf9274cb5a808218859473d5324812228..126dfefb65fbc0b4b954c28279035120f79539a2 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
@@ -6,11 +6,6 @@ local util = require 'gluon.util'
 local uci = require('simple-uci').cursor()
 
 
-local enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
-if enabled == nil then
-	enabled = site.mesh_vpn.enabled or false
-end
-
 local syslog_level = uci:get('fastd', 'mesh_vpn', 'syslog_level') or 'verbose'
 
 local methods
@@ -40,7 +35,6 @@ end
 
 
 uci:section('fastd', 'fastd', 'mesh_vpn', {
-	enabled = enabled,
 	group = 'gluon-mesh-vpn',
 	syslog_level = syslog_level,
 	interface = 'mesh-vpn',
diff --git a/package/gluon-mesh-vpn-tunneldigger/luasrc/lib/gluon/upgrade/400-mesh-vpn-tunneldigger b/package/gluon-mesh-vpn-tunneldigger/luasrc/lib/gluon/upgrade/400-mesh-vpn-tunneldigger
index 01500e52cf48d69784802adb2719be66280e3796..85d899c0448127fd7fb5753e3f9093a39fee5459 100755
--- a/package/gluon-mesh-vpn-tunneldigger/luasrc/lib/gluon/upgrade/400-mesh-vpn-tunneldigger
+++ b/package/gluon-mesh-vpn-tunneldigger/luasrc/lib/gluon/upgrade/400-mesh-vpn-tunneldigger
@@ -6,18 +6,17 @@ local util = require 'gluon.util'
 local uci = require('simple-uci').cursor()
 
 
-local enabled = uci:get('tunneldigger', 'mesh_vpn', 'enabled')
-if enabled == nil then
-	if uci:get_first('tunneldigger', 'broker', 'interface') == "mesh-vpn" then
+local enabled
+
+-- Delete old broker config section (remove in 2019)
+if not uci:get('tunneldigger', 'mesh_vpn') then
+	if uci:get_first('tunneldigger', 'broker', 'interface') == 'mesh-vpn' then
 		enabled = uci:get_first('tunneldigger', 'broker', 'enabled')
 	end
-end
-if enabled == nil then
-	enabled = site.mesh_vpn.enabled or false
-end
 
--- Delete old broker config section
-if not uci:get('tunneldigger', 'mesh_vpn') then
+	-- In the usual case (no migration from old tunneldigger package), the
+	-- enabled state is set in the 500-mesh-vpn script
+
 	uci:delete_all('tunneldigger', 'broker')
 end