diff --git a/package/gluon-mesh-vpn-fastd/Makefile b/package/gluon-mesh-vpn-fastd/Makefile
index 27342dedc91c43b13884aee9fcfd8e14508a248f..3531b3b153724f68a11e3d5ecfd2e4847b064c46 100644
--- a/package/gluon-mesh-vpn-fastd/Makefile
+++ b/package/gluon-mesh-vpn-fastd/Makefile
@@ -1,8 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gluon-mesh-vpn-fastd
-PKG_VERSION:=1
-PKG_RELEASE:=1.$(GLUON_CONFIG_VERSION)
+PKG_VERSION:=2
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 
@@ -31,10 +30,6 @@ endef
 
 define Package/gluon-mesh-vpn-fastd/install
 	$(CP) ./files/* $(1)/
-
-	$(INSTALL_DIR) $(1)/lib/gluon/upgrade/mesh-vpn-fastd/invariant
-	$(GLUON_CONFIGURE) fastd.pl > $(1)/lib/gluon/upgrade/mesh-vpn-fastd/invariant/010-mesh-vpn-fastd
-	chmod +x $(1)/lib/gluon/upgrade/mesh-vpn-fastd/invariant/010-mesh-vpn-fastd
 endef
 
 $(eval $(call BuildPackage,gluon-mesh-vpn-fastd))
diff --git a/package/gluon-mesh-vpn-fastd/fastd.pl b/package/gluon-mesh-vpn-fastd/fastd.pl
deleted file mode 100644
index cc79f0a7b940163cf1e6546321ed530e06a9d008..0000000000000000000000000000000000000000
--- a/package/gluon-mesh-vpn-fastd/fastd.pl
+++ /dev/null
@@ -1,77 +0,0 @@
-my $cfg = $CONFIG->{fastd_mesh_vpn};
-my $backbone = $cfg->{backbone};
-
-my $add_methods = '';
-for (@{$cfg->{methods}}) {
-	$add_methods .= "uci add_list fastd.mesh_vpn.method='$_'\n";
-}
-
-my $set_peer_limit;
-if ($backbone->{limit}) {
-	$set_peer_limit = "uci_set fastd mesh_vpn_backbone peer_limit '$backbone->{limit}'\n";
-}
-else {
-	$set_peer_limit = "uci_remove fastd mesh_vpn_backbone peer_limit\n";
-}
-
-print <<END;
-#/bin/sh
-
-. /lib/functions.sh
-. /lib/gluon/functions/sysconfig.sh
-. /lib/gluon/functions/users.sh
-
-add_user gluon-fastd 800
-
-uci_add fastd fastd mesh_vpn
-
-uci_set fastd mesh_vpn user 'gluon-fastd'
-uci_set fastd mesh_vpn syslog_level 'verbose'
-uci_set fastd mesh_vpn interface 'mesh-vpn'
-uci_set fastd mesh_vpn mode 'tap'
-uci_set fastd mesh_vpn mtu '$cfg->{mtu}'
-uci_set fastd mesh_vpn secure_handshakes '1'
-
-uci_remove fastd mesh_vpn method
-$add_methods
-
-uci_remove fastd mesh_vpn_backbone
-uci_add fastd peer_group mesh_vpn_backbone
-uci_set fastd mesh_vpn_backbone enabled '1'
-uci_set fastd mesh_vpn_backbone net 'mesh_vpn'
-$set_peer_limit
-END
-
-foreach my $name (sort keys %{$backbone->{peers}}) {
-	my $peer = $backbone->{peers}->{$name};
-	print <<EOF;
-uci_remove fastd 'mesh_vpn_backbone_peer_$name'
-uci_add fastd peer 'mesh_vpn_backbone_peer_$name'
-uci_set fastd 'mesh_vpn_backbone_peer_$name' enabled '1'
-uci_set fastd 'mesh_vpn_backbone_peer_$name' net 'mesh_vpn'
-uci_set fastd 'mesh_vpn_backbone_peer_$name' group 'mesh_vpn_backbone'
-uci_set fastd 'mesh_vpn_backbone_peer_$name' key '$peer->{key}'
-EOF
-
-	for (@{$peer->{remotes}}) {
-		print "uci add_list fastd.mesh_vpn_backbone_peer_$name.remote='$_'\n";
-	}
-}
-
-print <<'END';
-
-uci_add network interface mesh_vpn
-uci_set network mesh_vpn ifname 'mesh-vpn'
-uci_set network mesh_vpn proto 'batadv'
-uci_set network mesh_vpn mesh 'bat0'
-uci_set network mesh_vpn mesh_no_rebroadcast '1'
-
-mainaddr=$(sysconfig primary_mac)
-oIFS="$IFS"; IFS=":"; set -- $mainaddr; IFS="$oIFS"
-b2mask=0x02
-vpnaddr=$(printf "%02x:%s:%s:%02x:%s:%s" $(( 0x$1 | $b2mask )) $2 $3 $(( (0x$4 + 1) % 0x100 )) $5 $6)
-uci_set network mesh_vpn macaddr "$vpnaddr"
-
-uci_commit fastd
-uci_commit network
-END
diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/mesh-vpn-fastd/invariant/010-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/mesh-vpn-fastd/invariant/010-mesh-vpn-fastd
new file mode 100755
index 0000000000000000000000000000000000000000..1d6d581125c15eeff61880f46fb6923f2033e1cd
--- /dev/null
+++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/mesh-vpn-fastd/invariant/010-mesh-vpn-fastd
@@ -0,0 +1,68 @@
+#!/usr/bin/lua
+
+local site = require 'gluon.site_config'
+local sysconfig = require 'gluon.sysconfig'
+local nixio = require 'nixio'
+local uci = require 'luci.model.uci'
+
+local c = uci.cursor()
+
+
+os.execute('. /lib/gluon/functions/users.sh && add_user gluon-fastd 800')
+
+
+c:section('fastd', 'fastd', 'mesh_vpn',
+	  {
+		  user = 'gluon-fastd',
+		  syslog_level = 'verbose',
+		  interface = 'mesh-vpn',
+		  mode = 'tap',
+		  mtu = site.fastd_mesh_vpn.mtu,
+		  secure_handshakes = '1',
+		  method = site.fastd_mesh_vpn.methods,
+	  }
+)
+
+c:delete('fastd', 'mesh_vpn_backbone')
+c:section('fastd', 'peer_group', 'mesh_vpn_backbone',
+	  {
+		  enabled = 1,
+		  net = 'mesh_vpn',
+		  peer_limit = site.fastd_mesh_vpn.backbone.limit,
+	  }
+)
+
+for name, config in pairs(site.fastd_mesh_vpn.backbone.peers) do
+	c:delete('fastd', 'mesh_vpn_backbone_peer_' .. name)
+	c:section('fastd', 'peer', 'mesh_vpn_backbone_peer_' .. name,
+		  {
+			  enabled = 1,
+			  net = 'mesh_vpn',
+			  group = 'mesh_vpn_backbone',
+			  key = config.key,
+			  remote = config.remotes,
+		  }
+	)
+end
+
+c:save('fastd')
+c:commit('fastd')
+
+
+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)
+m4 = (tonumber(m4, 16)+1) % 0x100
+local vpnaddr = string.format('%02x:%s:%s:%02x:%s:%s', m1, m2, m3, m4, m5, m6)
+
+c:section('network', 'interface', 'mesh_vpn',
+	  {
+		  ifname = 'mesh-vpn',
+		  proto = 'batadv',
+		  mesh = 'bat0',
+		  mesh_no_rebroadcast = 1,
+		  macaddr = vpnaddr,
+	  }
+)
+
+c:save('network')
+c:commit('network')