Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: fix net80211 802.11g compatibility check
To:
tech@openbsd.org
Date:
Thu, 31 Jul 2025 16:16:49 +0200

Download raw body.

Thread
On Thu, Jul 31, 2025 at 12:26:48PM +0100, Tom Smyth wrote:
> so it would be better to  check for at least one of the supported rates to
> detect a particular standard of AP be it 802.11  b, or a or g or n or ac
> etc...
> 

If we make any of the extended rates count, then we could use a
simpler heuristic: Check for the presence of the "extended rates"
info element in beacons, probe responses, assoc requests etc. on
2GHz channels.

M  sys/dev/ic/qwx.c               |  1+   1-
M  sys/net80211/ieee80211_node.c  |  7+  29-

2 files changed, 8 insertions(+), 30 deletions(-)

commit - 9af86e4b4d937c32c5d083ec0b7952c1b34fada6
commit + 1403242634014294ccb5ea5de1aabc3d401721b2
blob - f7921f80d7b005454efa677b714d90697dd06468
blob + 6d640b2d7627eb188213ca0960b21ac99914f4fa
--- sys/dev/ic/qwx.c
+++ sys/dev/ic/qwx.c
@@ -23135,7 +23135,7 @@ qwx_mac_vdev_start_restart(struct qwx_softc *sc, struc
 	/* Deduce a legacy mode based on the channel characteristics. */
 	if (IEEE80211_IS_CHAN_5GHZ(chan))
 		arg.channel.mode = MODE_11A;
-	else if (ieee80211_iserp_sta(ic->ic_bss))
+	else if (ic->ic_bss->ni_flags & IEEE80211_NODE_ERP)
 		arg.channel.mode = MODE_11G;
 	else
 		arg.channel.mode = MODE_11B;
blob - c6ca10f5df7c13a01d8cddd8f552e3abf2b41184
blob + 3a5f05057cc85ece31e8cd14ea58fd79445a68e4
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -2633,6 +2633,10 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct 
 		}
 		memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
 		rs->rs_nrates += nxrates;
+
+		/* 11g support implies ERP support */
+		if (nxrates > 0 && IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+			ni->ni_flags |= IEEE80211_NODE_ERP;
 	}
 	return ieee80211_fix_rate(ic, ni, flags);
 }
@@ -2684,31 +2688,6 @@ ieee80211_node_addba_request_ac_vo_to(void *arg)
 	ieee80211_node_addba_request(ni, EDCA_AC_VO);
 }
 
-/*
- * Check if the specified node supports ERP / 802.11g.
- */
-int
-ieee80211_iserp_sta(const struct ieee80211_node *ni)
-{
-	static const u_int8_t rates[] = { 2, 4, 11, 22, 12, 24, 48 };
-	const struct ieee80211_rateset *rs = &ni->ni_rates;
-	int i, j;
-
-	/*
-	 * A STA supports ERP operation if it includes all the Clause 19
-	 * mandatory rates in its supported rate set.
-	 */
-	for (i = 0; i < nitems(rates); i++) {
-		for (j = 0; j < rs->rs_nrates; j++) {
-			if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == rates[i])
-				break;
-		}
-		if (j == rs->rs_nrates)
-			return 0;
-	}
-	return 1;
-}
-
 #ifndef IEEE80211_STA_ONLY
 /*
  * This function is called to notify the 802.1X PACP machine that a new
@@ -2804,7 +2783,7 @@ ieee80211_count_nonerpsta(void *arg, struct ieee80211_
 	if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT)
 		return;
 
-	if (!ieee80211_iserp_sta(ni))
+	if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0)
 		(*nonerpsta)++;
 }
 
@@ -2857,7 +2836,7 @@ ieee80211_node_join_11g(struct ieee80211com *ic, struc
 		    ether_sprintf(ni->ni_macaddr), longslotsta));
 	}
 
-	if (!ieee80211_iserp_sta(ni)) {
+	if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) {
 		/*
 		 * Joining STA is non-ERP.
 		 */
@@ -2874,8 +2853,7 @@ ieee80211_node_join_11g(struct ieee80211com *ic, struc
 
 		if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
 			ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
-	} else
-		ni->ni_flags |= IEEE80211_NODE_ERP;
+	}
 }
 
 void