[PATCH v3 2/4] fff-hoods/fff-wireless: Reconfigure instead of delete and create

Adrian Schmutzler freifunk at adrianschmutzler.de
So Jun 16 16:23:24 CEST 2019


Previously, when configurehood switched status, all WiFi devices
were completely rewritten and all interfaces were deleted and
recreated. This is both unnecessary and ugly.

This patch redesigns WiFi setup to create all interfaces (in
parallel) initially, and then only to enable/disable them as
necessary. Where reconfiguration is necessary, only the variable
parts are changed.

Since most of the wifi-device config is already created by
OpenWrt, this builds based on the existing wifi-devices and
only removes the default wifi-ifaces.

This patch will not change the logic (codeflow) of configurehood,
but only affects how action on the WiFi devices/interfaces is
taken.

Signed-off-by: Adrian Schmutzler <freifunk at adrianschmutzler.de>

---

Changes in v2:
- Move w2sta to fff-hoods packages (so fff-wireless can be used
  by gateway firmware)
- Build based on existing OpenWrt config

Changes in v3:
- Rebased to directly apply onto master
- Enable wXap and wXmesh by default (required for old configurenetwork)
- Fix configap uci name in hoodfile function
- Move removal of -q to separate patch
---
 src/packages/fff/fff-hoods/Makefile                |   3 +-
 .../fff-hoods/files/etc/uci-defaults/24c-fff-wXsta |  27 +++
 .../fff-hoods/files/usr/lib/functions/fff/hoodfile |  37 ++--
 .../fff/fff-hoods/files/usr/sbin/configurehood     |  90 ++++-----
 src/packages/fff/fff-wireless/Makefile             |   2 +-
 .../fff/fff-wireless/files/etc/config/wireless     |   0
 .../files/etc/uci-defaults/60-fff-wireless         |  96 ++++++---
 .../fff-wireless/files/lib/functions/fff/wireless  | 218 +--------------------
 8 files changed, 168 insertions(+), 305 deletions(-)
 create mode 100644 src/packages/fff/fff-hoods/files/etc/uci-defaults/24c-fff-wXsta
 delete mode 100644 src/packages/fff/fff-wireless/files/etc/config/wireless

diff --git a/src/packages/fff/fff-hoods/Makefile b/src/packages/fff/fff-hoods/Makefile
index f1a62896..9d0e6786 100644
--- a/src/packages/fff/fff-hoods/Makefile
+++ b/src/packages/fff/fff-hoods/Makefile
@@ -1,8 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=fff-hoods
-PKG_VERSION:=5
-PKG_RELEASE:=1
+PKG_RELEASE:=6
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
 
