Search Linux Wireless

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxx>
---
 net/mac80211/ieee80211_i.h | 3 +++
 net/mac80211/offchannel.c  | 9 +++++++++
 net/mac80211/rx.c          | 5 +++++
 3 files changed, 17 insertions(+)

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)
-- 
2.20.1



[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux