Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: fix 802.11 mode selection in ieee80211_node_join_bss()
To:
tech@openbsd.org
Date:
Fri, 25 Jul 2025 11:34:42 +0200

Download raw body.

Thread
On Fri, Jul 25, 2025 at 11:19:16AM +0200, Stefan Sperling wrote:
> When we are joining a new BSS (i.e. a new access point) while roaming,
> we might have to switch bands from 2 GHz to 5 GHz or vice-versa.
> @@ -1303,7 +1303,13 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc
>  	uint32_t assoc_fail = 0;
>  
>  	/* Reinitialize media mode and channels if needed. */
> -	mode = ieee80211_chan2mode(ic, selbs->ni_chan);
> +	if (IEEE80211_IS_CHAN_5GHZ(selbs->ni_chan))
> +		mode = IEEE80211_MODE_11A;
> +	else if (ieee80211_iserp_sta(selbs))
> +		mode = IEEE80211_MODE_11G;
> +	else
> +		mode = IEEE80211_MODE_11B;
> +

Ooops, this layer needs to take into account whether the driver supports 11g.

Drivers announce what they support by setting appropriate channel flags.
Check those as well to avoid breaking 11b-only devices such as atw(4). 

M  sys/net80211/ieee80211_node.c  |  9+  3-

1 file changed, 9 insertions(+), 3 deletions(-)

commit - d64e5fcced832f2a47ed1896e35987cba9887e42
commit + bccdbcb2d328be6d1547cc7b82972e40e32611a7
blob - c6ca10f5df7c13a01d8cddd8f552e3abf2b41184
blob + 491e5ef044a00ce6912c53914f5f114e1473e2c6
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -1303,7 +1303,15 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc
 	uint32_t assoc_fail = 0;
 
 	/* Reinitialize media mode and channels if needed. */
-	mode = ieee80211_chan2mode(ic, selbs->ni_chan);
+	if (IEEE80211_IS_CHAN_5GHZ(selbs->ni_chan))
+		mode = IEEE80211_MODE_11A;
+	else if (ieee80211_iserp_sta(selbs) &&
+	    ((selbs->ni_chan->ic_flags &
+	    (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0))
+		mode = IEEE80211_MODE_11G;
+	else
+		mode = IEEE80211_MODE_11B;
+
 	if (mode != ic->ic_curmode)
 		ieee80211_setmode(ic, mode);
 
@@ -1317,8 +1325,6 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc
 	ni = ic->ic_bss;
 	ni->ni_assoc_fail |= assoc_fail;
 
-	ic->ic_curmode = ieee80211_chan2mode(ic, ni->ni_chan);
-
 	/* Make sure we send valid rates in an association request. */
 	if (ic->ic_opmode == IEEE80211_M_STA)
 		ieee80211_fix_rate(ic, ni,