diff --git a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
index db753f763662751778e801572d5d63ae7c6a4e04..d10f2ea4fffc23bcf1867af5dd32fa4dd40cf4c5 100644
--- a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
+++ b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
@@ -24,54 +24,39 @@ return function(form, uci)
 	local o
 
 	local meshvpn = s:option(Flag, "meshvpn", pkg_i18n.translate("Use internet connection (mesh VPN)"))
-	meshvpn.default = uci:get_bool("fastd", "mesh_vpn", "enabled") or uci:get_bool("tunneldigger", "mesh_vpn", "enabled")
+	meshvpn.default = uci:get_bool("gluon", "mesh_vpn", "enabled")
 	function meshvpn:write(data)
-		if has_fastd then
-			uci:set("fastd", "mesh_vpn", "enabled", data)
-		end
-		if has_tunneldigger then
-			uci:set("tunneldigger", "mesh_vpn", "enabled", data)
-		end
+		uci:set("gluon", "mesh_vpn", "enabled", data)
 	end
 
 	local limit = s:option(Flag, "limit_enabled", pkg_i18n.translate("Limit bandwidth"))
 	limit:depends(meshvpn, true)
-	limit.default = uci:get_bool("simple-tc", "mesh_vpn", "enabled")
+	limit.default = uci:get_bool("gluon", "mesh_vpn", "limit_enabled")
 	function limit:write(data)
-		uci:set("simple-tc", "mesh_vpn", "interface")
-		uci:set("simple-tc", "mesh_vpn", "enabled", data)
-		uci:set("simple-tc", "mesh_vpn", "ifname", "mesh-vpn")
-		if not data and has_tunneldigger then
-			uci:delete("tunneldigger", "mesh_vpn", "limit_bw_down")
-		end
+		uci:set("gluon", "mesh_vpn", "limit_enabled", data)
 	end
 
 	o = s:option(Value, "limit_ingress", pkg_i18n.translate("Downstream (kbit/s)"))
 	o:depends(limit, true)
-	o.default = uci:get("simple-tc", "mesh_vpn", "limit_ingress")
-	if has_tunneldigger then
-		-- Check if limit_bw_down exists. If not, take the value from limit_ingress
-		local limit_bw_down = uci:get("tunneldigger", "mesh_vpn", "limit_bw_down")
-		if limit_bw_down ~= nil then
-			o.default = limit_bw_down
-		end
-	end
+	o.default = uci:get("gluon", "mesh_vpn", "limit_ingress")
 	o.datatype = "uinteger"
 	function o:write(data)
-		if has_tunneldigger then
-			uci:set("tunneldigger", "mesh_vpn", "limit_bw_down", data)
-		else
-			uci:set("simple-tc", "mesh_vpn", "limit_ingress", data)
-		end
+		uci:set("gluon", "mesh_vpn", "limit_ingress", data)
 	end
 
 	o = s:option(Value, "limit_egress", pkg_i18n.translate("Upstream (kbit/s)"))
 	o:depends(limit, true)
-	o.default = uci:get("simple-tc", "mesh_vpn", "limit_egress")
+	o.default = uci:get("gluon", "mesh_vpn", "limit_egress")
 	o.datatype = "uinteger"
 	function o:write(data)
-		uci:set("simple-tc", "mesh_vpn", "limit_egress", data)
+		uci:set("gluon", "mesh_vpn", "limit_egress", data)
+	end
+
+	function s:handle()
+		Section.handle(s)
+		uci:save('gluon')
+		os.execute('exec /lib/gluon/mesh-vpn/update-config')
 	end
 
-	return {'fastd', 'tunneldigger', 'simple-tc'}
+	return {'gluon', 'fastd', 'tunneldigger', 'simple-tc'}
 end
