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 <chenhuan@qti.qualcomm.com>
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) &&
!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;
struct hostapd_iface *iface = hapd->iface;
#endif /* CONFIG_OWE */
bool updated = false;
+ bool driver_acl;
if (addr == NULL) {
/*
* 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) {
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,
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 ||