From: Chenming Huang Date: Fri, 16 May 2025 01:57:27 +0000 (+0530) Subject: AP MLD: Use hostapd-based ACL for MLO cases X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d48a63d4da44c8cbd85dd409a7da68d0e2a052e2;p=thirdparty%2Fhostap.git AP MLD: Use hostapd-based ACL for MLO cases Currently NL80211_CMD_SET_MAC_ACL is not supported for MLO cases. Since this command has no upstream driver support, further extension might not be accepted and this command itself may be removed in the future, too. To support the same ACL setting from hostapd control interface, use hostapd-based ACL instead when comes to MLO case. In addition, verify both the link addresses and MLD MAC addresses of the non-AP MLD. Signed-off-by: Chenming Huang --- diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index 441995bcb..799aff765 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -1644,6 +1644,11 @@ int hostapd_disassoc_deny_mac(struct hostapd_data *hapd) struct vlan_description vlan_id; for (sta = hapd->sta_list; sta; sta = sta->next) { +#ifdef CONFIG_IEEE80211BE + int link_id; + struct mld_link_info *info; +#endif /* CONFIG_IEEE80211BE */ + if (hostapd_maclist_found(hapd->conf->deny_mac, hapd->conf->num_deny_mac, sta->addr, &vlan_id) && @@ -1651,6 +1656,24 @@ int hostapd_disassoc_deny_mac(struct hostapd_data *hapd) !vlan_compare(&vlan_id, sta->vlan_desc))) ap_sta_disconnect(hapd, sta, sta->addr, WLAN_REASON_UNSPECIFIED); +#ifdef CONFIG_IEEE80211BE + for (link_id = 0; hapd->conf->mld_ap && + link_id < MAX_NUM_MLD_LINKS && + sta->mld_info.mld_sta; link_id++) { + info = &sta->mld_info.links[link_id]; + if (!info->valid || link_id != hapd->mld_link_id) + continue; + + if (hostapd_maclist_found(hapd->conf->deny_mac, + hapd->conf->num_deny_mac, + info->peer_addr, + &vlan_id) && + (!vlan_id.notempty || + !vlan_compare(&vlan_id, sta->vlan_desc))) + ap_sta_disconnect(hapd, sta, sta->addr, + WLAN_REASON_UNSPECIFIED); + } +#endif /* CONFIG_IEEE80211BE */ } return 0; diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index f3aeb2236..b54bb4f9e 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -330,6 +330,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, struct hostapd_iface *iface = hapd->iface; #endif /* CONFIG_OWE */ bool updated = false; + bool driver_acl; if (addr == NULL) { /* @@ -460,13 +461,56 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, * ACL if the driver supports ACL offload to avoid potentially * conflicting ACL rules. */ - if (hapd->iface->drv_max_acl_mac_addrs == 0 && + driver_acl = hapd->iface->drv_max_acl_mac_addrs > 0; +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) + driver_acl = false; +#endif /* CONFIG_IEEE80211BE */ + if (!driver_acl && hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) { wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect", MAC2STR(addr)); reason = WLAN_REASON_UNSPECIFIED; goto fail; } +#ifdef CONFIG_IEEE80211BE + /* + * The idea is that ACL is per link. For MLO associations, check + * whether peer MLD MAC address is acceptable in all requested links. + * For each peer link address, check the corresponding association + * local link's ACL configuration whether it is acceptable. + */ + if (!driver_acl && hapd->conf->mld_ap && link_addr) { + int link_id; + struct mld_link_info *info; + struct hostapd_data *bss; + + for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { + info = &sta->mld_info.links[link_id]; + if (!info->valid) + continue; + + bss = hostapd_mld_get_link_bss(hapd, link_id); + if (bss != hapd && + hostapd_check_acl(bss, addr, NULL) != + HOSTAPD_ACL_ACCEPT) { + wpa_printf(MSG_INFO, "STA " MACSTR + " not allowed to connect", + MAC2STR(addr)); + reason = WLAN_REASON_UNSPECIFIED; + goto fail; + } + if (hostapd_check_acl(bss, info->peer_addr, NULL) != + HOSTAPD_ACL_ACCEPT) { + wpa_printf(MSG_INFO, "link addr" MACSTR + " not allowed to connect", + MAC2STR(info->peer_addr)); + reason = WLAN_REASON_UNSPECIFIED; + goto fail; + } + } + } +#endif /* CONFIG_IEEE80211BE */ #ifdef CONFIG_P2P if (elems.p2p) { diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 7f2ebecb8..0dd2b89bb 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1809,6 +1809,14 @@ int hostapd_set_acl(struct hostapd_data *hapd) if (hapd->iface->drv_max_acl_mac_addrs == 0) return 0; +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) { + wpa_printf(MSG_DEBUG, + "Kernel doesn't support offloaded ACL for AP MLD. Use hostapd based ACL instead."); + return 0; + } +#endif /* CONFIG_IEEE80211BE */ + if (conf->macaddr_acl == DENY_UNLESS_ACCEPTED) { accept_acl = 1; err = hostapd_set_acl_list(hapd, conf->accept_mac, diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 53c32b0ef..bf36d7f9e 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3301,6 +3301,23 @@ static void handle_auth(struct hostapd_data *hapd, if (res == HOSTAPD_ACL_PENDING) return; +#ifdef CONFIG_IEEE80211BE + if (mld_sta) { + res = ieee802_11_allowed_address(hapd, mgmt->sa, + (const u8 *) mgmt, len, + &rad_info); + if (res == HOSTAPD_ACL_REJECT) { + wpa_msg(hapd->msg_ctx, MSG_DEBUG, + "Ignore Authentication frame from " MACSTR + " due to ACL reject", MAC2STR(mgmt->sa)); + resp = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto fail; + } + if (res == HOSTAPD_ACL_PENDING) + return; + } +#endif /* CONFIG_IEEE80211BE */ + #ifdef CONFIG_SAE if (auth_alg == WLAN_AUTH_SAE && !from_queue && (auth_transaction == 1 ||