diff mbox series

Advertise 6G RNR IE from nr_db also in probe response

Message ID CY8PR19MB7252426D615A540C4F7CC8E4DB072@CY8PR19MB7252.namprd19.prod.outlook.com
State Changes Requested
Headers show
Series Advertise 6G RNR IE from nr_db also in probe response | expand

Commit Message

Nikita Chernikov April 9, 2024, 7:44 a.m. UTC
From ccf6b23c40b4a05d10147c2bddc19e59ba751c73 Mon Sep 17 00:00:00 2001
From: Nikita Chernikov <nchernikov@maxlinear.com>
Date: Tue, 2 Apr 2024 14:45:39 +0300
Subject: [PATCH] Advertise 6G RNR IE from nr_db also in probe response
To: hostap@lists.infradead.org

Currently, RNR elements built from nr_db are only advertised in beacon.
To comply with 11AX standard, RNR IE of 6G should also be advertised in probe response.
Also, replace magic numbers with definitions in nr_db RNR element construction.

Signed-off-by: Nikita Chernikov <nchernikov@maxlinear.com>
---
 src/ap/ieee802_11.c  | 39 +++++++++++++++++++++++++--------------
 src/ap/neighbor_db.h |  4 ++++
 2 files changed, 29 insertions(+), 14 deletions(-)

Comments

Jouni Malinen June 12, 2024, 8:54 a.m. UTC | #1
On Tue, Apr 09, 2024 at 07:44:03AM +0000, Nikita Chernikov wrote:
> Currently, RNR elements built from nr_db are only advertised in beacon.
> To comply with 11AX standard, RNR IE of 6G should also be advertised in probe response.

Could you please be more specific on what exact requirements you are
referring to? The one in IEEE Std 80211ax-2021, 11.53 about RNR element
with the Co-Located AP subfield being set to 1? If so, that is
conditional on the AP operating in the 2.4 GHz or 5 GHz and being in the
same co-located AP set as the 6 GHz AP. Those conditions should likely
be included here as well.

> Also, replace magic numbers with definitions in nr_db RNR element construction.

That should be in a separate patch of its own to make the actual
functional changes clearer.

> diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
> +		/* Skip building RNR element from nr_db for non 6G VAPs in probe response */
> +		if (!(is_6ghz_op_class(wpabuf_head_u8(nr->nr)[HOSTAPD_NEIGHBOR_DB_NR_OPCLASS])) &&
> +			(frame_stype == WLAN_FC_STYPE_PROBE_RESP))
>  			continue;

It looks quite strange to look at the RNR information for determining
whether the AP is operating on the 6 GHz band. Shouldn't this be based
on the local AP's configuration, i.e., hapd->iconf->op_class?
diff mbox series

Patch

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index fcb2d14cf..a992379b6 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -50,6 +50,7 @@ 
 #include "ieee802_11.h"
 #include "dfs.h"
 #include "mbo_ap.h"
+#include "neighbor_db.h"
 #include "rrm.h"
 #include "taxonomy.h"
 #include "fils_hlp.h"
@@ -7301,14 +7302,19 @@  u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
 
 
 static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