diff --git a/src/packages/fff/fff-hoods/files/etc/uci-defaults/24c-fff-wXsta b/src/packages/fff/fff-hoods/files/etc/uci-defaults/24c-fff-wXsta
new file mode 100644
index 00000000..e9867b98
--- /dev/null
+++ b/src/packages/fff/fff-hoods/files/etc/uci-defaults/24c-fff-wXsta
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. /lib/functions/fff/wireless
+
+# Set up wXsta
+for radio in $(wifiListRadio); do
+	# wXsta: We can use $freq here, as the initial radios are not set up with auto
+	freq="$(wifiGetFreq $radio)"
+
+	uci batch <<-__EOF__
+		set network.configsta${freq}=interface
+		set network.configsta${freq}.proto='static'
+
+		set wireless.w${freq}sta='wifi-iface'
+		set wireless.w${freq}sta.device='${radio}'
+		set wireless.w${freq}sta.network='configsta${freq}'
+		set wireless.w${freq}sta.ifname='w${freq}sta'
+		set wireless.w${freq}sta.mode='sta'
+		set wireless.w${freq}sta.ssid='config.franken.freifunk.net'
+		set wireless.w${freq}sta.disabled='1'
+	__EOF__
+done
+
+uci commit network
+uci commit wireless
+
+# vim: set noexpandtab:tabstop=4
diff --git a/src/packages/fff/fff-hoods/files/usr/lib/functions/fff/hoodfile b/src/packages/fff/fff-hoods/files/usr/lib/functions/fff/hoodfile
index d4a9ecb2..9bc6a35d 100644
--- a/src/packages/fff/fff-hoods/files/usr/lib/functions/fff/hoodfile
+++ b/src/packages/fff/fff-hoods/files/usr/lib/functions/fff/hoodfile
@@ -13,33 +13,20 @@ getWirelessHoodfile() {
 
 	# only change temporarily
 
-	if ! wifiDelIface; then
-		echo "Can't delete current wifi setup"
-		exit 1
-	fi
-	#now we look for phy and add this
-	for phy in $(iw phy | awk '/^Wiphy/{ print $2 }'); do
-		radio="$(wifiAddPhyCond "$phy" "2" "auto")"
-		radio5="$(wifiAddPhyCond "$phy" "5" "auto5")"
-		if [ -n "$radio5" ] ; then
-			radio="$radio5"
-			staiface="w5sta"
-		else
-			staiface="w2sta"
-		fi
-
-		#and here we add the station
-		if ! wifiAddSta "$radio" "config.franken.freifunk.net" "configSta" "$staiface" ; then
-			echo "Can't add Sta interface on $radio."
-			exit 1
-		else
-			uci -q set network.configSta=interface
-			uci -q set network.configSta.proto='static'
-			uci -q commit network
-			reload_config
-		fi
+	# Set channel to auto, enable wXsta, disable other interfaces
+	for radio in $(wifiListRadio); do
+		uci set "wireless.${radio}.channel=auto"
+
+		freq="$(wifiGetFreq $radio)"
+		uci set wireless.w${freq}ap.disabled='1'
+		uci set wireless.w${freq}mesh.disabled='1'
+		uci set wireless.w${freq}configap.disabled='1'
+		uci set wireless.w${freq}sta.disabled='0'
 	done
 
+	uci commit wireless
+	reload_config
+
 	wifi
 	# wait a moment to start the interface
 	sleep 10;
diff --git a/src/packages/fff/fff-hoods/files/usr/sbin/configurehood b/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
index 0df41887..4b85ae46 100755
--- a/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
+++ b/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
@@ -46,27 +46,17 @@ hasInternet() {
 
 if [ -s "$hoodfilewww" ] && isGatewayAvailable ; then
 	needwifi="0"
-	for radio in $(uci show wireless | sed -n 's,.*\.\([a-z0-9]*\)=wifi-device,\1,p'); do
-		freq="2"
-		if [ "$(uci get "wireless.${radio}.channel")" -gt "14" ]; then
-			freq="5"
-		fi
+	for radio in $(wifiListRadio); do
+		freq="$(wifiGetFreq $radio)"
+
 		# Break: wXconfig is up
-		uci -q get "wireless.w${freq}configap" > /dev/null && continue
+		[ "$(uci get "wireless.w${freq}configap.disabled")" = "0" ] && continue
 		# Break: No mesh interface
-		uci -q get "wireless.w${freq}mesh" > /dev/null || continue
+		[ "$(uci get "wireless.w${freq}mesh.disabled")" = "0" ] || continue
 		
-		# Create configap
-		iface="configap$freq"
-		uci set network.${iface}=interface
-		uci set network.${iface}.proto='static'
-		uci set network.${iface}.ip6addr='fe80::1/64'
-		uci commit network
-		reload_config
-		if ! wifiAddAP "$radio" "config.franken.freifunk.net" "$iface" "configap" "1"; then
-			echo "Can't add Config interface on $radio."
-			exit 1
-		fi
+		# Enable configap
+		uci set wireless.w${freq}configap.disabled='0'
+		uci commit wireless
 		needwifi="1"
 	done
 
@@ -157,38 +147,50 @@ if [ -s "$hoodfiletmp" ]; then
 		uci -q commit system
 		reload_config
 
-		if ! wifiDelIface; then
-			echo "Can't delete current wifi setup"
-			exit 1
-		fi
-
-		for phy in $(iw phy | awk '/^Wiphy/{ print $2 }'); do
-			radio="$(wifiAddPhyCond "$phy" "2" "$chan2ghz")"
-			radio5="$(wifiAddPhyCond "$phy" "5" "$chan5ghz")"
-			[ -n "$radio5" ] && radio="$radio5"
-
-			if ! wifiAddAP "$radio" "$essid" "mesh" "ap" "0"; then
-				echo "Can't add AP interface on $radio."
-				exit 1
-			fi
+		for radio in $(wifiListRadio); do
+			freq="$(wifiGetFreq $radio)"
 
-			# add 802.11s mesh if type = "802.11s"
-			if ( [ -n "$radio5" ] && [ "$mesh_type5" = "802.11s" ] ) || [ "$mesh_type2" = "802.11s" ]; then
-				if ! wifiAddMesh "$radio" "$mesh_id"; then
-					echo "Can't add Mesh interface on $radio."
-					exit 1
-				fi
+			if [ "$freq" = "5" ]; then
+				uci set wireless.${radio}.channel="$chan5ghz"
+				mesh_type="$mesh_type5"
+			elif [ "$freq" = "2" ]; then
+				uci set wireless.${radio}.channel="$chan2ghz"
+				mesh_type="$mesh_type2"
 			fi
 
-			# add IBSS mesh if type = "ibss"
-			if ( [ -n "$radio5" ] && [ "$mesh_type5" = "ibss" ] ) || [ "$mesh_type2" = "ibss" ]; then
-				if ! wifiAddAdHocMesh "$radio" "$mesh_essid" "$mesh_bssid"; then
-					echo "Can't add AdHocMesh interface on $radio."
-					exit 1
-				fi
+			# Disable wXsta, wXconfigap
+			uci set wireless.w${freq}sta.disabled='1'
+			uci set wireless.w${freq}configap.disabled='1'
+
+			# Configure wXap
+			uci set wireless.w${freq}ap.ssid="$essid"
+			uci set wireless.w${freq}ap.disabled='0'
+
+			# Configure 802.11s mesh if type = "802.11s"
+			if [ "$mesh_type" = "802.11s" ]; then
+				uci set wireless.w${freq}mesh.mode='mesh'
+				uci -q del wireless.w${freq}mesh.bssid
+				uci -q del wireless.w${freq}mesh.ssid
+				uci -q del wireless.w${freq}mesh.mcast_rate
+				uci set wireless.w${freq}mesh.mesh_id="$mesh_id"
+				uci set wireless.w${freq}mesh.mesh_fwding='0'
+				uci set wireless.w${freq}mesh.disabled='0'
+			# Configure IBSS mesh if type = "ibss"
+			elif [ "$mesh_type" = "ibss" ]; then
+				uci set wireless.w${freq}mesh.mode='adhoc'
+				uci -q del wireless.w${freq}mesh.mesh_id
+				uci -q del wireless.w${freq}mesh.mesh_fwding
+				uci set wireless.w${freq}mesh.bssid="$mesh_bssid"
+				uci set wireless.w${freq}mesh.ssid="$mesh_essid"
+				uci set wireless.w${freq}mesh.mcast_rate='6000'
+				uci set wireless.w${freq}mesh.disabled='0'
+			# Disable mesh by setting no mesh_type
+			else
+				uci set wireless.w${freq}mesh.disabled='1'
 			fi
 		done
 
+		uci commit wireless
 		echo "Loading wifi"
 		wifi
 
diff --git a/src/packages/fff/fff-wireless/Makefile b/src/packages/fff/fff-wireless/Makefile
index 6c0b6a9b..9b7b4d3f 100644
--- a/src/packages/fff/fff-wireless/Makefile
+++ b/src/packages/fff/fff-wireless/Makefile
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=fff-wireless
-PKG_RELEASE:=8
+PKG_RELEASE:=9
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
 
diff --git a/src/packages/fff/fff-wireless/files/etc/config/wireless b/src/packages/fff/fff-wireless/files/etc/config/wireless
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/packages/fff/fff-wireless/files/etc/uci-defaults/60-fff-wireless b/src/packages/fff/fff-wireless/files/etc/uci-defaults/60-fff-wireless
index 7e2fcf97..e0c4a14b 100644
--- a/src/packages/fff/fff-wireless/files/etc/uci-defaults/60-fff-wireless
+++ b/src/packages/fff/fff-wireless/files/etc/uci-defaults/60-fff-wireless
@@ -1,32 +1,80 @@
 #!/bin/sh
 # Copyright 2016 Tim Niemeyer
+# Copyright 2019 Adrian Schmutzler
 # License GPLv3
 
+. /lib/functions.sh
 . /lib/functions/fff/wireless
 
-if ! wifiDelAll; then
-	echo "Can't delete current wifi setup"
-	exit 1
-fi
-
-for phy in $(iw phy | awk '/^Wiphy/{ print $2 }'); do
-	radio="$(wifiAddPhyCond "$phy" "2" "1")"
-	radio5="$(wifiAddPhyCond "$phy" "5" "36")"
-	[ -n "$radio5" ] && radio="$radio5"
-	if [ -z "$radio" ] ; then
-		echo "Can't create radio for $phy"
-		exit 1
-	fi
-
-	if ! wifiAddAP "$radio" "do.not.use" "mesh" "ap" "0" ; then
-		echo "Can't add AP interface on $radio."
-		exit 1
-	fi
-
-	if ! wifiAddMesh "$radio" "mesh.do.not.use" ; then
-		echo "Can't add Mesh interface on $radio."
-		exit 1
-	fi
-done
+removeWifiIface() {
+	local name="$1"
+	uci del "wireless.$name"
+}
+
+configWifiDevice() {
+	local radio="$1"
+	local freq="$(wifiGetFreq $radio)"
+
+	[ "$freq" = "2" ] && uci set "wireless.${radio}.legacy_rates=0"
+
+	# Comments
+	# wXmesh: use 802.11s mesh as "default"
+
+	uci batch <<-__EOF__
+		set wireless.${radio}.htmode='HT20'
+		set wireless.${radio}.country='DE'
+		set wireless.${radio}.disabled='0'
+
+		set wireless.w${freq}ap='wifi-iface'
+		set wireless.w${freq}ap.device='${radio}'
+		set wireless.w${freq}ap.network='mesh'
+		set wireless.w${freq}ap.ifname='w${freq}ap'
+		set wireless.w${freq}ap.mode='ap'
+		set wireless.w${freq}ap.ssid='noservice.freifunk'
+		set wireless.w${freq}ap.encryption='none'
+		set wireless.w${freq}ap.hidden='0'
+		set wireless.w${freq}ap.disabled='0'
+
+		set network.w${freq}mesh='interface'
+		set network.w${freq}mesh.mtu='1560'
+		set network.w${freq}mesh.proto='batadv'
+		set network.w${freq}mesh.mesh='bat0'
+
+		set wireless.w${freq}mesh='wifi-iface'
+		set wireless.w${freq}mesh.device='${radio}'
+		set wireless.w${freq}mesh.network='w${freq}mesh'
+		set wireless.w${freq}mesh.ifname='w${freq}mesh'
+		set wireless.w${freq}mesh.mode='mesh'
+		set wireless.w${freq}mesh.mesh_id='nomesh.freifunk'
+		set wireless.w${freq}mesh.encryption='none'
+		set wireless.w${freq}mesh.mesh_fwding=0
+		set wireless.w${freq}mesh.disabled='0'
+
+		set network.configap${freq}=interface
+		set network.configap${freq}.proto='static'
+		set network.configap${freq}.ip6addr='fe80::1/64'
+
+		set wireless.w${freq}configap='wifi-iface'
+		set wireless.w${freq}configap.device='${radio}'
+		set wireless.w${freq}configap.network='configap${freq}'
+		set wireless.w${freq}configap.ifname='w${freq}configap'
+		set wireless.w${freq}configap.mode='ap'
+		set wireless.w${freq}configap.ssid='config.franken.freifunk.net'
+		set wireless.w${freq}configap.encryption='none'
+		set wireless.w${freq}configap.hidden='1'
+		set wireless.w${freq}configap.disabled='1'
+	__EOF__
+}
+
+# Remove WiFi config
+config_load wireless
+config_foreach removeWifiIface wifi-iface
+
+# Set up WiFi devices and interfaces, but leave the latter disabled
+config_load wireless
+config_foreach configWifiDevice wifi-device
+
+uci commit network
+uci commit wireless
 
 # vim: set noexpandtab:tabstop=4
diff --git a/src/packages/fff/fff-wireless/files/lib/functions/fff/wireless b/src/packages/fff/fff-wireless/files/lib/functions/fff/wireless
index ae16d2d2..c531e077 100644
--- a/src/packages/fff/fff-wireless/files/lib/functions/fff/wireless
+++ b/src/packages/fff/fff-wireless/files/lib/functions/fff/wireless
@@ -1,229 +1,29 @@
 # Copyright 2016 Tim Niemeyer
 # License GPLv3
 
-wifiDelAll() {
+wifiListRadio() {
 	if [ $# -ne "0" ]
 	then
-		echo "Usage: wifiDelAll"
+		echo "Usage: wifiListRadio"
 		return 1
 	fi
 
-	> /etc/config/wireless
-
-	return 0
-}
-
-wifiDelIface() {
-	if [ $# -ne "0" ]
-	then
-		echo "Usage: wifiDelIface"
-		return 1
-	fi
-
-	grep 'config wifi-iface' /etc/config/wireless | sed -n -e "s/.*'\([^']*\)'.*/\1/p" | while read -r line ; do
-		uci -q delete "wireless.$line"
-	done
-	uci -q commit wireless
-
-	return 0
-}
-
-wifiAddPhy() {
-	if [ $# -ne "2" ]
-	then
-		echo "Usage: wifiAddPhy <phy> <channel>"
-		return 1
-	fi
-
-	local phy=$1
-	local channel=$2
-	local radio="radio$(echo "$phy" | tr -d -C "0-9")"
-	local hwmode="11g"
-	if [ "$channel" = "auto5" ] ; then
-		hwmode="11a"
-		channel="auto"
-	elif ( ! [ "$channel" = "auto" ] ) && [ "$channel" -gt "14" ]; then
-		hwmode="11a"
-	fi
-
-	uci batch <<-__EOF__
-		set wireless.${radio}='wifi-device'
-		set wireless.${radio}.type='mac80211'
-		set wireless.${radio}.channel='${channel}'
-		set wireless.${radio}.phy='${phy}'
-		set wireless.${radio}.hwmode='${hwmode}'
-		set wireless.${radio}.htmode='HT20'
-		set wireless.${radio}.country='DE'
-	__EOF__
-	if [ "$hwmode" = "11g" ]; then
-		uci batch <<-__EOF__
-			set wireless.${radio}.legacy_rates='0'
-		__EOF__
-	fi
-	uci commit wireless
-
-	echo "${radio}"
+	uci show wireless | sed -n 's,.*\.\([a-z0-9]*\)=wifi-device,\1,p'
 	return 0
 }
 
-wifiAddPhyCond() {
-	if [ $# -ne "3" ]
+wifiGetFreq() {
+	if [ $# -ne "1" ]
 	then
-		return 1
-	fi
-
-	local phy=$1
-	local freq=$2
-	local channel=$3
-	local radio=""
-
-	if iw phy "$phy" info | grep -q -m1 "${freq}... MHz"; then
-		radio="$(wifiAddPhy "$phy" "$channel")"
-		if [ -z "$radio" ]; then
-			return 1
-		fi
-	fi
-	
-	echo "$radio"
-	return 0 # also returns success if outermost if is false
-}
-
-wifiAddAdHocMesh() {
-	if [ $# -ne "3" ]
-	then
-		echo "Usage: wifiAddAdHocMesh <radio> <essid> <bssid>"
+		echo "Usage: wifiGetFreq <radio>"
 		return 1
 	fi
 
 	local radio=$1
-	local essid=$2
-	local bssid=$3
-
-	local channel=$(uci get "wireless.${radio}.channel")
-	local iface="w2mesh"
-	if [ "$channel" -gt "14" ]; then
-		iface="w5mesh"
-	fi
-
-	uci batch <<-__EOF__
-		set wireless.${iface}='wifi-iface'
-		set wireless.${iface}.device='${radio}'
-		set wireless.${iface}.network='${iface}'
-		set wireless.${iface}.ifname='${iface}'
-		set wireless.${iface}.mode='adhoc'
-		set wireless.${iface}.bssid='${bssid}'
-		set wireless.${iface}.ssid='${essid}'
-		set wireless.${iface}.mcast_rate='6000'
-		set wireless.${iface}.encryption='none'
-		commit wireless
-
-		set network.${iface}='interface'
-		set network.${iface}.mtu='1528'
-		set network.${iface}.proto='batadv'
-		set network.${iface}.mesh='bat0'
-		commit network
-	__EOF__
-
-	echo "${iface}"
-	return 0
-}
-
-wifiAddAP() {
-	if [ $# -ne "5" ]
-	then
-		echo "Usage: wifiAddAP <radio> <essid> <network> <iface> <hidden>"
-		return 1
-	fi
-
-	local radio=$1
-	local essid=$2
-	local network=$3
-	local inface=$4
-	local hidden=$5
-
-	local channel=$(uci get "wireless.${radio}.channel")
-	local iface="w2${inface}"
-	if [ "$channel" -gt "14" ]; then
-		iface="w5${inface}"
-	fi
-	uci batch <<-__EOF__
-		set wireless.${iface}='wifi-iface'
-		set wireless.${iface}.device='${radio}'
-		set wireless.${iface}.network='${network}'
-		set wireless.${iface}.ifname='${iface}'
-		set wireless.${iface}.mode='ap'
-		set wireless.${iface}.ssid='${essid}'
-		set wireless.${iface}.encryption='none'
-		set wireless.${iface}.hidden='${hidden}'
-
-		commit wireless
-	__EOF__
-
-	echo "${iface}"
-	return 0
-}
-
-wifiAddSta() {
-	if [ $# -ne "4" ]
-	then
-		echo "Usage: wifiAddSta <radio> <essid> <network> <iface>"
-		return 1
-	fi
-
-	local radio=$1
-	local essid=$2
-	local network=$3
-	local iface=$4
-
-	uci batch <<-__EOF__
-		set wireless.${iface}='wifi-iface'
-		set wireless.${iface}.device='${radio}'
-		set wireless.${iface}.network='${network}'
-		set wireless.${iface}.ifname='${iface}'
-		set wireless.${iface}.mode='sta'
-		set wireless.${iface}.ssid='${essid}'
-
-		commit wireless
-	__EOF__
-	
-	echo "${iface}"
-	return 0
-}
-
-wifiAddMesh() {
-	if [ $# -ne "2" ]
-	then
-		echo "Usage: wifiAddMesh <radio> <mesh-id>"
-		return 1
-	fi
-
-	local radio=$1
-	local mesh_id=$2
-
-	local channel=$(uci get "wireless.${radio}.channel")
-	local iface="w2mesh"
-	if [ "$channel" -gt "14" ]; then
-		iface="w5mesh"
-	fi
-	uci batch <<-__EOF__
-		set wireless.${iface}='wifi-iface'
-		set wireless.${iface}.device='${radio}'
-		set wireless.${iface}.network='${iface}'
-		set wireless.${iface}.ifname='${iface}'
-		set wireless.${iface}.mode='mesh'
-		set wireless.${iface}.mesh_id='${mesh_id}'
-		set wireless.${iface}.encryption='none'
-		set wireless.${iface}.mesh_fwding=0
-		commit wireless
-
-		set network.${iface}='interface'
-		set network.${iface}.mtu='1560'
-		set network.${iface}.proto='batadv'
-		set network.${iface}.mesh='bat0'
-		commit network
-	__EOF__
 
-	echo "${iface}"
+	# Use hwmode for switching, since this is always set by firmware (effectively hard-coded)
+	# Do not use channel, as this might be "auto" for both
+	[ "$(uci get "wireless.${radio}.hwmode")" = "11a" ] && echo "5" || echo "2"
 	return 0
 }
 # vim: set noexpandtab:tabstop=4
-- 
2.11.0



Mehr Informationen über die Mailingliste franken-dev