#ifdef CONFIG_OWE
static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd,
const u8 *peer, const u8 *ie,
- size_t ie_len)
+ size_t ie_len, const u8 *link_addr)
{
u16 status;
struct sta_info *sta;
}
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
+#ifdef CONFIG_IEEE80211BE
+ if (link_addr) {
+ struct mld_info *info = &sta->mld_info;
+ u8 link_id = hapd->mld_link_id;
+
+ info->mld_sta = true;
+ sta->mld_assoc_link_id = link_id;;
+ os_memcpy(info->common_info.mld_addr, peer, ETH_ALEN);
+ info->links[link_id].valid = true;
+ os_memcpy(info->links[link_id].local_addr, hapd->own_addr,
+ ETH_ALEN);
+ os_memcpy(info->links[link_id].peer_addr, link_addr, ETH_ALEN);
+ }
+#endif /* CONFIG_IEEE80211BE */
+
status = owe_process_rsn_ie(hapd, sta, elems.rsn_ie,
elems.rsn_ie_len, elems.owe_dh,
- elems.owe_dh_len);
+ elems.owe_dh_len, link_addr);
if (status != WLAN_STATUS_SUCCESS)
ap_free_sta(hapd, sta);
return 0;
err:
- hostapd_drv_update_dh_ie(hapd, peer, status, NULL, 0);
+ hostapd_drv_update_dh_ie(hapd, link_addr ? link_addr : peer, status,
+ NULL, 0);
return 0;
}
#endif /* CONFIG_OWE */
case EVENT_UPDATE_DH:
if (!data)
return;
+#ifdef CONFIG_IEEE80211BE
+ if (data->update_dh.assoc_link_id != -1) {
+ hapd = hostapd_mld_get_link_bss(
+ hapd, data->update_dh.assoc_link_id);
+ if (!hapd) {
+ wpa_printf(MSG_ERROR,
+ "MLD: Failed to get link BSS for EVENT_UPDATE_DH assoc_link_id=%d",
+ data->update_dh.assoc_link_id);
+ return;
+ }
+ }
+#endif /* CONFIG_IEEE80211BE */
hostapd_notif_update_dh_ie(hapd, data->update_dh.peer,
data->update_dh.ie,
- data->update_dh.ie_len);
+ data->update_dh.ie_len,
+ data->update_dh.link_addr);
break;
#endif /* CONFIG_OWE */
case EVENT_DISASSOC:
u16 owe_process_rsn_ie(struct hostapd_data *hapd,
struct sta_info *sta,
const u8 *rsn_ie, size_t rsn_ie_len,
- const u8 *owe_dh, size_t owe_dh_len)
+ const u8 *owe_dh, size_t owe_dh_len,
+ const u8 *link_addr)
{
u16 status;
u8 *owe_buf, ie[256 * 2];
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto end;
}
+#ifdef CONFIG_IEEE80211BE
+ if (sta->mld_info.mld_sta)
+ wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
+ sta->mld_assoc_link_id, &sta->mld_info);
+#endif /* CONFIG_IEEE80211BE */
rsn_ie -= 2;
rsn_ie_len += 2;
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
end:
wpa_printf(MSG_DEBUG, "OWE: Update status %d, ie len %d for peer "
MACSTR, status, (unsigned int) ie_len,
- MAC2STR(sta->addr));
- hostapd_drv_update_dh_ie(hapd, sta->addr, status,
+ MAC2STR(link_addr ? link_addr : sta->addr));
+ hostapd_drv_update_dh_ie(hapd, link_addr ? link_addr : sta->addr,
+ status,
status == WLAN_STATUS_SUCCESS ? ie : NULL,
ie_len);
u8 *owe_buf, size_t owe_buf_len, u16 *status);
u16 owe_process_rsn_ie(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *rsn_ie, size_t rsn_ie_len,
- const u8 *owe_dh, size_t owe_dh_len);
+ const u8 *owe_dh, size_t owe_dh_len,
+ const u8 *link_addr);
u16 owe_validate_request(struct hostapd_data *hapd, const u8 *peer,
const u8 *rsn_ie, size_t rsn_ie_len,
const u8 *owe_dh, size_t owe_dh_len);
const u8 *peer;
const u8 *ie;
size_t ie_len;
+ int assoc_link_id;
+ const u8 *link_addr;
} update_dh;
/**
struct nlattr *tb[])
{
union wpa_event_data data;
+ u8 *addr, *link_addr = NULL;
+ int assoc_link_id = -1;
if (!is_ap_interface(drv->nlmode))
return;
return;
os_memset(&data, 0, sizeof(data));
- data.update_dh.peer = nla_data(tb[NL80211_ATTR_MAC]);
+ addr = nla_data(tb[NL80211_ATTR_MAC]);
+
+ if (bss->links[0].link_id == NL80211_DRV_LINK_ID_NA &&
+ (tb[NL80211_ATTR_MLO_LINK_ID] ||
+ tb[NL80211_ATTR_MLD_ADDR])) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: Link info not expected for DH event for non-MLD AP");
+ return;
+ }
+
+ if (tb[NL80211_ATTR_MLO_LINK_ID]) {
+ assoc_link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: STA assoc link ID %d in UPDATE_OWE_INFO event",
+ assoc_link_id);
+
+ if (assoc_link_id != NL80211_DRV_LINK_ID_NA &&
+ tb[NL80211_ATTR_MLD_ADDR]) {
+ link_addr = addr;
+ addr = nla_data(tb[NL80211_ATTR_MLD_ADDR]);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: STA assoc link addr " MACSTR,
+ MAC2STR(link_addr));
+ }
+ }
+
+ data.update_dh.peer = addr;
data.update_dh.ie = nla_data(tb[NL80211_ATTR_IE]);
data.update_dh.ie_len = nla_len(tb[NL80211_ATTR_IE]);
+ data.update_dh.assoc_link_id = assoc_link_id;
+ data.update_dh.link_addr = link_addr;
wpa_printf(MSG_DEBUG, "nl80211: DH event - peer " MACSTR,
MAC2STR(data.update_dh.peer));