> -----Original Message----- > From: Hostap <hostap-bounces@xxxxxxxxxxxxxxxxxxx> On Behalf Of Andrei > Otcheretianski > Sent: Thursday, February 16, 2023 4:38 AM > To: hostap@xxxxxxxxxxxxxxxxxxx > Cc: Ilan Peer <ilan.peer@xxxxxxxxx> > Subject: [PATCH 10/50] AP: Include an RNR element in beacons for MLD AP > > From: Ilan Peer <ilan.peer@xxxxxxxxx> > > - 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@xxxxxxxxx> > --- > 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; > + For Lower band AP collocated with a 6GHz AP, RNR Element carrying ML Partner information should be a separate element from the one that carried OOB information Is it handled here ? > + 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; mld id is 0 if its not MBSS case i.e. If the reported AP is part of same MLD as reporting AP then mld id should be 0. > + *eid++ = hapd->conf->mld_link_id | (1 << 4); _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap