* [PATCH v3 0/2] Support for changing address while powered
@ 2022-08-26 17:00 James Prestwood
2022-08-26 17:00 ` [PATCH v3 1/2] include: nl80211: Add POWERED_ADDR_CHANGE feature James Prestwood
2022-08-26 17:00 ` [PATCH v3 2/2] mac80211: Support " James Prestwood
0 siblings, 2 replies; 3+ messages in thread
From: James Prestwood @ 2022-08-26 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: James Prestwood
v1 -> v2:
- Renamed the flag from 'LIVE' to 'POWERED'. Live can be interpreted
differently i.e if it means just IFF_UP/powered or if it means
connected. POWERED is more accurate to what this feature does.
- Reworked the logic to check if individual interfaces are busy
rather than globally. Simply checking local->scanning/roc_list
was a large hammer, and puts limitations in that aren't needed.
Now roc_list is traversed and only returns -EBUSY if the actual
interface has ROC work. Similarly the scanning sdata is checked
and -EBUSY is returned if it matches the sdata for which the
address is being changed.
- Only P2P_CLIENT/STATION iftypes are allowed to do a powered address
change. I personally see no reason this is needed for other iftypes
but if we want others to be supported I'm fine adding more.
- Check return of drv_add_interface
v2 -> v3:
- Moved address memcpy directly after eth_mac_addr (only if success)
- Added WARN_ON for drv_add_interface return rather than overwriting
eth_mac_addr's return.
James Prestwood (2):
include: nl80211: Add POWERED_ADDR_CHANGE feature
mac80211: Support POWERED_ADDR_CHANGE feature
include/uapi/linux/nl80211.h | 9 +++++
net/mac80211/iface.c | 71 +++++++++++++++++++++++++++++++++++-
net/mac80211/main.c | 2 +
3 files changed, 80 insertions(+), 2 deletions(-)
--
2.34.3
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 1/2] include: nl80211: Add POWERED_ADDR_CHANGE feature
2022-08-26 17:00 [PATCH v3 0/2] Support for changing address while powered James Prestwood
@ 2022-08-26 17:00 ` James Prestwood
2022-08-26 17:00 ` [PATCH v3 2/2] mac80211: Support " James Prestwood
1 sibling, 0 replies; 3+ messages in thread
From: James Prestwood @ 2022-08-26 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: James Prestwood
Add a new extended feature bit signifying that the wireless hardware
supports changing the MAC address while the underlying net_device is
powered. Note that this has a different meaning from
IFF_LIVE_ADDR_CHANGE as additional restrictions might be imposed by
the hardware, such as:
- No connection is active on this interface, carrier is off
- No scan is in progress
- No offchannel operations are in progress
Signed-off-by: James Prestwood <prestwoj@gmail.com>
---
include/uapi/linux/nl80211.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d9490e3062a7..57ead424a0c3 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -6174,6 +6174,14 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC
* detection.
*
+ * @NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE: Device can perform a MAC address
+ * change without having to bring the underlying network device down
+ * first. For example, in station mode this can be used to vary the
+ * origin MAC address prior to a connection to a new AP for privacy
+ * or other reasons. Note that certain driver specific restrictions
+ * might apply, e.g. no scans in progress, no offchannel operations
+ * in progress, and no active connections.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -6241,6 +6249,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BSS_COLOR,
NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
NL80211_EXT_FEATURE_RADAR_BACKGROUND,
+ NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
--
2.34.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v3 2/2] mac80211: Support POWERED_ADDR_CHANGE feature
2022-08-26 17:00 [PATCH v3 0/2] Support for changing address while powered James Prestwood
2022-08-26 17:00 ` [PATCH v3 1/2] include: nl80211: Add POWERED_ADDR_CHANGE feature James Prestwood
@ 2022-08-26 17:00 ` James Prestwood
1 sibling, 0 replies; 3+ messages in thread
From: James Prestwood @ 2022-08-26 17:00 UTC (permalink / raw)
To: linux-wireless; +Cc: James Prestwood
Adds support in mac80211 for NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE.
The motivation behind this functionality is to fix limitations of
address randomization on frequencies which are disallowed in world
roaming.
The way things work now, if a client wants to randomize their address
per-connection it must power down the device, change the MAC, and
power back up. Here lies a problem since powering down the device
may result in frequencies being disabled (until the regdom is set).
If the desired BSS is on one such frequency the client is unable to
connect once the phy is powered again.
For mac80211 based devices changing the MAC while powered is possible
but currently disallowed (-EBUSY). This patch adds some logic to
allow a MAC change while powered by removing the interface, changing
the MAC, and adding it again. mac80211 will advertise support for
this feature so userspace can determine the best course of action e.g.
disallow address randomization on certain frequencies if not
supported.
There are certain limitations put on this which simplify the logic:
- No active connection
- No offchannel work, including scanning.
Signed-off-by: James Prestwood <prestwoj@gmail.com>
---
net/mac80211/iface.c | 71 ++++++++++++++++++++++++++++++++++++++++++--
net/mac80211/main.c | 2 ++
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 1a9ada411879..8bc168339390 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -199,15 +199,73 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
return ret;
}
+static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_roc_work *roc;
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_sub_if_data *scan_sdata;
+ int ret = 0;
+
+ /* To be the most flexible here we want to only limit changing the
+ * address if the specific interface is doing offchannel work or
+ * scanning.
+ */
+ if (netif_carrier_ok(sdata->dev))
+ return -EBUSY;
+
+ mutex_lock(&local->mtx);
+
+ /* First check no ROC work is happening on this iface */
+ list_for_each_entry(roc, &local->roc_list, list) {
+ if (roc->sdata != sdata)
+ continue;
+
+ if (roc->started) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+ }
+
+ /* And if this iface is scanning */
+ if (local->scanning) {
+ scan_sdata = rcu_dereference_protected(local->scan_sdata,
+ lockdep_is_held(&local->mtx));
+ if (sdata == scan_sdata)
+ ret = -EBUSY;
+ }
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ /* More interface types could be added here but changing the
+ * address while powered makes the most sense in client modes.
+ */
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+unlock:
+ mutex_unlock(&local->mtx);
+ return ret;
+}
+
static int ieee80211_change_mac(struct net_device *dev, void *addr)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
struct sockaddr *sa = addr;
bool check_dup = true;
+ bool live = false;
int ret;
- if (ieee80211_sdata_running(sdata))
- return -EBUSY;
+ if (ieee80211_sdata_running(sdata)) {
+ ret = ieee80211_can_powered_addr_change(sdata);
+ if (ret)
+ return ret;
+
+ live = true;
+ }
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
@@ -217,11 +275,19 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
if (ret)
return ret;
+ if (live)
+ drv_remove_interface(local, sdata);
ret = eth_mac_addr(dev, sa);
if (ret == 0)
memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
+ /* Regardless of eth_mac_addr() return we still want to add the
+ * interface back. This should not fail...
+ */
+ if (live)
+ WARN_ON(drv_add_interface(local, sdata));
+
return ret;
}
@@ -2128,6 +2194,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
sdata->u.mgd.use_4addr = params->use_4addr;
ndev->features |= local->hw.netdev_features;
+ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
ndev->hw_features |= ndev->features &
MAC80211_SUPPORTED_FEATURES_TX;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5a385d4146b9..3aeb5e598263 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -616,6 +616,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS);
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_SCAN_FREQ_KHZ);
+ wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE);
if (!ops->hw_scan) {
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
--
2.34.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-08-26 17:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-26 17:00 [PATCH v3 0/2] Support for changing address while powered James Prestwood
2022-08-26 17:00 ` [PATCH v3 1/2] include: nl80211: Add POWERED_ADDR_CHANGE feature James Prestwood
2022-08-26 17:00 ` [PATCH v3 2/2] mac80211: Support " James Prestwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).