diff --git a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config
new file mode 100755
index 0000000000000000000000000000000000000000..45ecc2d5e3620c51dc64104cb225db74b7a14c8c
--- /dev/null
+++ b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config
@@ -0,0 +1,48 @@
+#!/usr/bin/lua
+
+local uci = require('simple-uci').cursor()
+local unistd = require 'posix.unistd'
+
+local vpn
+if unistd.access('/lib/gluon/mesh-vpn/fastd') then
+	vpn = 'fastd'
+elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
+	vpn = 'tunneldigger'
+end
+
+local vpn_config = {
+	enabled = uci:get_bool('gluon', 'mesh_vpn', 'enabled'),
+	limit_enabled = uci:get_bool('gluon', 'mesh_vpn', 'limit_enabled'),
+	limit_egress = uci:get('gluon', 'mesh_vpn', 'limit_egress'),
+	limit_ingress = uci:get('gluon', 'mesh_vpn', 'limit_ingress'),
+}
+
+uci:delete('simple-tc', 'mesh_vpn')
+uci:section('simple-tc', 'interface', 'mesh_vpn', {
+	ifname = 'mesh-vpn',
+	enabled = vpn_config.limit_enabled,
+	limit_egress = vpn_config.limit_egress,
+})
+
+if vpn == 'fastd' then
+	uci:set('fastd', 'mesh_vpn', 'enabled', vpn_config.enabled)
+	uci:set('simple-tc', 'mesh_vpn', 'limit_ingress', vpn_config.limit_ingress)
+else
+	uci:set('fastd', 'mesh_vpn', 'enabled', false)
+end
+uci:save('fastd')
+
+if vpn == 'tunneldigger' then
+	uci:set('tunneldigger', 'mesh_vpn', 'enabled', vpn_config.enabled)
+
+	if vpn_config.limit_enabled then
+		uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', vpn_config.limit_ingress)
+	else
+		uci:delete('tunneldigger', 'mesh_vpn', 'limit_bw_down')
+	end
+else
+	uci:set('tunneldigger', 'mesh_vpn', 'enabled', false)
+end
+uci:save('tunneldigger')
+
+uci:save('simple-tc')
diff --git a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
index 007645888704da5e982165db4c4ec263a471b0a2..019b9afbe10ed8d5b76f80660709accdfc1c559e 100755
--- a/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
+++ b/package/gluon-mesh-vpn-core/luasrc/lib/gluon/upgrade/500-mesh-vpn
@@ -20,21 +20,6 @@ uci:section('network', 'interface', 'mesh_vpn', {
 uci:save('network')
 
 
-if unistd.access('/etc/config/gluon-simple-tc') then
-	os.rename('/etc/config/gluon-simple-tc', '/etc/config/simple-tc')
-end
-
-if not uci:get('simple-tc', 'mesh_vpn') then
-	uci:section('simple-tc', 'interface', 'mesh_vpn', {
-		ifname = 'mesh-vpn',
-		enabled = site.mesh_vpn.bandwidth_limit.enabled(false),
-		limit_ingress = site.mesh_vpn.bandwidth_limit.ingress(),
-		limit_egress = site.mesh_vpn.bandwidth_limit.egress(),
-	})
-	uci:save('simple-tc')
-end
-
-
 -- The previously used user and group are removed, we now have a generic group
 users.remove_user('gluon-fastd')
 users.remove_group('gluon-fastd')
@@ -49,42 +34,59 @@ uci:save('firewall')
 
 
 -- VPN migration
-local has_fastd = unistd.access('/lib/gluon/mesh-vpn/fastd')
-local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
-
-local has_tunneldigger = unistd.access('/lib/gluon/mesh-vpn/tunneldigger')
-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(false)
-end
+if not uci:get('gluon', 'mesh_vpn') then
+	local vpn
+	if unistd.access('/lib/gluon/mesh-vpn/fastd') then
+		vpn = 'fastd'
+	elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
+		vpn = 'tunneldigger'
+	end
 
-if has_fastd then
-	uci:set('fastd', 'mesh_vpn', 'enabled', enabled)
-else
-	uci:delete('fastd', 'mesh_vpn')
-end
-uci:save('fastd')
-
-if has_tunneldigger then
-	uci:set('tunneldigger', 'mesh_vpn', 'enabled', enabled)
-	if site.mesh_vpn.bandwidth_limit.enabled(false) then
-		uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', site.mesh_vpn.bandwidth_limit.ingress())
-		uci:set('simple-tc', 'mesh_vpn', 'limit_ingress', 0)
-		uci:save('simple-tc')
+	local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
+	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 vpn == 'fastd' and fastd_enabled then
+		enabled = fastd_enabled == '1'
+	elseif vpn == '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(false)
 	end
-else
-	uci:delete('tunneldigger', 'mesh_vpn')
+
+
+	local limit_enabled = tonumber((uci:get('simple-tc', 'mesh_vpn', 'enabled')))
+	if limit_enabled == nil then
+		limit_enabled = site.mesh_vpn.bandwidth_limit.enabled(false)
+	end
+
+	local limit_ingress = tonumber((uci:get('tunneldigger', 'mesh_vpn', 'limit_bw_down')))
+	if limit_ingress == nil then
+		limit_ingress = tonumber((uci:get('simple-tc', 'mesh_vpn', 'limit_ingress')))
+	end
+	if limit_ingress == nil then
+		limit_ingress = site.mesh_vpn.bandwidth_limit.ingress()
+	end
+
+	local limit_egress = tonumber((uci:get('simple-tc', 'mesh_vpn', 'limit_egress')))
+	if limit_egress == nil then
+		limit_egress = site.mesh_vpn.bandwidth_limit.egress()
+	end
+
+
+	uci:section('gluon', 'mesh_vpn', 'mesh_vpn', {
+		enabled = enabled,
+		limit_enabled = limit_enabled,
+		limit_ingress = limit_ingress,
+		limit_egress = limit_egress,
+	})
+	uci:save('gluon')
 end
-uci:save('tunneldigger')
+
+os.execute('exec /lib/gluon/mesh-vpn/update-config')