hostapd: MLO: Avoid use of mld_id as user configuration

mld_id was provided as a user configuration to identify partner BSS
belonging to the same AP MLD. The same id is used at the protocol level
also to indicate the AP MLD ID of the MLD.

But, in general mld_id is a relative reference of the MLD where 0 is
used as the mld_id to represent the self MLD and in case of MLO MBSSID
mld_id of a non transmitted BSS affiliated to an AP MLD is based on the
relative BSS index of the non transmitted BSS from the transmitted BSS.
Hence mld_id need not be fetched from users, rather it can be identified
wherever required.

To verify if the partners belong to the same AP MLD the interface name
can be checked, since all link BSS partners of the same AP MLD belong to
the same interface.

Hence, remove use of mld_id user config and instead introduce two
functions hostapd_is_ml_partner() and hostapd_get_mld_id(). The former
is used to verify whether partners belong to the same AP MLD and the
latter is used to get the MLD ID of the BSS.

Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
Sriram R 2024-03-06 12:06:33 +05:30 committed by Jouni Malinen
parent 272c253dc9
commit 259b43a31a
14 changed files with 61 additions and 56 deletions

View file

@ -5044,8 +5044,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->punct_acs_threshold = val; conf->punct_acs_threshold = val;
} else if (os_strcmp(buf, "mld_ap") == 0) { } else if (os_strcmp(buf, "mld_ap") == 0) {
bss->mld_ap = !!atoi(pos); bss->mld_ap = !!atoi(pos);
} else if (os_strcmp(buf, "mld_id") == 0) {
bss->mld_id = atoi(pos);
} else if (os_strcmp(buf, "mld_addr") == 0) { } else if (os_strcmp(buf, "mld_addr") == 0) {
if (hwaddr_aton(pos, bss->mld_addr)) { if (hwaddr_aton(pos, bss->mld_addr)) {
wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr", wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",

View file

@ -3476,10 +3476,8 @@ static int hostapd_ctrl_iface_enable_mld(struct hostapd_iface *iface)
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!h_conf->mld_ap || if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
h_conf->mld_id != iface->bss[0]->conf->mld_id)
continue; continue;
if (hostapd_enable_iface(h_iface)) { if (hostapd_enable_iface(h_iface)) {
@ -3517,10 +3515,8 @@ static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!h_conf->mld_ap || if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
h_conf->mld_id != iface->bss[0]->conf->mld_id)
continue; continue;
if (!h_hapd->mld_first_bss) { if (!h_hapd->mld_first_bss) {
@ -3538,10 +3534,8 @@ static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!h_conf->mld_ap || if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]) ||
h_conf->mld_id != iface->bss[0]->conf->mld_id ||
!h_hapd->mld_first_bss) !h_hapd->mld_first_bss)
continue; continue;

View file

@ -1071,9 +1071,6 @@ wmm_ac_vo_acm=0
# 1 = yes (MLO) # 1 = yes (MLO)
#mld_ap=0 #mld_ap=0
# MLD ID - Affiliated MLD ID
#mld_id=1
# AP MLD MAC address # AP MLD MAC address
# The configured address will be set as the interface hardware address and used # The configured address will be set as the interface hardware address and used
# as the AP MLD MAC address. If not set, the current interface hardware address # as the AP MLD MAC address. If not set, the current interface hardware address

View file

@ -175,9 +175,15 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
continue; continue;
} }
if (!hconf->mld_ap || hconf->mld_id != conf->mld_id) { if (!hconf->mld_ap) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Skip non matching mld_id"); "MLD: Skip non-MLD");
continue;
}
if (!hostapd_is_ml_partner(hapd, h_hapd)) {
wpa_printf(MSG_DEBUG,
"MLD: Skip non matching MLD vif name");
continue; continue;
} }

View file

@ -960,7 +960,7 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
* We want to include the AP MLD ID in the response if it was * We want to include the AP MLD ID in the response if it was
* included in the request. * included in the request.
*/ */
probed_mld_id = mld_id != -1 ? mld_id : hapd->conf->mld_id; probed_mld_id = mld_id != -1 ? mld_id : hostapd_get_mld_id(hapd);
for_each_mld_link(link, i, j, hapd->iface->interfaces, for_each_mld_link(link, i, j, hapd->iface->interfaces,
probed_mld_id) { probed_mld_id) {
@ -2676,8 +2676,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
continue; continue;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && other->bss[0]->conf->mld_ap && if (hostapd_is_ml_partner(hapd, other->bss[0]))
hapd->conf->mld_id == other->bss[0]->conf->mld_id)
mld_ap = true; mld_ap = true;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */

View file

@ -1013,7 +1013,7 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
"mld_id[%d]=%d\n" "mld_id[%d]=%d\n"
"mld_link_id[%d]=%d\n", "mld_link_id[%d]=%d\n",
(int) i, MAC2STR(bss->mld_addr), (int) i, MAC2STR(bss->mld_addr),
(int) i, bss->conf->mld_id, (int) i, hostapd_get_mld_id(bss),
(int) i, bss->mld_link_id); (int) i, bss->mld_link_id);
if (os_snprintf_error(buflen - len, ret)) if (os_snprintf_error(buflen - len, ret))
return len; return len;

