Download raw body.
replace ieee80211_chan2mode()
On 2025 Aug 01 (Fri) at 13:16:19 +0200 (+0200), Stefan Sperling wrote:
:ieee80211_chan2mode() is broken in several ways.
:
:chan2mode does not detect 11g APs properly. This can be fixed now that
:we are setting the ERP flag not only in hostap mode but also in client
:mode.
:
:If chan2mode is called while our phy mode is fixed, then it always
:returns our fixed phy mode. This means it wrongly selects 11g rates if
:our phy mode is fixed to 11g even if we are talking to an 11b-only peer
:which cannot receive 11g rates.
:
:chan2mode tries to handle a NULL channel which is not relevant to any
:of the callers.
:
:I want to replace chan2mode with a new ieee80211_node_abg_mode() function
:which serves the same purpose but does not have any of the above issues.
:
:Tested with qwx(4), which can now automatically associate with an AP which
:denies clients that use 11b data rates. Previously, 'ifconfig qwx0 mode 11g'
:was required to associate with such APs.
:
:ok?
:
OK, two optional comments inline
:blob - 2e02e1fff93930e65fc955599b4f7f1d85843259
:blob + a9abfb9366f3bc80f5abaaabceb9480bd06d9a5f
:--- sys/net80211/ieee80211_node.c
:+++ sys/net80211/ieee80211_node.c
:@@ -931,8 +931,28 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct
: mode = IEEE80211_MODE_11AC;
: else if (ic->ic_flags & IEEE80211_F_HTON)
: mode = IEEE80211_MODE_11N;
:- else
:- mode = ieee80211_chan2mode(ic, ni->ni_chan);
:+ else {
As I mentioned on icb, can you add the comment from the other place you
have this switch?
:+ switch (IFM_MODE(ic->ic_media.ifm_cur->ifm_media)) {
:+ case IFM_IEEE80211_11A:
:+ mode = IEEE80211_MODE_11A;
:+ break;
:+ case IFM_IEEE80211_11G:
:+ mode = IEEE80211_MODE_11G;
:+ break;
:+ case IFM_IEEE80211_11B:
:+ mode = IEEE80211_MODE_11B;
:+ break;
:+ default:
:+ if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
:+ mode = IEEE80211_MODE_11A;
:+ else if ((ni->ni_chan->ic_flags &
:+ (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0)
:+ mode = IEEE80211_MODE_11G;
:+ else
:+ mode = IEEE80211_MODE_11B;
:+ break;
:+ }
:+ }
: ieee80211_setmode(ic, mode);
: /* Pick an appropriate mode for supported legacy rates. */
: if (ic->ic_curmode == IEEE80211_MODE_11AC) {
:blob - 3d8d649c8f0ff5e79c98fc9b6ec95d0c4d68b7f2
:blob + 2463eec03cbbb297d18a40f1016e9c8800859f7f
:--- sys/net80211/ieee80211_proto.c
:+++ sys/net80211/ieee80211_proto.c
:@@ -221,7 +221,7 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct iee
:
: error = 0;
: okrate = badrate = fixedrate = 0;
:- srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
:+ srs = &ic->ic_sup_rates[ieee80211_node_abg_mode(ic, ni)];
: nrs = &ni->ni_rates;
: for (i = 0; i < nrs->rs_nrates; ) {
: ignore = 0;
:@@ -1153,8 +1153,8 @@ justcleanup:
: /* initialize bss for probe request */
: IEEE80211_ADDR_COPY(ni->ni_macaddr, etherbroadcastaddr);
: IEEE80211_ADDR_COPY(ni->ni_bssid, etherbroadcastaddr);
:- ni->ni_rates = ic->ic_sup_rates[
:- ieee80211_chan2mode(ic, ni->ni_chan)];
:+ ni->ni_rates = ic->ic_sup_rates[ieee80211_node_abg_mode(ic,
:+ ni)];
Purely a bikeshed, but the line-wrapping here makes my eye twitch. Can
you wrap it in the same style as the - lines?
: ni->ni_associd = 0;
: ni->ni_rstamp = 0;
: ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE;
--
Two can Live as Cheaply as One for Half as Long.
-- Howard Kandel
replace ieee80211_chan2mode()