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

Adrian Schmutzler freifunk at adrianschmutzler.de
Mi Apr 17 15:23:53 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>

---

This patch is build based on my network reconf patchset.

However, if you change 20a-fff-wireless to its old name, it is
supposed to work on current master except one-ports
(ETH0MAC problem).

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

Open question: Is the second config_load necessary?

I plan to rename 20a-fff-wireless and 20b-config-wireless to
24a-... and 24b-... in the network patchset. Thus, 24c-wXsta
already has the new name, but the other remain at 20* to enable
testing based on the old network set.
---
 .../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     |  98 +++++-----
 .../files/etc/uci-defaults/20a-fff-wireless        |  86 ++++++--
 .../fff-wireless/files/lib/functions/fff/wireless  | 217 +--------------------
 5 files changed, 170 insertions(+), 295 deletions(-)
 create mode 100644 src/packages/fff/fff-hoods/files/etc/uci-defaults/24c-fff-wXsta

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..008821a3 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}config.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..d5dc2c00 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
 
@@ -99,7 +89,7 @@ else
 
 			uci -q del "system. at system[0].hood"
 			uci -q del "system. at system[0].hoodid"
-			uci -q commit system
+			uci commit system
 			reload_config
 		
 			sleep 30 # Wait for the config AP, which may be created at the same time as this script has started
@@ -152,43 +142,55 @@ if [ -s "$hoodfiletmp" ]; then
 		fi
 
 		echo "Setting hood name: $hood (ID $hoodid)"
-		uci -q set "system. at system[0].hood=$hood"
-		uci -q set "system. at system[0].hoodid=$hoodid"
-		uci -q commit system
+		uci set "system. at system[0].hood=$hood"
+		uci set "system. at system[0].hoodid=$hoodid"
+		uci 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/files/etc/uci-defaults/20a-fff-wireless b/src/packages/fff/fff-wireless/files/etc/uci-defaults/20a-fff-wireless
index 860f47f6..dffe56ed 100644
--- a/src/packages/fff/fff-wireless/files/etc/uci-defaults/20a-fff-wireless
+++ b/src/packages/fff/fff-wireless/files/etc/uci-defaults/20a-fff-wireless
@@ -1,22 +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
-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='1'
+
+		set network.w${freq}mesh='interface'
+		set network.w${freq}mesh.mtu='1528'
+		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='1'
+
+		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 71a07f93..29803a1f 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,30 @@
 # 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}"
-	return 0
-}
-
-wifiAddPhyCond() {
-	if [ $# -ne "3" ]
-	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>"
-		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}"
+	uci show wireless | sed -n 's,.*\.\([a-z0-9]*\)=wifi-device,\1,p'
 	return 0
 }
 
-wifiAddAP() {
-	if [ $# -ne "5" ]
+wifiGetFreq() {
+	if [ $# -ne "1" ]
 	then
-		echo "Usage: wifiAddAP <radio> <essid> <network> <iface> <hidden>"
+		echo "Usage: wifiGetFreq <radio>"
 		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}"
+	# 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
 }
 
-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='1528'
-		set network.${iface}.proto='batadv'
-		set network.${iface}.mesh='bat0'
-		commit network
-	__EOF__
-
-	echo "${iface}"
-	return 0
-}
 # vim: set noexpandtab:tabstop=4
-- 
2.11.0



Mehr Informationen über die Mailingliste franken-dev