-				    size_t *current_len)
+				    size_t *current_len, unsigned int frame_stype)
 {
 	struct hostapd_neighbor_entry *nr;
 	size_t total_len = 0, len = *current_len;
 
 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
 			 list) {
-		if (!nr->nr || wpabuf_len(nr->nr) < 12)
+		if (!nr->nr || wpabuf_len(nr->nr) < HOSTAPD_NEIGHBOR_DB_NR_MAX_LEN)
+			continue;
+
+		/* Skip building RNR element from nr_db for non 6G VAPs in probe response */
+		if (!(is_6ghz_op_class(wpabuf_head_u8(nr->nr)[HOSTAPD_NEIGHBOR_DB_NR_OPCLASS])) &&
+			(frame_stype == WLAN_FC_STYPE_PROBE_RESP))
 			continue;
 
 		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
@@ -7484,11 +7490,11 @@  size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
 
 	switch (type) {
 	case WLAN_FC_STYPE_BEACON:
-		if (hapd->conf->rnr)
-			total_len += hostapd_eid_nr_db_len(hapd, &current_len);
 		/* fallthrough */
-
 	case WLAN_FC_STYPE_PROBE_RESP:
+		if (hapd->conf->rnr)
+			total_len += hostapd_eid_nr_db_len(hapd, &current_len, type);
+
 		if (mode == COLOCATED_LOWER_BAND || ap_mld)
 			total_len +=
 				hostapd_eid_rnr_multi_iface_len(hapd,
@@ -7517,7 +7523,7 @@  size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
 
 
 static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
-			      size_t *current_len)
+			      size_t *current_len, unsigned int frame_stype)
 {
 	struct hostapd_neighbor_entry *nr;
 	size_t len = *current_len;
@@ -7525,7 +7531,12 @@  static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
 
 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
 			 list) {
-		if (!nr->nr || wpabuf_len(nr->nr) < 12)
+		if (!nr->nr || wpabuf_len(nr->nr) < HOSTAPD_NEIGHBOR_DB_NR_MAX_LEN)
+			continue;
+
+		/* Skip building RNR element from nr_db for non 6G VAPs in probe response */
+		if (!(is_6ghz_op_class(wpabuf_head_u8(nr->nr)[HOSTAPD_NEIGHBOR_DB_NR_OPCLASS])) &&
+			(frame_stype == WLAN_FC_STYPE_PROBE_RESP))
 			continue;
 
 		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
@@ -7544,9 +7555,9 @@  static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
 		/* TBTT Information Length */
 		*eid++ = RNR_TBTT_INFO_LEN;
 		/* Operating Class */
-		*eid++ = wpabuf_head_u8(nr->nr)[10];
+		*eid++ = wpabuf_head_u8(nr->nr)[HOSTAPD_NEIGHBOR_DB_NR_OPCLASS];
 		/* Channel Number */
-		*eid++ = wpabuf_head_u8(nr->nr)[11];
+		*eid++ = wpabuf_head_u8(nr->nr)[HOSTAPD_NEIGHBOR_DB_NR_CHANNEL];
 		len += RNR_TBTT_HEADER_LEN;
 		/* TBTT Information Set */
 		/* TBTT Information field */
@@ -7758,11 +7769,11 @@  u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
 
 	switch (type) {
 	case WLAN_FC_STYPE_BEACON:
-		if (hapd->conf->rnr)
-			eid = hostapd_eid_nr_db(hapd, eid, &current_len);
 		/* fallthrough */
-
 	case WLAN_FC_STYPE_PROBE_RESP:
+		if (hapd->conf->rnr)
+			eid = hostapd_eid_nr_db(hapd, eid, &current_len, type);
+
 		if (mode == COLOCATED_LOWER_BAND || ap_mld)
 			eid = hostapd_eid_rnr_multi_iface(hapd, eid,
 							  &current_len);
@@ -8087,7 +8098,7 @@  u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
 	}
 
 	add_rnr = hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
-		frame_stype == WLAN_FC_STYPE_BEACON &&
+		((frame_stype == WLAN_FC_STYPE_BEACON) || (frame_stype == WLAN_FC_STYPE_PROBE_RESP)) &&
 		rnr_eid && rnr_count && rnr_offset && rnr_len;
 
 	while (bss_index < hapd->iface->num_bss) {
@@ -8128,7 +8139,7 @@  u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
 		cur_len = 0;
 
 		if (hapd->conf->rnr)
-			rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len);
+			rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len, frame_stype);
 		if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
 			rnr_eid = hostapd_eid_rnr_multi_iface(hapd, rnr_eid,
 							      &cur_len);
diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h
index 53f714203..621b94187 100644
--- a/src/ap/neighbor_db.h
+++ b/src/ap/neighbor_db.h
@@ -10,6 +10,10 @@ 
 #ifndef NEIGHBOR_DB_H
 #define NEIGHBOR_DB_H
 
+#define HOSTAPD_NEIGHBOR_DB_NR_OPCLASS 10
+#define HOSTAPD_NEIGHBOR_DB_NR_CHANNEL 11
+#define HOSTAPD_NEIGHBOR_DB_NR_MAX_LEN 12
+
 struct hostapd_neighbor_entry *
 hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
 		     const struct wpa_ssid_value *ssid);