From a2c4c0b1b6bb53b3a690c41987e85ed0416a7b00 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 30 Nov 2022 15:09:29 +0200 Subject: [PATCH] nl80211: Support MLD association request Define additional association parameters for MLD to be able to indicate information for all the requested links and fill these into nl80211 attributes. Signed-off-by: Ilan Peer Signed-off-by: Andrei Otcheretianski --- src/drivers/driver.h | 37 +++++++++++++++++ src/drivers/driver_nl80211.c | 79 +++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 78d229c24..9825b1a44 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -898,6 +898,38 @@ struct wpa_driver_sta_auth_params { size_t fils_kek_len; }; +struct wpa_driver_mld_params { + /** + * mld_addr - AP's MLD address + */ + const u8 *mld_addr; + + /** + * valid_links - The valid links including the association link + */ + u16 valid_links; + + /** + * assoc_link_id - The link on which the association is performed + */ + u8 assoc_link_id; + + /** + * mld_links - Link information + * + * Should include information on all the requested links for association + * including the link on which the association should take place. + * For the association link, the ies and ies_len should be NULL and + * 0 respectively. + */ + struct { + int freq; + const u8 *bssid; + const u8 *ies; + size_t ies_len; + } mld_links[MAX_NUM_MLD_LINKS]; +}; + /** * struct wpa_driver_associate_params - Association parameters * Data for struct wpa_driver_ops::associate(). @@ -1271,6 +1303,11 @@ struct wpa_driver_associate_params { * disable_eht - Disable EHT for this connection */ int disable_eht; + + /* + * mld_params - MLD association parameters + */ + struct wpa_driver_mld_params mld_params; }; enum hide_ssid { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 4796ed227..a2cc6ec47 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -6242,10 +6242,85 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv, struct wpa_driver_associate_params *params, struct nl_msg *msg) { + if (params->mld_params.mld_addr && params->mld_params.valid_links > 0) { + struct wpa_driver_mld_params *mld_params = ¶ms->mld_params; + struct nlattr *links, *attr; + int i; + u8 link_id; + + wpa_printf(MSG_DEBUG, " * MLD: MLD addr=" MACSTR, + MAC2STR(mld_params->mld_addr)); + + if (nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN, + mld_params->mld_addr) || + nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, + mld_params->assoc_link_id)) + return -1; + + links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS); + if (!links) + return -1; + + attr = nla_nest_start(msg, 0); + if (!attr) + return -1; + + /* First add the association link ID */ + link_id = mld_params->assoc_link_id; + if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id) || + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, + mld_params->mld_links[link_id].bssid) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, + mld_params->mld_links[link_id].freq)) + return -1; + + os_memcpy(drv->sta_mlo_info.links[link_id].bssid, + mld_params->mld_links[link_id].bssid, ETH_ALEN); + + nla_nest_end(msg, attr); + + for (i = 1, link_id = 0; link_id < MAX_NUM_MLD_LINKS; + link_id++) { + if (!(mld_params->valid_links & BIT(link_id)) || + link_id == mld_params->assoc_link_id) + continue; + + attr = nla_nest_start(msg, i); + if (!attr) + return -1; + + if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, + link_id) || + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, + mld_params->mld_links[link_id].bssid) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, + mld_params->mld_links[link_id].freq) || + (mld_params->mld_links[link_id].ies && + mld_params->mld_links[i].ies_len && + nla_put(msg, NL80211_ATTR_IE, + mld_params->mld_links[link_id].ies_len, + mld_params->mld_links[link_id].ies))) + return -1; + + os_memcpy(drv->sta_mlo_info.links[link_id].bssid, + mld_params->mld_links[link_id].bssid, + ETH_ALEN); + nla_nest_end(msg, attr); + i++; + } + + nla_nest_end(msg, links); + + os_memcpy(drv->sta_mlo_info.ap_mld_addr, + params->mld_params.mld_addr, ETH_ALEN); + drv->sta_mlo_info.assoc_link_id = mld_params->assoc_link_id; + drv->sta_mlo_info.req_links = mld_params->valid_links; + } + if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER)) return -1; - if (params->bssid) { + if (params->bssid && !params->mld_params.mld_addr) { wpa_printf(MSG_DEBUG, " * bssid=" MACSTR, MAC2STR(params->bssid)); if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid)) @@ -6260,7 +6335,7 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv, return -1; } - if (params->freq.freq) { + if (params->freq.freq && !params->mld_params.mld_addr) { wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq); if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq.freq))