diff mbox series

[1/5] mac80211: Random MAC address for a Management frame exchange

Message ID 20200425155713.25687-1-jouni@codeaurora.org (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series [1/5] mac80211: Random MAC address for a Management frame exchange | expand

Commit Message

Jouni Malinen April 25, 2020, 3:57 p.m. UTC
Allow user space to use a temporary random MAC address for a Management
frame exchange with drivers that indicate support for this. The main use
for this is to allow GAS/ANQP exchanges to be performed before a
connection without having to expose a persistent MAC address similarly
to the way active scanning can be done with a random MAC address.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 net/mac80211/ieee80211_i.h | 3 +++
 net/mac80211/offchannel.c  | 9 +++++++++
 net/mac80211/rx.c          | 5 +++++
 3 files changed, 17 insertions(+)

Comments

Johannes Berg April 29, 2020, 2:14 p.m. UTC | #1
On Sat, 2020-04-25 at 18:57 +0300, Jouni Malinen wrote:

> +++ b/net/mac80211/offchannel.c
> @@ -955,6 +955,12 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>  		IEEE80211_SKB_CB(skb)->hw_queue =
>  			local->hw.offchannel_tx_hw_queue;
>  
> +	/* remember a random MAC address for Management frame exchange */
> +	if (wiphy_ext_feature_isset(wiphy,
> +				    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA) &&
> +	    !ether_addr_equal(mgmt->sa, wdev_address(wdev)))
> +		memcpy(local->mgmt_tx_rand_addr, mgmt->sa, ETH_ALEN);
> +
>  	/* This will handle all kinds of coalescing and immediate TX */
>  	ret = ieee80211_start_roc_work(local, sdata, params->chan,
>  				       params->wait, cookie, skb,

This feels wrong to me. It seems it should be made part of the roc work
item, and only copied over when that item actually starts, and also used
to not coalesce different items if they specify conflicting temporary
addresses.

> @@ -971,6 +977,9 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
>  {
>  	struct ieee80211_local *local = wiphy_priv(wiphy);
>  
> +	/* stop using the random MAC address for Management frame exchange */
> +	eth_zero_addr(local->mgmt_tx_rand_addr);
> +
>  	return ieee80211_cancel_roc(local, cookie, true);

Similar here, not clear that the ROC item even started yet at this
point.

It seems to me it needs to be pushed a layer deeper, say into
ieee80211_handle_roc_started() and ieee80211_offchannel_return() or so.

johannes
diff mbox series

Patch

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9407cf44305c..d58f9acc90a3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1251,6 +1251,9 @@  struct ieee80211_local {
 	struct timer_list sta_cleanup;
 	int sta_generation;
 
+	/* temporary random address for a Management frame exchange */
+	u8 mgmt_tx_rand_addr[ETH_ALEN];
+
 	struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
 	struct tasklet_struct tx_pending_tasklet;
 	struct tasklet_struct wake_txqs_tasklet;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index db3b8bf75656..afdfced696ec 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -955,6 +955,12 @@  int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		IEEE80211_SKB_CB(skb)->hw_queue =
 			local->hw.offchannel_tx_hw_queue;
 
+	/* remember a random MAC address for Management frame exchange */
+	if (wiphy_ext_feature_isset(wiphy,
+				    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA) &&
+	    !ether_addr_equal(mgmt->sa, wdev_address(wdev)))
+		memcpy(local->mgmt_tx_rand_addr, mgmt->sa, ETH_ALEN);
+
 	/* This will handle all kinds of coalescing and immediate TX */
 	ret = ieee80211_start_roc_work(local, sdata, params->chan,
 				       params->wait, cookie, skb,
@@ -971,6 +977,9 @@  int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 
+	/* stop using the random MAC address for Management frame exchange */
+	eth_zero_addr(local->mgmt_tx_rand_addr);
+
 	return ieee80211_cancel_roc(local, cookie, true);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index eaf8931e4627..60dc2406171f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3898,6 +3898,7 @@  EXPORT_SYMBOL(ieee80211_mark_rx_ba_filtered_frames);
 static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 {
 	struct ieee80211_sub_if_data *sdata = rx->sdata;
+	struct ieee80211_local *local = sdata->local;
 	struct sk_buff *skb = rx->skb;
 	struct ieee80211_hdr *hdr = (void *)skb->data;
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
@@ -3912,6 +3913,10 @@  static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 			return false;
 		if (multicast)
 			return true;
+		if (is_valid_ether_addr(local->mgmt_tx_rand_addr) &&
+		    ether_addr_equal(local->mgmt_tx_rand_addr, hdr->addr1))
+			return true;
+
 		return ether_addr_equal(sdata->vif.addr, hdr->addr1);
 	case NL80211_IFTYPE_ADHOC:
 		if (!bssid)