View file

@ -1962,10 +1962,8 @@ static bool search_mld_sta(struct hostapd_data **p_hapd, const u8 *src)
struct hostapd_iface *h = struct hostapd_iface *h =
hapd->iface->interfaces->iface[i]; hapd->iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0]; struct hostapd_data *h_hapd = h->bss[0];
struct hostapd_bss_config *hconf = h_hapd->conf;
if (!hconf->mld_ap || if (!hostapd_is_ml_partner(h_hapd, hapd))
hconf->mld_id != hapd->conf->mld_id)
continue; continue;
h_hapd = hostapd_find_by_sta(h, src, false); h_hapd = hostapd_find_by_sta(h, src, false);

View file

@ -3217,11 +3217,9 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
struct hostapd_iface *h_iface = struct hostapd_iface *h_iface =
hapd_iface->interfaces->iface[j]; hapd_iface->interfaces->iface[j];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!h_conf->mld_ap || if (!hostapd_is_ml_partner(h_hapd,
h_conf->mld_id != hapd_iface->bss[0]) ||
hapd_iface->bss[0]->conf->mld_id ||
h_iface == hapd_iface) h_iface == hapd_iface)
continue; continue;
@ -4406,6 +4404,7 @@ void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd, struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
u8 link_id) u8 link_id)
{ {
@ -4414,9 +4413,8 @@ struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
for (i = 0; i < hapd->iface->interfaces->count; i++) { for (i = 0; i < hapd->iface->interfaces->count; i++) {
struct hostapd_iface *h = hapd->iface->interfaces->iface[i]; struct hostapd_iface *h = hapd->iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0]; struct hostapd_data *h_hapd = h->bss[0];
struct hostapd_bss_config *hconf = h_hapd->conf;
if (!hconf->mld_ap || hconf->mld_id != hapd->conf->mld_id) if (!hostapd_is_ml_partner(hapd, h_hapd))
continue; continue;
if (h_hapd->mld_link_id == link_id) if (h_hapd->mld_link_id == link_id)
@ -4425,6 +4423,29 @@ struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
return NULL; return NULL;
} }
bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
struct hostapd_data *hapd2)
{
if (!hapd1->conf->mld_ap || !hapd2->conf->mld_ap)
return false;
return !os_strcmp(hapd1->conf->iface, hapd2->conf->iface);
}
u8 hostapd_get_mld_id(struct hostapd_data *hapd)
{
if (!hapd->conf->mld_ap)
return 255;
/* MLD ID 0 represents self */
return 0;
/* TODO: MLD ID for Multiple BSS cases */
}
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */

View file

@ -781,6 +781,9 @@ int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd);
struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd, struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
u8 link_id); u8 link_id);
int hostapd_link_remove(struct hostapd_data *hapd, u32 count); int hostapd_link_remove(struct hostapd_data *hapd, u32 count);
bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
struct hostapd_data *hapd2);
u8 hostapd_get_mld_id(struct hostapd_data *hapd);
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
#define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \ #define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \
@ -794,7 +797,7 @@ int hostapd_link_remove(struct hostapd_data *hapd, u32 count);
for (_link = \ for (_link = \
(_ifaces)->iface[_iface_idx]->bss[_bss_idx]; \ (_ifaces)->iface[_iface_idx]->bss[_bss_idx]; \
_link && _link->conf->mld_ap && \ _link && _link->conf->mld_ap && \
_link->conf->mld_id == _mld_id; \ hostapd_get_mld_id(_link) == _mld_id; \
_link = NULL) _link = NULL)
#else /* CONFIG_IEEE80211BE */ #else /* CONFIG_IEEE80211BE */
#define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \ #define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \

View file

