[PATCH 10/50] AP: Include an RNR element in beacons for MLD AP
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Feb 15 15:08:24 PST 2023
From: Ilan Peer <ilan.peer at intel.com>
- Include RNR element in beacons of MLD APs.
- Whenever a new interface is added to an MLD AP, reconfigure
the beacon for all other interfaces, to allow updating their RNR
element.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/ap/beacon.c | 24 ++++++----
src/ap/hostapd.c | 3 ++
src/ap/ieee802_11.c | 86 +++++++++++++++++++++++++++++-------
src/common/ieee802_11_defs.h | 1 +
4 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 14cde4c584..c7ebc55347 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -2114,21 +2114,29 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
if (!iface->interfaces || iface->interfaces->count <= 1)
return 0;
- /* Update Beacon frames in case of 6 GHz colocation */
+ /* Update Beacon frames in case of 6 GHz colocation or MLD AP */
is_6g = is_6ghz_op_class(iface->conf->op_class);
for (j = 0; j < iface->interfaces->count; j++) {
- struct hostapd_iface *colocated;
+ struct hostapd_iface *other;
+ bool mld_ap = false;
- colocated = iface->interfaces->iface[j];
- if (colocated == iface || !colocated || !colocated->conf)
+ other = iface->interfaces->iface[j];
+ if (other == iface || !other || !other->conf)
continue;
- if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
+#ifdef CONFIG_IEEE80211BE
+ if (hapd->conf->mld_ap && other->bss[0]->conf->mld_ap &&
+ hapd->conf->mld_id == other->bss[0]->conf->mld_id)
+ mld_ap = true;
+#endif /* CONFIG_IEEE80211BE */
+
+ if (is_6g == is_6ghz_op_class(other->conf->op_class) &&
+ !mld_ap)
continue;
- for (i = 0; i < colocated->num_bss; i++) {
- if (colocated->bss[i] && colocated->bss[i]->started)
- __ieee802_11_set_beacon(colocated->bss[i]);
+ for (i = 0; i < other->num_bss; i++) {
+ if (other->bss[i] && other->bss[i]->started)
+ __ieee802_11_set_beacon(other->bss[i]);
}
}
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 9abfb5fa5f..bd353c5523 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -2316,6 +2316,9 @@ dfs_offload:
for (j = 0; j < iface->num_bss; j++)
hostapd_neighbor_set_own_report(iface->bss[j]);
+ if (iface->interfaces && iface->interfaces->count > 1)
+ ieee802_11_set_beacons(iface);
+
return 0;
fail:
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 8facad3692..5549e1094e 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -6414,6 +6414,11 @@ static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
size_t total_len = 0, len = *current_len;
int tbtt_count = 0;
size_t i, start = 0;
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ mld_ap = !!hapd->conf->mld_ap;
+#endif /* CONFIG_IEEE80211BE */
while (start < hapd->iface->num_bss) {
if (!len ||
@@ -6439,8 +6444,13 @@ static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
- len += RNR_TBTT_INFO_LEN;
- total_len += RNR_TBTT_INFO_LEN;
+ if (!mld_ap) {
+ len += RNR_TBTT_INFO_LEN;
+ total_len += RNR_TBTT_INFO_LEN;
+ } else {
+ len += RNR_TBTT_INFO_MLD_LEN;
+ total_len += RNR_TBTT_INFO_MLD_LEN;
+ }
tbtt_count++;
}
start = i;
@@ -6495,8 +6505,8 @@ static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
}
-static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
- size_t *current_len)
+static size_t hostapd_eid_rnr_multi_iface_len(struct hostapd_data *hapd,
+ size_t *current_len)
{
struct hostapd_iface *iface;
size_t len = 0;
@@ -6507,9 +6517,16 @@ static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
for (i = 0; i < hapd->iface->interfaces->count; i++) {
iface = hapd->iface->interfaces->iface[i];
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
+ hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
+ mld_ap = true;
+#endif /* CONFIG_IEEE80211BE */
if (iface == hapd->iface ||
- !is_6ghz_op_class(iface->conf->op_class))
+ !(is_6ghz_op_class(iface->conf->op_class) || mld_ap))
continue;
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
@@ -6524,6 +6541,11 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
{
size_t total_len = 0, current_len = 0;
enum colocation_mode mode = get_colocation_mode(hapd);
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ mld_ap = !!hapd->conf->mld_ap;
+#endif /* CONFIG_IEEE80211BE */
switch (type) {
case WLAN_FC_STYPE_BEACON:
@@ -6532,9 +6554,10 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
/* fallthrough */
case WLAN_FC_STYPE_PROBE_RESP:
- if (mode == COLOCATED_LOWER_BAND)
- total_len += hostapd_eid_rnr_colocation_len(
- hapd, ¤t_len);
+ if (mode == COLOCATED_LOWER_BAND || mld_ap)
+ total_len +=
+ hostapd_eid_rnr_multi_iface_len(hapd,
+ ¤t_len);
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
@@ -6620,6 +6643,11 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
size_t len = *current_len;
u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
u8 tbtt_count = 0, op_class, channel, bss_param;
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ mld_ap = !!hapd->conf->mld_ap;
+#endif /* CONFIG_IEEE80211BE */
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
return eid;
@@ -6642,7 +6670,12 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
}
tbtt_count_pos = eid++;
- *eid++ = RNR_TBTT_INFO_LEN;
+
+ if (!mld_ap)
+ *eid++ = RNR_TBTT_INFO_LEN;
+ else
+ *eid++ = RNR_TBTT_INFO_MLD_LEN;
+
*eid++ = op_class;
*eid++ = hapd->iconf->channel;
len += RNR_TBTT_HEADER_LEN;
@@ -6687,7 +6720,18 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
*eid++ = bss_param;
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
- len += RNR_TBTT_INFO_LEN;
+
+ if (!mld_ap) {
+ len += RNR_TBTT_INFO_LEN;
+ } else {
+#ifdef CONFIG_IEEE80211BE
+ *eid++ = hapd->conf->mld_id;
+ *eid++ = hapd->conf->mld_link_id | (1 << 4);
+ *eid++ = 0;
+ len += RNR_TBTT_INFO_MLD_LEN;
+#endif /* CONFIG_IEEE80211BE */
+ }
+
tbtt_count += 1;
}
@@ -6704,7 +6748,7 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
}
-static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
+static u8 *hostapd_eid_rnr_multi_iface(struct hostapd_data *hapd, u8 *eid,
size_t *current_len)
{
struct hostapd_iface *iface;
@@ -6715,9 +6759,16 @@ static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
for (i = 0; i < hapd->iface->interfaces->count; i++) {
iface = hapd->iface->interfaces->iface[i];
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
+ hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
+ mld_ap = true;
+#endif /* CONFIG_IEEE80211BE */
if (iface == hapd->iface ||
- !is_6ghz_op_class(iface->conf->op_class))
+ !(is_6ghz_op_class(iface->conf->op_class) || mld_ap))
continue;
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
@@ -6733,6 +6784,11 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
u8 *eid_start = eid;
size_t current_len = 0;
enum colocation_mode mode = get_colocation_mode(hapd);
+ bool mld_ap = false;
+
+#ifdef CONFIG_IEEE80211BE
+ mld_ap = !!hapd->conf->mld_ap;
+#endif /* CONFIG_IEEE80211BE */
switch (type) {
case WLAN_FC_STYPE_BEACON:
@@ -6741,9 +6797,9 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
/* fallthrough */
case WLAN_FC_STYPE_PROBE_RESP:
- if (mode == COLOCATED_LOWER_BAND)
- eid = hostapd_eid_rnr_colocation(hapd, eid,
- ¤t_len);
+ if (mode == COLOCATED_LOWER_BAND || mld_ap)
+ eid = hostapd_eid_rnr_multi_iface(hapd, eid,
+ ¤t_len);
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 21b48ac523..12ddad466f 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2418,6 +2418,7 @@ struct ieee80211_he_mu_edca_parameter_set {
#define RNR_TBTT_INFO_COUNT(x) (((x) & 0xf) << 4)
#define RNR_TBTT_INFO_COUNT_MAX 16
#define RNR_TBTT_INFO_LEN 13
+#define RNR_TBTT_INFO_MLD_LEN 16
#define RNR_NEIGHBOR_AP_OFFSET_UNKNOWN 255
/* Figure 9-632a - BSS Parameters subfield format */
#define RNR_BSS_PARAM_OCT_RECOMMENDED BIT(0)
--
2.38.1
More information about the Hostap
mailing list