diff --git a/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh b/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh
index 8cbf3d14db4e39f3c021c6410166e9c08d67f92e..aaf9c908ea5a5e550ab0d067a6fe4be500d15cb4 100755
--- a/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh
+++ b/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh
@@ -8,6 +8,13 @@ proto_gluon_bat0_init_config() {
 	no_device=1
 	available=1
 	renew_handler=1
+
+	proto_config_add_string 'gw_mode'
+}
+
+lookup_site() {
+	local path="$1" default="$2"
+	lua -e "print(require('gluon.site').$path('$default'))"
 }
 
 proto_gluon_bat0_renew() {
@@ -36,16 +43,43 @@ proto_gluon_bat0_renew() {
 proto_gluon_bat0_setup() {
 	local config="$1"
 
+	local routing_algo=$(lookup_site 'mesh.batman_adv.routing_algo' 'BATMAN_IV')
+
+	local gw_mode
+	json_get_vars gw_mode
+
+	batctl routing_algo "$routing_algo"
+	batctl interface create
+
+	batctl orig_interval 5000
+	batctl hop_penalty 15
+	batctl multicast_mode 0
+
+	case "$gw_mode" in
+		server)
+			batctl gw_mode "server"
+		;;
+		client)
+			local gw_sel_class="$(lookup_site 'mesh.batman_adv.gw_sel_class')"
+			if [ -n "$gw_sel_class" ]; then
+				batctl gw_mode "client" "$gw_sel_class"
+			else
+				batctl gw_mode "client"
+			fi
+		;;
+		*)
+			batctl gw_mode "off"
+		;;
+	esac
+
+
 	local primary0_mac="$(lua -e 'print(require("gluon.util").generate_mac(3))')"
 
 	ip link add primary0 type dummy
 	echo 1 > /proc/sys/net/ipv6/conf/primary0/disable_ipv6
 	ip link set primary0 address "$primary0_mac" mtu 1532 up
 
-	local routing_algo="$(lua -e 'print(require("gluon.site").mesh.batman_adv.routing_algo())')"
-	(echo "$routing_algo" >/sys/module/batman_adv/parameters/routing_algo) 2>/dev/null
-
-	echo bat0 > /sys/class/net/primary0/batman_adv/mesh_iface
+	batctl interface add primary0
 
 	proto_init_update primary0 1
 	proto_send_update "$config"
@@ -56,7 +90,7 @@ proto_gluon_bat0_setup() {
 proto_gluon_bat0_teardown() {
 	local config="$1"
 
-	ip link del bat0
+	batctl interface destroy
 	ip link del primary0
 }
 
diff --git a/package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-mesh b/package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-mesh
index f021de2d1163513680965f96d429e06a6e626b0f..9ba1289fc7a26b70e8683e2f521e7a4d0df24b55 100755
--- a/package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-mesh
+++ b/package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-mesh
@@ -1,33 +1,23 @@
 #!/usr/bin/lua
 
 local sysconfig = require 'gluon.sysconfig'
-local site = require 'gluon.site'
 local util = require 'gluon.util'
 
 local uci = require('simple-uci').cursor()
 
 
-local gw_mode = uci:get('batman-adv', 'bat0', 'gw_mode') or 'client'
-local gw_sel_class = site.mesh.batman_adv.gw_sel_class()
-local routing_algo = site.mesh.batman_adv.routing_algo()
+local gw_mode = uci:get('network', 'gluon_bat0', 'gw_mode') or uci:get('network', 'bat0', 'gw_mode') or 'client'
 
 uci:delete('batman-adv-legacy', 'bat0')
 uci:save('batman-adv-legacy')
 
 uci:delete('batman-adv', 'bat0')
-uci:section('batman-adv', 'mesh', 'bat0', {
-	orig_interval = 5000,
-	gw_mode = gw_mode,
-	gw_sel_class = gw_sel_class,
-	hop_penalty = 15,
-	routing_algo = routing_algo,
-	multicast_mode = false,
-})
 uci:save('batman-adv')
 
 uci:delete('network', 'gluon_bat0')
 uci:section('network', 'interface', 'gluon_bat0', {
 	proto = 'gluon_bat0',
+	gw_mode = gw_mode,
 })
 
 uci:delete('network', 'bat0')