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 <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
Ilan Peer 2022-11-30 15:09:29 +02:00 committed by Jouni Malinen
parent a134b4dc5c
commit a2c4c0b1b6
2 changed files with 114 additions and 2 deletions

View file

@ -898,6 +898,38 @@ struct wpa_driver_sta_auth_params {
size_t fils_kek_len; 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 * struct wpa_driver_associate_params - Association parameters
* Data for struct wpa_driver_ops::associate(). * Data for struct wpa_driver_ops::associate().
@ -1271,6 +1303,11 @@ struct wpa_driver_associate_params {
* disable_eht - Disable EHT for this connection * disable_eht - Disable EHT for this connection
*/ */
int disable_eht; int disable_eht;
/*
* mld_params - MLD association parameters
*/
struct wpa_driver_mld_params mld_params;
}; };
enum hide_ssid { enum hide_ssid {

View file

@ -6242,10 +6242,85 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params, struct wpa_driver_associate_params *params,
struct nl_msg *msg) struct nl_msg *msg)
{ {
if (params->mld_params.mld_addr && params->mld_params.valid_links > 0) {
struct wpa_driver_mld_params *mld_params = &params->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)) if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
return -1; return -1;
if (params->bssid) { if (params->bssid && !params->mld_params.mld_addr) {
wpa_printf(MSG_DEBUG, " * bssid=" MACSTR, wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
MAC2STR(params->bssid)); MAC2STR(params->bssid));
if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, 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; return -1;
} }
if (params->freq.freq) { if (params->freq.freq && !params->mld_params.mld_addr) {
wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq); wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq);
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
params->freq.freq)) params->freq.freq))