@ -4598,8 +4598,7 @@ int hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
if (hapd->iface == iface) if (hapd->iface == iface)
continue; continue;
if (iface->bss[0]->conf->mld_ap && if (hostapd_is_ml_partner(hapd, iface->bss[0]) &&
hapd->conf->mld_id == iface->bss[0]->conf->mld_id &&
i == iface->bss[0]->mld_link_id) i == iface->bss[0]->mld_link_id)
break; break;
} }
@ -5814,8 +5813,7 @@ static bool hostapd_ml_handle_disconnect(struct hostapd_data *hapd,
tmp_hapd = tmp_hapd =
assoc_hapd->iface->interfaces->iface[i]->bss[0]; assoc_hapd->iface->interfaces->iface[i]->bss[0];
if (!tmp_hapd->conf->mld_ap || if (!hostapd_is_ml_partner(assoc_hapd, tmp_hapd))
assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@ -6482,8 +6480,7 @@ static void hostapd_ml_handle_assoc_cb(struct hostapd_data *hapd,
struct hostapd_data *tmp_hapd = struct hostapd_data *tmp_hapd =
hapd->iface->interfaces->iface[i]->bss[0]; hapd->iface->interfaces->iface[i]->bss[0];
if (!tmp_hapd->conf->mld_ap || if (!hostapd_is_ml_partner(tmp_hapd, hapd))
hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@ -7446,8 +7443,7 @@ static size_t hostapd_eid_rnr_multi_iface_len(struct hostapd_data *hapd,
bool ap_mld = false; bool ap_mld = false;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap && if (hostapd_is_ml_partner(hapd, iface->bss[0]))
hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
ap_mld = true; ap_mld = true;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -7619,11 +7615,10 @@ static bool hostapd_eid_rnr_bss(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
u8 param_ch = hapd->eht_mld_bss_param_change; u8 param_ch = hapd->eht_mld_bss_param_change;
if (reporting_hapd->conf->mld_ap && if (hostapd_is_ml_partner(bss, reporting_hapd))
bss->conf->mld_id == reporting_hapd->conf->mld_id)
*eid++ = 0; *eid++ = 0;
else else
*eid++ = hapd->conf->mld_id; *eid++ = hostapd_get_mld_id(hapd);
*eid++ = hapd->mld_link_id | ((param_ch & 0xF) << 4); *eid++ = hapd->mld_link_id | ((param_ch & 0xF) << 4);
*eid = (param_ch >> 4) & 0xF; *eid = (param_ch >> 4) & 0xF;
@ -7721,8 +7716,7 @@ static u8 * hostapd_eid_rnr_multi_iface(struct hostapd_data *hapd, u8 *eid,
bool ap_mld = false; bool ap_mld = false;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap && if (hostapd_is_ml_partner(hapd, iface->bss[0]))
hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
ap_mld = true; ap_mld = true;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */

View file

@ -505,8 +505,8 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
if (include_mld_id) { if (include_mld_id) {
wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x", wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x",
hapd->conf->mld_id); hostapd_get_mld_id(hapd));
wpabuf_put_u8(buf, hapd->conf->mld_id); wpabuf_put_u8(buf, hostapd_get_mld_id(hapd));
} }
if (!mld_info) if (!mld_info)
@ -1039,8 +1039,7 @@ static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd,
if (hapd == other_hapd) if (hapd == other_hapd)
continue; continue;
if (other_hapd->conf->mld_ap && if (hostapd_is_ml_partner(hapd, other_hapd) &&
other_hapd->conf->mld_id == hapd->conf->mld_id &&
link_id == other_hapd->mld_link_id) link_id == other_hapd->mld_link_id)
break; break;
} }

View file

@ -172,8 +172,7 @@ static void ieee802_1x_ml_set_sta_authorized(struct hostapd_data *hapd,
struct hostapd_data *tmp_hapd = struct hostapd_data *tmp_hapd =
hapd->iface->interfaces->iface[i]->bss[0]; hapd->iface->interfaces->iface[i]->bss[0];
if (!tmp_hapd->conf->mld_ap || if (!hostapd_is_ml_partner(hapd, tmp_hapd))
hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;

View file

@ -978,8 +978,7 @@ static bool ap_sta_ml_disconnect(struct hostapd_data *hapd,
tmp_hapd = interfaces->iface[i]->bss[0]; tmp_hapd = interfaces->iface[i]->bss[0];
if (!tmp_hapd->conf->mld_ap || if (!hostapd_is_ml_partner(tmp_hapd, assoc_hapd))
assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@ -1731,7 +1730,7 @@ static void ap_sta_remove_link_sta(struct hostapd_data *hapd,
unsigned int i, j; unsigned int i, j;
for_each_mld_link(tmp_hapd, i, j, hapd->iface->interfaces, for_each_mld_link(tmp_hapd, i, j, hapd->iface->interfaces,
hapd->conf->mld_id) { hostapd_get_mld_id(hapd)) {
struct sta_info *tmp_sta; struct sta_info *tmp_sta;
if (hapd == tmp_hapd) if (hapd == tmp_hapd)

View file

@ -1556,8 +1556,7 @@ static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx,
struct hostapd_iface *iface = struct hostapd_iface *iface =
hapd->iface->interfaces->iface[j]; hapd->iface->interfaces->iface[j];
if (!iface->bss[0]->conf->mld_ap || if (!hostapd_is_ml_partner(hapd, iface->bss[0]) ||
hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
link_id != iface->bss[0]->mld_link_id || link_id != iface->bss[0]->mld_link_id ||
!iface->bss[0]->wpa_auth) !iface->bss[0]->wpa_auth)
continue; continue;
@ -1599,8 +1598,7 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
struct hostapd_iface *iface = struct hostapd_iface *iface =
hapd->iface->interfaces->iface[j]; hapd->iface->interfaces->iface[j];
if (!iface->bss[0]->conf->mld_ap || if (!hostapd_is_ml_partner(hapd, iface->bss[0]) ||
hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
link_id != iface->bss[0]->mld_link_id || link_id != iface->bss[0]->mld_link_id ||
!iface->bss[0]->wpa_auth) !iface->bss[0]->wpa_auth)
continue; continue;