From: Kavita Kavita Date: Fri, 9 May 2025 15:50:30 +0000 (+0530) Subject: MLD: Clear group keys for removed links X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7139cc28a07803cf1ce97134b16fbbdbdf744cb;p=thirdparty%2Fhostap.git MLD: Clear group keys for removed links For AP link removal case, group keys (e.g., GTK, IGTK, BIGTK, etc.) were not cleared for links that were removed in the NL80211_CMD_LINKS_REMOVED event. Since the links are already removed, we should clear the keys associated with these links for proper cleanup. This functionality was missing in the current implementation, so address this by clearing group keys for the removed links. Signed-off-by: Kavita Kavita --- diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 9bf9888ae..60e5f5892 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -918,6 +918,47 @@ out: #endif /* CONFIG_DRIVER_NL80211_QCA */ +static void mlme_event_link_removal(struct wpa_driver_nl80211_data *drv, + struct nlattr *mlo_links) +{ + struct nlattr *link; + u16 removed_links = 0; + int rem_links, i; + + if (!mlo_links) + return; + nla_for_each_nested(link, mlo_links, rem_links) { + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + int link_id; + + nla_parse(tb, NL80211_ATTR_MAX, nla_data(link), nla_len(link), + NULL); + + if (!tb[NL80211_ATTR_MLO_LINK_ID]) + continue; + + link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]); + if (link_id >= MAX_NUM_MLD_LINKS) + continue; + + removed_links |= BIT(link_id); + } + + drv->sta_mlo_info.valid_links &= ~removed_links; + drv->sta_mlo_info.req_links &= ~removed_links; + + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + if (!(removed_links & BIT(i))) + continue; + + os_memset(&drv->sta_mlo_info.links[i], 0, + sizeof(drv->sta_mlo_info.links[i])); + } + + wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL); +} + + static void mlme_event_connect(struct wpa_driver_nl80211_data *drv, enum nl80211_commands cmd, bool qca_roam_auth, struct nlattr *status, @@ -4308,7 +4349,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, break; #endif /* CONFIG_IEEE80211AX */ case NL80211_CMD_LINKS_REMOVED: - wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL); + mlme_event_link_removal(drv, tb[NL80211_ATTR_MLO_LINKS]); break; case NL80211_CMD_ASSOC_MLO_RECONF: mlme_event_link_addition(drv, nla_data(frame), nla_len(frame)); diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 9a0463170..f5319c606 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -4729,14 +4729,36 @@ void wpa_sm_set_ssid(struct wpa_sm *sm, const u8 *ssid, size_t ssid_len) } +static void wpa_sm_clear_mlo_group_keys(struct wpa_sm *sm, int link_id) +{ + if (!sm) + return; + + os_memset(&sm->mlo.links[link_id].gtk, 0, + sizeof(sm->mlo.links[link_id].gtk)); + os_memset(&sm->mlo.links[link_id].gtk_wnm_sleep, 0, + sizeof(sm->mlo.links[link_id].gtk_wnm_sleep)); + os_memset(&sm->mlo.links[link_id].igtk, 0, + sizeof(sm->mlo.links[link_id].igtk)); + os_memset(&sm->mlo.links[link_id].igtk_wnm_sleep, 0, + sizeof(sm->mlo.links[link_id].igtk_wnm_sleep)); + os_memset(&sm->mlo.links[link_id].bigtk, 0, + sizeof(sm->mlo.links[link_id].bigtk)); + os_memset(&sm->mlo.links[link_id].bigtk_wnm_sleep, 0, + sizeof(sm->mlo.links[link_id].bigtk_wnm_sleep)); +} + + int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo) { int i; + u16 removed_links; if (!sm) return -1; os_memcpy(sm->mlo.ap_mld_addr, mlo->ap_mld_addr, ETH_ALEN); + removed_links = ~mlo->valid_links & sm->mlo.valid_links; sm->mlo.assoc_link_id = mlo->assoc_link_id; sm->mlo.valid_links = mlo->valid_links; sm->mlo.req_links = mlo->req_links; @@ -4865,6 +4887,13 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo) } sm->mlo.links[i].ap_rsnxoe_len = len; } + + if (removed_links & BIT(i)) { + wpa_printf(MSG_DEBUG, + "RSN: Clearing MLO group keys for link[%u]", + i); + wpa_sm_clear_mlo_group_keys(sm, i); + } } return 0;