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 <daniel@makrotopia.org>
			
			
This commit is contained in:
		| @@ -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_BOOL="mesh_auto_open_plinks mesh_fwding" | ||||||
| MP_CONFIG_STRING="mesh_power_mode" | MP_CONFIG_STRING="mesh_power_mode" | ||||||
|  |  | ||||||
| iw() { |  | ||||||
| 	command iw $@ || logger -t mac80211 "Failed command: iw $@" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NEWAPLIST= | NEWAPLIST= | ||||||
| OLDAPLIST= | OLDAPLIST= | ||||||
| NEWSPLIST= | NEWSPLIST= | ||||||
| @@ -446,6 +442,36 @@ mac80211_iw_interface_add() { | |||||||
| 		rc="$?" | 		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 ] && { | 	[ "$rc" = 233 ] && { | ||||||
| 		# Device might not support virtual interfaces, so the interface never got deleted in the first place. | 		# 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. | 		# Check if the interface already exists, and avoid failing in this case. | ||||||
| @@ -511,6 +537,11 @@ mac80211_prepare_vif() { | |||||||
| 			[ "$enable" = 0 ] || staidx="$(($staidx + 1))" | 			[ "$enable" = 0 ] || staidx="$(($staidx + 1))" | ||||||
| 			[ "$wds" -gt 0 ] && wdsflag="4addr on" | 			[ "$wds" -gt 0 ] && wdsflag="4addr on" | ||||||
| 			mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return | 			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" | 			[ "$powersave" -gt 0 ] && powersave="on" || powersave="off" | ||||||
| 			iw "$ifname" set power_save "$powersave" | 			iw "$ifname" set power_save "$powersave" | ||||||
| 		;; | 		;; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Daniel Golle
					Daniel Golle