Bläddra i källkod

gluon-mesh-batman-adv: refactor interface management

We now create bat0 and primary0 independently of the lower mesh interfaces,
making the whole setup a lot more robust. In particular:

- we can't accidentially destroy primary0 because of concurrent setup and
  teardown runs of different interfaces
- bat0 will always exist, even when no mesh interfaces are up (e.g. no link
  on wired mesh)
- interfaces going down and up again will never tear down the whole of
  batman-adv
- we can enable and disable bat0 independently of the lower interface
  states
Matthias Schiffer 7 år sedan
förälder
incheckning
e45c30330d

+ 3 - 0
package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/post-setup.d/30-gluon-mesh-batman-adv

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+ubus call network.interface.gluon_bat0 renew

+ 11 - 1
package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv

@@ -1,3 +1,13 @@
 #!/bin/sh
 
-exec /lib/gluon/mesh-batman-adv/config_mesh_interface setup
+if [ "$FIXED_MTU" -eq 0 ]; then
+	# In case on VLAN on IBSS, first set MTU of the underlying interface
+	for lower in /sys/class/net/"$IFNAME"/lower_*/wireless; do
+		lower="${lower%%\/wireless}"
+		lower="${lower##*\/lower_}"
+		ip link set dev "$lower" mtu 1536
+		break
+	done
+
+	ip link set dev "$IFNAME" mtu 1532
+fi

+ 3 - 1
package/gluon-mesh-batman-adv/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv

@@ -1,3 +1,5 @@
 #!/bin/sh
 
-exec /lib/gluon/mesh-batman-adv/config_mesh_interface teardown
+lock /var/lock/gluon_bat0.lock
+(echo 'none' > "/sys/class/net/$IFNAME/batman_adv/mesh_iface") 2>/dev/null
+lock -u /var/lock/gluon_bat0.lock

+ 59 - 0
package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh

@@ -0,0 +1,59 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_gluon_bat0_init_config() {
+	no_device=1
+	available=1
+	renew_handler=1
+}
+
+proto_gluon_bat0_renew() {
+	local config="$1"
+
+	lock /var/lock/gluon_bat0.lock
+
+	local ifdump="$(ubus call network.interface dump)"
+
+	echo "$ifdump" | jsonfilter \
+		-e "@.interface[@.proto='gluon_mesh' && @.up=true]['device','data']" \
+	| while read dev; do
+		read data
+
+		echo bat0 > "/sys/class/net/$dev/batman_adv/mesh_iface"
+
+		! [ "$(echo "$data" | jsonfilter -e "@.transitive")" = 'true' ]
+		transitive=$?
+
+		(echo "$transitive" > "/sys/class/net/$dev/batman_adv/no_rebroadcast") 2>/dev/null
+	done
+
+	lock -u /var/lock/gluon_bat0.lock
+}
+
+proto_gluon_bat0_setup() {
+	local config="$1"
+
+	local primary0_mac="$(lua -lgluon.util -e 'print(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
+	echo bat0 > /sys/class/net/primary0/batman_adv/mesh_iface
+
+	proto_init_update primary0 1
+	proto_send_update "$config"
+
+	proto_gluon_bat0_renew "$1"
+}
+
+proto_gluon_bat0_teardown() {
+	local config="$1"
+
+	ip link del bat0
+	ip link del primary0
+}
+
+add_protocol gluon_bat0

+ 0 - 66
package/gluon-mesh-batman-adv/luasrc/lib/gluon/mesh-batman-adv/config_mesh_interface

@@ -1,66 +0,0 @@
-#!/usr/bin/lua
-
-local util = require 'gluon.util'
-local fs = require 'nixio.fs'
-
-
-local ifname = os.getenv('IFNAME')
-local cmd = arg[1]
-
-
-if cmd == 'setup' then
-
-	local fixed_mtu = tonumber(os.getenv('FIXED_MTU')) or 0
-	local transitive = tonumber(os.getenv('TRANSITIVE')) or 0
-
-	local mtu = 1532
-
-	if not fs.access('/sys/class/net/primary0') then
-		os.execute([[
-			ip link add primary0 type dummy
-			echo 1 > /proc/sys/net/ipv6/conf/primary0/disable_ipv6
-			ip link set primary0 address ]] .. util.generate_mac(3) .. [[ mtu ]] .. mtu .. [[ up
-			echo 'bat0' > /sys/class/net/primary0/batman_adv/mesh_iface
-		]])
-	end
-
-	if fixed_mtu == 0 then
-		local lower = fs.glob('/sys/class/net/' .. ifname .. '/lower_*/wireless')()
-		if lower then
-			lower = lower:match('/lower_([^/]+)/wireless$')
-			util.exec('ip', 'link', 'set', 'dev', lower, 'mtu', tostring(mtu+4))
-		end
-
-		util.exec('ip', 'link', 'set', 'dev', ifname, 'mtu', tostring(mtu))
-	end
-
-	local file = assert(io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w'))
-	file:write('bat0')
-	file:close()
-
-	file = io.open('/sys/class/net/' .. ifname .. '/batman_adv/no_rebroadcast', 'w')
-	if file then
-		file:write(tostring(transitive))
-		file:close()
-	end
-
-elseif cmd == 'teardown' then
-
-	local file = io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w')
-	if file then
-		file:write('none')
-		file:close()
-	end
-
-	local other = false
-	for lower in fs.glob('/sys/class/net/bat0/lower_*') do
-		if lower ~= '/sys/class/net/bat0/lower_primary0' then
-			other = true
-			break
-		end
-	end
-
-	if not other then
-		os.execute('ip link del primary0')
-	end
-end

+ 6 - 0
package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-mesh

@@ -22,10 +22,16 @@ uci:section('batman-adv', 'mesh', 'bat0', {
 })
 uci:save('batman-adv')
 
+uci:delete('network', 'gluon_bat0')
+uci:section('network', 'interface', 'gluon_bat0', {
+	proto = 'gluon_bat0',
+})
+
 uci:delete('network', 'bat0')
 uci:section('network', 'interface', 'bat0', {
 	ifname = 'bat0',
 	proto = 'none',
+	auto = true,
 	macaddr = sysconfig.primary_mac,
 	multicast_router = 2,
 	learning = false,