MLD level structure is present to store the MLD level information.
Add changes to use the MLD structure instead of link specific struct
hostapd_data to get/set the MLD level information.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap)
- addr = hapd->mld_addr;
+ addr = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
hapd->l2_test = l2_packet_init(ifname, addr,
ETHERTYPE_IP, hostapd_data_test_rx,
if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
continue;
- if (!h_hapd->mld_first_bss) {
+ if (hostapd_mld_is_first_bss(h_hapd)) {
first_iface = h_iface;
continue;
}
struct hostapd_data *h_hapd = h_iface->bss[0];
if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]) ||
- !h_hapd->mld_first_bss)
+ hostapd_mld_is_first_bss(h_hapd))
continue;
if (hostapd_disable_iface(h_iface)) {
* is not configured, and otherwise it would be the
* configured BSSID.
*/
- os_memcpy(hapd->mld_addr, h_hapd->mld_addr, ETH_ALEN);
if (is_zero_ether_addr(b)) {
- os_memcpy(hapd->own_addr, h_hapd->mld_addr, ETH_ALEN);
+ os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr,
+ ETH_ALEN);
random_mac_addr_keep_oui(hapd->own_addr);
} else {
os_memcpy(hapd->own_addr, b, ETH_ALEN);
}
- /*
- * Mark the interface as a secondary interface, as this
- * is needed for the de-initialization flow
- */
- hapd->mld_first_bss = h_hapd;
- hapd->mld_link_id = hapd->mld_first_bss->mld_next_link_id++;
+ hapd->mld_link_id = hapd->mld->next_link_id++;
+ hostapd_mld_add_link(hapd);
goto setup_mld;
}
* configured, and otherwise it would be the configured BSSID.
*/
if (hapd->conf->mld_ap) {
- os_memcpy(hapd->mld_addr, hapd->own_addr, ETH_ALEN);
- hapd->mld_next_link_id = 0;
- hapd->mld_link_id = hapd->mld_next_link_id++;
+ os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
+
if (!b)
random_mac_addr_keep_oui(hapd->own_addr);
else
os_memcpy(hapd->own_addr, b, ETH_ALEN);
+
+ hapd->mld_link_id = hapd->mld->next_link_id++;
+ hostapd_mld_add_link(hapd);
}
setup_mld:
wpa_printf(MSG_DEBUG,
"MLD: Set link_id=%u, mld_addr=" MACSTR
", own_addr=" MACSTR,
- hapd->mld_link_id, MAC2STR(hapd->mld_addr),
+ hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
MAC2STR(hapd->own_addr));
hostapd_drv_link_add(hapd, hapd->mld_link_id,
link_id = hapd->mld_link_id;
if (ap_sta_is_mld(hapd, sta))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
}
#endif /* CONFIG_IEEE80211BE */
struct sta_info *sta = ap_get_sta(hapd, addr);
if (ap_sta_is_mld(hapd, sta))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
}
#endif /* CONFIG_IEEE80211BE */
sta = ap_get_sta(hapd, dst);
if (ap_sta_is_mld(hapd, sta)) {
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
bssid = own_addr;
}
#endif /* CONFIG_IEEE80211BE */
struct radius_server_conf srv;
struct hostapd_bss_config *conf = hapd->conf;
- if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+ if (!hostapd_mld_is_first_bss(hapd)) {
+ struct hostapd_data *first;
+
wpa_printf(MSG_DEBUG,
"MLD: Using RADIUS server of the first BSS");
- hapd->radius_srv = hapd->mld_first_bss->radius_srv;
+ first = hostapd_mld_get_first_bss(hapd);
+ if (!first)
+ return -1;
+ hapd->radius_srv = first->radius_srv;
return 0;
}
+#endif /* CONFIG_IEEE80211BE */
os_memset(&srv, 0, sizeof(srv));
srv.client_file = conf->radius_server_clients;
int authsrv_init(struct hostapd_data *hapd)
{
- if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+ if (!hostapd_mld_is_first_bss(hapd)) {
+ struct hostapd_data *first;
+
wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
+ first = hostapd_mld_get_first_bss(hapd);
+ if (!first)
+ return -1;
#ifdef EAP_TLS_FUNCS
- hapd->ssl_ctx = hapd->mld_first_bss->ssl_ctx;
+ hapd->ssl_ctx = first->ssl_ctx;
#endif /* EAP_TLS_FUNCS */
- hapd->eap_cfg = hapd->mld_first_bss->eap_cfg;
+ hapd->eap_cfg = first->eap_cfg;
#ifdef EAP_SIM_DB
- hapd->eap_sim_db_priv = hapd->mld_first_bss->eap_sim_db_priv;
+ hapd->eap_sim_db_priv = first->eap_sim_db_priv;
#endif /* EAP_SIM_DB */
return 0;
}
+#endif /* CONFIG_IEEE80211BE */
#ifdef EAP_TLS_FUNCS
if (hapd->conf->eap_server &&
void authsrv_deinit(struct hostapd_data *hapd)
{
- if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+ if (!hostapd_mld_is_first_bss(hapd)) {
wpa_printf(MSG_DEBUG,
"MLD: Deinit auth_serv of a non-first BSS");
#endif /* EAP_TLS_FUNCS */
return;
}
+#endif /* CONFIG_IEEE80211BE */
#ifdef RADIUS_SERVER
radius_server_deinit(hapd->radius_srv);
"mld_addr[%d]=" MACSTR "\n"
"mld_id[%d]=%d\n"
"mld_link_id[%d]=%d\n",
- (int) i, MAC2STR(bss->mld_addr),
+ (int) i, MAC2STR(bss->mld->mld_addr),
(int) i, hostapd_get_mld_id(bss),
(int) i, bss->mld_link_id);
if (os_snprintf_error(buflen - len, ret))
if (ap_sta_is_mld(hapd, sta)) {
wpa_printf(MSG_DEBUG,
"MLD: Set ML info in RSN Authenticator");
- wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
+ wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
sta->mld_assoc_link_id,
&sta->mld_info);
}
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap &&
- ether_addr_equal(hapd->mld_addr, bssid))
+ ether_addr_equal(hapd->mld->mld_addr, bssid))
is_mld = true;
#endif /* CONFIG_IEEE80211BE */
hapd = tmp_hapd;
#ifdef CONFIG_IEEE80211BE
} else if (hapd->conf->mld_ap &&
- ether_addr_equal(hapd->mld_addr, get_hdr_bssid(hdr, len))) {
+ ether_addr_equal(hapd->mld->mld_addr,
+ get_hdr_bssid(hdr, len))) {
/* AP MLD address match - use hapd pointer as-is */
#endif /* CONFIG_IEEE80211BE */
} else {
static void hostapd_clear_drv_priv(struct hostapd_data *hapd)
{
+#ifdef CONFIG_IEEE80211BE
unsigned int i;
for (i = 0; i < hapd->iface->interfaces->count; i++) {
continue;
if (iface->bss && iface->bss[0] &&
- iface->bss[0]->mld_first_bss == hapd)
+ hostapd_mld_get_first_bss(iface->bss[0]) == hapd)
iface->bss[0]->drv_priv = NULL;
}
+#endif /* CONFIG_IEEE80211BE */
hapd->drv_priv = NULL;
}
vlan_deinit(hapd);
hostapd_acl_deinit(hapd);
#ifndef CONFIG_NO_RADIUS
- if (!hapd->mld_first_bss) {
+ if (hostapd_mld_is_first_bss(hapd)) {
+#ifdef CONFIG_IEEE80211BE
struct hapd_interfaces *ifaces = hapd->iface->interfaces;
size_t i;
h->radius_das = NULL;
}
}
+#endif /* CONFIG_IEEE80211BE */
radius_client_deinit(hapd->radius);
radius_das_deinit(hapd->radius_das);
}
}
+/* hostapd_bss_link_deinit - Per-BSS ML cleanup (deinitialization)
+ * @hapd: Pointer to BSS data
+ *
+ * This function is used to unlink the BSS from the AP MLD.
+ * If the BSS being removed is the first link, the next link becomes the first
+ * link.
+ */
+static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
+{
+#ifdef CONFIG_IEEE80211BE
+ if (!hapd->conf || !hapd->conf->mld_ap)
+ return;
+
+ if (!hapd->mld->num_links)
+ return;
+
+ /* If not started, not yet linked to the MLD. However, the first
+ * BSS is always linked since it is linked during driver_init(), and
+ * hence, need to remove it from the AP MLD.
+ */
+ if (!hapd->started && hapd->iface->bss[0] != hapd)
+ return;
+
+ /* The first BSS can also be only linked when at least driver_init() is
+ * executed. But if previous interface fails, it is not, and hence,
+ * safe to skip.
+ */
+ if (hapd->iface->bss[0] == hapd && !hapd->drv_priv)
+ return;
+
+ hostapd_mld_remove_link(hapd);
+#endif /* CONFIG_IEEE80211BE */
+}
+
+
/**
* hostapd_cleanup - Per-BSS cleanup (deinitialization)
* @hapd: Pointer to BSS data
u8 if_addr[ETH_ALEN];
int flush_old_stations = 1;
- if (hapd->mld_first_bss)
+ if (!hostapd_mld_is_first_bss(hapd))
wpa_printf(MSG_DEBUG,
"MLD: %s: Setting non-first BSS", __func__);
}
#endif /* CONFIG_SQLITE */
- if (!hapd->mld_first_bss) {
+ if (hostapd_mld_is_first_bss(hapd)) {
hapd->radius = radius_client_init(hapd, conf->radius);
if (!hapd->radius) {
wpa_printf(MSG_ERROR,
}
}
} else {
+#ifdef CONFIG_IEEE80211BE
+ struct hostapd_data *f_bss;
+
wpa_printf(MSG_DEBUG,
"MLD: Using RADIUS client of the first BSS");
- hapd->radius = hapd->mld_first_bss->radius;
- hapd->radius_das = hapd->mld_first_bss->radius_das;
+ f_bss = hostapd_mld_get_first_bss(hapd);
+ if (!f_bss)
+ return -1;
+ hapd->radius = f_bss->radius;
+ hapd->radius_das = f_bss->radius_das;
+#endif /* CONFIG_IEEE80211BE */
}
#endif /* CONFIG_NO_RADIUS */
static void hostapd_no_ir_cleanup(struct hostapd_data *bss)
{
hostapd_bss_deinit_no_free(bss);
+ hostapd_bss_link_deinit(bss);
hostapd_free_hapd_data(bss);
hostapd_cleanup_iface_partial(bss->iface);
}
hapd->rad_attr_db = NULL;
}
#endif /* CONFIG_SQLITE */
+
+ hostapd_bss_link_deinit(hapd);
hostapd_cleanup(hapd);
}
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
if (driver && driver->hapd_deinit && drv_priv) {
- if (!iface->bss[0]->mld_first_bss)
+ if (hostapd_mld_is_first_bss(iface->bss[0]))
driver->hapd_deinit(drv_priv);
hostapd_clear_drv_priv(iface->bss[0]);
}
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
if (driver && driver->hapd_deinit && drv_priv) {
- if (!hapd_iface->bss[0]->mld_first_bss)
+ if (hostapd_mld_is_first_bss(hapd_iface->bss[0]))
driver->hapd_deinit(drv_priv);
for (j = 0; j < hapd_iface->num_bss; j++) {
wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
#ifdef CONFIG_IEEE80211BE
if (hapd_iface->bss[0]->conf->mld_ap &&
- !hapd_iface->bss[0]->mld_first_bss) {
+ hostapd_mld_is_first_bss((hapd_iface->bss[0]))) {
/* Do not allow mld_first_bss disabling before other BSSs */
for (j = 0; j < hapd_iface->interfaces->count; ++j) {
struct hostapd_iface *h_iface =
for (j = 0; j < hapd_iface->num_bss; j++) {
struct hostapd_data *hapd = hapd_iface->bss[j];
hostapd_bss_deinit_no_free(hapd);
+ hostapd_bss_link_deinit(hapd);
hostapd_free_hapd_data(hapd);
}
if (start_ctrl_iface_bss(hapd) < 0 ||
(hapd_iface->state == HAPD_IFACE_ENABLED &&
hostapd_setup_bss(hapd, -1, true))) {
+ hostapd_bss_link_deinit(hapd);
hostapd_cleanup(hapd);
hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
hapd_iface->conf->num_bss--;
wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
__func__, hapd_iface->bss[i],
hapd->conf->iface);
+ hostapd_bss_link_deinit(hapd);
hostapd_cleanup(hapd);
os_free(hapd);
hapd_iface->bss[i] = NULL;
unsigned int reenable_beacon:1;
u8 own_addr[ETH_ALEN];
- u8 mld_addr[ETH_ALEN];
- u8 mld_link_id;
- /* Used for mld_link_id assignment - valid on the first MLD BSS only */
- u8 mld_next_link_id;
-
- struct hostapd_data *mld_first_bss;
int num_sta; /* number of entries in sta_list */
struct sta_info *sta_list; /* STA info list head */
u8 eht_mld_bss_param_change;
struct hostapd_mld *mld;
struct dl_list link;
+ u8 mld_link_id;
#ifdef CONFIG_TESTING_OPTIONS
u8 eht_mld_link_removal_count;
#endif /* CONFIG_TESTING_OPTIONS */
* the addresses.
*/
if (ap_sta_is_mld(hapd, sta)) {
- sa = hapd->mld_addr;
+ sa = hapd->mld->mld_addr;
ml_resp = hostapd_ml_auth_resp(hapd);
if (!ml_resp)
#ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
if (sta->sae->tmp) {
u16 seq_ctrl;
struct radius_sta rad_info;
const u8 *dst, *sa, *bssid;
+#ifdef CONFIG_IEEE80211BE
bool mld_sta = false;
+#endif /* CONFIG_IEEE80211BE */
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
goto fail;
}
+#ifdef CONFIG_IEEE80211BE
if (mld_sta &&
(ether_addr_equal(sa, hapd->own_addr) ||
- ether_addr_equal(sa, hapd->mld_addr))) {
+ ether_addr_equal(sa, hapd->mld->mld_addr))) {
wpa_printf(MSG_INFO,
"Station " MACSTR " not allowed to authenticate",
MAC2STR(sa));
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
+#endif /* CONFIG_IEEE80211BE */
if (hapd->conf->no_auth_if_seen_on) {
struct hostapd_data *other;
*/
if (ap_sta_is_mld(hapd, sta)) {
dst = sta->addr;
- bssid = hapd->mld_addr;
+ bssid = hapd->mld->mld_addr;
}
#endif /* CONFIG_IEEE80211BE */
}
#ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta))
- wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
+ wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
sta->mld_assoc_link_id, &sta->mld_info);
#endif /* CONFIG_IEEE80211BE */
rsn_ie -= 2;
wpa_printf(MSG_DEBUG,
"MLD: Set ML info in RSN Authenticator");
wpa_auth_set_ml_info(sta->wpa_sm,
- hapd->mld_addr,
+ hapd->mld->mld_addr,
sta->mld_assoc_link_id,
info);
}
* MLD MAC address.
*/
if (ap_sta_is_mld(hapd, sta) && allow_mld_addr_trans)
- sa = hapd->mld_addr;
+ sa = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
os_memcpy(reply->da, addr, ETH_ALEN);
#endif /* CONFIG_MESH */
#ifdef CONFIG_IEEE80211BE
!(hapd->conf->mld_ap &&
- ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
+ ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
#endif /* CONFIG_IEEE80211BE */
!ether_addr_equal(mgmt->bssid, hapd->own_addr)) {
wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
stype != WLAN_FC_STYPE_ACTION) &&
#ifdef CONFIG_IEEE80211BE
!(hapd->conf->mld_ap &&
- ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
+ ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_NAN_USD
!ether_addr_equal(mgmt->da, nan_network_id) &&
wpabuf_put_u8(buf, common_info_len);
/* Own MLD MAC Address */
- wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
+ wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
/* Own Link ID */
wpabuf_put_u8(buf, hapd->mld_link_id);
wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
wpabuf_put_le16(buf, MULTI_LINK_CONTROL_TYPE_BASIC);
wpabuf_put_u8(buf, ETH_ALEN + 1);
- wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
+ wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
return buf;
}
#ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
#ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
struct eapol_auth_config conf;
struct eapol_auth_cb cb;
- if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+ if (!hostapd_mld_is_first_bss(hapd)) {
+ struct hostapd_data *first;
+
wpa_printf(MSG_DEBUG,
"MLD: Using IEEE 802.1X state machine of the first BSS");
- hapd->eapol_auth = hapd->mld_first_bss->eapol_auth;
+ first = hostapd_mld_get_first_bss(hapd);
+ if (!first)
+ return -1;
+ hapd->eapol_auth = first->eapol_auth;
return 0;
}
+#endif /* CONFIG_IEEE80211BE */
dl_list_init(&hapd->erp_keys);
void ieee802_1x_deinit(struct hostapd_data *hapd)
{
- if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+ if (!hostapd_mld_is_first_bss(hapd)) {
wpa_printf(MSG_DEBUG,
"MLD: Deinit IEEE 802.1X state machine of a non-first BSS");
hapd->eapol_auth = NULL;
return;
}
+#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_WEP
eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && (!sta || ap_sta_is_mld(hapd, sta)))
- own_addr = hapd->mld_addr;
+ own_addr = hapd->mld->mld_addr;
#endif /* CONFIG_IEEE80211BE */
return own_addr;