Browse Source

mac80211: detect existing interface before adding

Keep existing wdev when creating new nl80211 interfaces if phy and
type match, delete it otherwise.
To make this work, also remove left-over debugging function which
prevented the return-value of the 'iw' command to be taken into
account in mac80211_iw_interface_add().
As 4addr-mode (WDS) was setup during interface creation for station
interfaces, also set it after interface creation to make sure an
existing sta interface ends up with the right mode.

Fixes: a5bc9787d4 ("mac80211: add support for dynamically
                    reconfiguring wifi")
Signed-off-by: Daniel Golle <[email protected]>
Daniel Golle 6 years ago
parent
commit
ccf2aa9d4b
1 changed files with 35 additions and 4 deletions
  1. 35 4
      package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh

+ 35 - 4
package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh

@@ -15,10 +15,6 @@ MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh
 MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding"
 MP_CONFIG_STRING="mesh_power_mode"
 
-iw() {
-	command iw $@ || logger -t mac80211 "Failed command: iw $@"
-}
-
 NEWAPLIST=
 OLDAPLIST=
 NEWSPLIST=
@@ -446,6 +442,36 @@ mac80211_iw_interface_add() {
 		rc="$?"
 	}
 
+	[ "$rc" = 233 ] && {
+		# Keep matching pre-existing interface
+		[ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && \
+		case "$(iw dev wlan0 info | grep "^\ttype" | cut -d' ' -f2- 2>/dev/null)" in
+			"AP")
+				[ "$type" = "__ap" ] && rc=0
+				;;
+			"IBSS")
+				[ "$type" = "adhoc" ] && rc=0
+				;;
+			"managed")
+				[ "$type" = "managed" ] && rc=0
+				;;
+			"mesh point")
+				[ "$type" = "mp" ] && rc=0
+				;;
+			"monitor")
+				[ "$type" = "monitor" ] && rc=0
+				;;
+		esac
+	}
+
+	[ "$rc" = 233 ] && {
+		iw dev "$ifname" del
+		sleep 1
+
+		iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
+		rc="$?"
+	}
+
 	[ "$rc" = 233 ] && {
 		# Device might not support virtual interfaces, so the interface never got deleted in the first place.
 		# Check if the interface already exists, and avoid failing in this case.
@@ -511,6 +537,11 @@ mac80211_prepare_vif() {
 			[ "$enable" = 0 ] || staidx="$(($staidx + 1))"
 			[ "$wds" -gt 0 ] && wdsflag="4addr on"
 			mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return
+			if [ "$wds" -gt 0 ]; then
+				iw "$ifname" set 4addr on
+			else
+				iw "$ifname" set 4addr off
+			fi
 			[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
 			iw "$ifname" set power_save "$powersave"
 		;;