diff options
author | Johannes Berg <johannes.berg@intel.com> | 2022-04-14 17:50:57 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2022-06-20 13:54:58 +0300 |
commit | 7b0a0e3c3a88260b6fcb017e49f198463aa62ed1 (patch) | |
tree | 901f9b3eb7cff778627b12e9f37c7ae226877a65 /net/wireless/wext-compat.c | |
parent | 92ea8df110b8ca92f9664ec7bd76dea109115348 (diff) | |
download | linux-7b0a0e3c3a88260b6fcb017e49f198463aa62ed1.tar.xz |
wifi: cfg80211: do some rework towards MLO link APIs
In order to support multi-link operation with multiple links,
start adding some APIs. The notable addition here is to have
the link ID in a new nl80211 attribute, that will be used to
differentiate the links in many nl80211 operations.
So far, this patch adds the netlink NL80211_ATTR_MLO_LINK_ID
attribute (as well as the NL80211_ATTR_MLO_LINKS attribute)
and plugs it through the system in some places, checking the
validity etc. along with other infrastructure needed for it.
For now, I've decided to include only the over-the-air link
ID in the API. I know we discussed that we eventually need to
have to have other ways of identifying a link, but for local
AP mode and auth/assoc commands as well as set_key etc. we'll
use the OTA ID.
Also included in this patch is some refactoring of the data
structures in struct wireless_dev, splitting for the first
time the data into type dependent pieces, to make reasoning
about these things easier.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/wext-compat.c')
-rw-r--r-- | net/wireless/wext-compat.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index a32065d600a1..a9767bfe7330 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -7,7 +7,7 @@ * we directly assign the wireless handlers of wireless interfaces. * * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net> - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2022 Intel Corporation */ #include <linux/export.h> @@ -415,6 +415,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, int err, i; bool rejoin = false; + if (wdev->valid_links) + return -EINVAL; + if (pairwise && !addr) return -EINVAL; @@ -437,7 +440,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, return -EOPNOTSUPP; if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - if (!wdev->current_bss) + if (!wdev->connected) return -ENOLINK; if (!rdev->ops->set_default_mgmt_key) @@ -450,7 +453,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if (remove) { err = 0; - if (wdev->current_bss) { + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) { /* * If removing the current TX key, we will need to * join a new IBSS without the privacy bit clear. @@ -501,7 +506,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, return -EINVAL; err = 0; - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 && params->cipher != WLAN_CIPHER_SUITE_WEP104) @@ -526,7 +533,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || params->cipher == WLAN_CIPHER_SUITE_WEP104) && (tx_key || (!addr && wdev->wext.default_key == -1))) { - if (wdev->current_bss) { + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) { /* * If we are getting a new TX key from not having * had one before we need to join a new IBSS with @@ -549,7 +558,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_set_default_mgmt_key(rdev, dev, idx); if (!err) wdev->wext.default_mgmt_key = idx; @@ -595,6 +606,11 @@ static int cfg80211_wext_siwencode(struct net_device *dev, return -EOPNOTSUPP; wiphy_lock(&rdev->wiphy); + if (wdev->valid_links) { + err = -EOPNOTSUPP; + goto out; + } + idx = erq->flags & IW_ENCODE_INDEX; if (idx == 0) { idx = wdev->wext.default_key; @@ -613,7 +629,9 @@ static int cfg80211_wext_siwencode(struct net_device *dev, /* No key data - just set the default TX key index */ err = 0; wdev_lock(wdev); - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_set_default_key(rdev, dev, idx, true, true); if (!err) @@ -865,7 +883,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, break; } - ret = rdev_get_channel(rdev, wdev, &chandef); + ret = rdev_get_channel(rdev, wdev, 0, &chandef); if (ret) break; freq->m = chandef.chan->center_freq; @@ -1270,7 +1288,10 @@ static int cfg80211_wext_siwrate(struct net_device *dev, return -EINVAL; wiphy_lock(&rdev->wiphy); - ret = rdev_set_bitrate_mask(rdev, dev, NULL, &mask); + if (dev->ieee80211_ptr->valid_links) + ret = -EOPNOTSUPP; + else + ret = rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask); wiphy_unlock(&rdev->wiphy); return ret; @@ -1294,8 +1315,9 @@ static int cfg80211_wext_giwrate(struct net_device *dev, err = 0; wdev_lock(wdev); - if (wdev->current_bss) - memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN); + if (!wdev->valid_links && wdev->links[0].client.current_bss) + memcpy(addr, wdev->links[0].client.current_bss->pub.bssid, + ETH_ALEN); else err = -EOPNOTSUPP; wdev_unlock(wdev); @@ -1339,11 +1361,11 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) /* Grab BSSID of current BSS, if any */ wdev_lock(wdev); - if (!wdev->current_bss) { + if (wdev->valid_links || !wdev->links[0].client.current_bss) { wdev_unlock(wdev); return NULL; } - memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); + memcpy(bssid, wdev->links[0].client.current_bss->pub.bssid, ETH_ALEN); wdev_unlock(wdev); memset(&sinfo, 0, sizeof(sinfo)); |