nl80211: Introduce and implement a callback to add an MLO link for AP MLD
Add a driver callback to add a link to an AP interface. As the kernel removes all links on underline interface removal, there is currently no need to support individual link removal. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
parent
47269be36e
commit
821374d43a
2 changed files with 81 additions and 0 deletions
|
@ -4962,6 +4962,15 @@ struct wpa_driver_ops {
|
||||||
int (*get_sta_mlo_info)(void *priv,
|
int (*get_sta_mlo_info)(void *priv,
|
||||||
struct driver_sta_mlo_info *mlo_info);
|
struct driver_sta_mlo_info *mlo_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* link_add - Add a link to the AP MLD interface
|
||||||
|
* @priv: Private driver interface data
|
||||||
|
* @link_id: The link ID
|
||||||
|
* @addr: The MAC address to use for the link
|
||||||
|
* Returns: 0 on success, negative value on failure
|
||||||
|
*/
|
||||||
|
int (*link_add)(void *priv, u8 link_id, const u8 *addr);
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
int (*register_frame)(void *priv, u16 type,
|
int (*register_frame)(void *priv, u16 type,
|
||||||
const u8 *match, size_t match_len,
|
const u8 *match, size_t match_len,
|
||||||
|
|
|
@ -13105,6 +13105,77 @@ static int nl80211_dpp_listen(void *priv, bool enable)
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
|
|
||||||
|
|
||||||
|
static int nl80211_link_add(void *priv, u8 link_id, const u8 *addr)
|
||||||
|
{
|
||||||
|
struct i802_bss *bss = priv;
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
struct nl_msg *msg;
|
||||||
|
unsigned int idx, i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: MLD: add link_id=%u, addr=" MACSTR,
|
||||||
|
link_id, MAC2STR(addr));
|
||||||
|
|
||||||
|
if (drv->nlmode != NL80211_IFTYPE_AP) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: MLD: cannot add link to iftype=%u",
|
||||||
|
drv->nlmode);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bss->n_links >= MAX_NUM_MLD_LINKS) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: MLD: already have n_links=%zu",
|
||||||
|
bss->n_links);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bss->n_links; i++) {
|
||||||
|
if (bss->links[i].link_id == link_id &&
|
||||||
|
bss->links[i].beacon_set) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: MLD: link already set");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try using the first link entry, assuming it is not beaconing yet */
|
||||||
|
if (bss->n_links == 1 &&
|
||||||
|
bss->flink->link_id == NL80211_DRV_LINK_ID_NA) {
|
||||||
|
if (bss->flink->beacon_set) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: BSS already beaconing");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
} else {
|
||||||
|
idx = bss->n_links;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_ADD_LINK);
|
||||||
|
if (!msg ||
|
||||||
|
nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id) ||
|
||||||
|
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: add link failed. ret=%d (%s)",
|
||||||
|
ret, strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bss->links[idx].link_id = link_id;
|
||||||
|
os_memcpy(bss->links[idx].addr, addr, ETH_ALEN);
|
||||||
|
|
||||||
|
bss->n_links = idx + 1;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: MLD: n_links=%zu", bss->n_links);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
|
||||||
static int testing_nl80211_register_frame(void *priv, u16 type,
|
static int testing_nl80211_register_frame(void *priv, u16 type,
|
||||||
|
@ -13297,6 +13368,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.dpp_listen = nl80211_dpp_listen,
|
.dpp_listen = nl80211_dpp_listen,
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
||||||
|
.link_add = nl80211_link_add,
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
.register_frame = testing_nl80211_register_frame,
|
.register_frame = testing_nl80211_register_frame,
|
||||||
.radio_disable = testing_nl80211_radio_disable,
|
.radio_disable = testing_nl80211_radio_disable,
|
||||||
|
|
Loading…
Reference in a new issue