diff mbox series

[RFC,2/4] {nl|cfg}80211: Support mac change as part of SME Connect

Message ID 20190904191155.28056-3-prestwoj@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series Allow live MAC address change | expand

Commit Message

James Prestwood Sept. 4, 2019, 7:11 p.m. UTC
---
 include/net/cfg80211.h       |  1 +
 include/uapi/linux/nl80211.h |  1 +
 net/wireless/core.h          |  1 +
 net/wireless/nl80211.c       | 11 +++++++++++
 net/wireless/sme.c           |  7 +++++++
 net/wireless/util.c          | 11 +++++++++++
 6 files changed, 32 insertions(+)
diff mbox series

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5253e7f667bd..25eacbebfa29 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2553,6 +2553,7 @@  struct cfg80211_connect_params {
 	size_t fils_erp_rrk_len;
 	bool want_1x;
 	struct ieee80211_edmg edmg;
+	const u8 *mac_to_use;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 0ceb945a08fb..1bb4ce58da67 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2834,6 +2834,7 @@  enum nl80211_attrs {
 
 	NL80211_ATTR_WIPHY_EDMG_CHANNELS,
 	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
+	NL80211_ATTR_MAC_TO_USE,
 
 	/* add attributes here, update the policy in nl80211.c */
 
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 77556c58d9ac..29e6ab2cf343 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -454,6 +454,7 @@  int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			  struct vif_params *params);
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
 void cfg80211_process_wdev_events(struct wireless_dev *wdev);
+int cfg80211_set_mac_to_use(struct net_device *dev, const u8 *mac);
 
 bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
 				u32 center_freq_khz, u32 bw_khz);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4565d7385884..0202a762b5c8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -591,6 +591,8 @@  const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 					.len = SAE_PASSWORD_MAX_LEN },
 	[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
 	[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
+	[NL80211_ATTR_MAC_TO_USE] = { .type = NLA_EXACT_LEN_WARN,
+				      .len = ETH_ALEN },
 };
 
 /* policy for the key attributes */
@@ -10045,6 +10047,15 @@  static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
 		connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
 	}
 
+	if (info->attrs[NL80211_ATTR_MAC_TO_USE]) {
+		if (!wiphy_ext_feature_isset(wiphy,
+				NL80211_EXT_FEATURE_LIVE_ADDRESS_CHANGE))
+			return -EOPNOTSUPP;
+
+		connect.mac_to_use =
+			nla_data(info->attrs[NL80211_ATTR_MAC_TO_USE]);
+	}
+
 	wdev_lock(dev->ieee80211_ptr);
 
 	err = cfg80211_connect(rdev, dev, &connect, connkeys,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 7a6c38ddc65a..f164af33655f 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1242,11 +1242,18 @@  int cfg80211_connect(struct cfg80211_registered_device *rdev,
 	wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS :
 					      IEEE80211_BSS_TYPE_ESS;
 
+	if (connect->mac_to_use) {
+		err = cfg80211_set_mac_to_use(dev, connect->mac_to_use);
+		if (err)
+			goto fail;
+	}
+
 	if (!rdev->ops->connect)
 		err = cfg80211_sme_connect(wdev, connect, prev_bssid);
 	else
 		err = rdev_connect(rdev, dev, connect);
 
+fail:
 	if (err) {
 		wdev->connect_keys = NULL;
 		/*
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 92cb2cbb179b..06700431cba0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2148,3 +2148,14 @@  bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
 	return false;
 }
 EXPORT_SYMBOL(cfg80211_iftype_allowed);
+
+int cfg80211_set_mac_to_use(struct net_device *dev, const u8 *mac)
+{
+	struct sockaddr sa;
+
+	sa.sa_family = dev->type;
+	memcpy(sa.sa_data, mac, ETH_ALEN);
+
+	return dev_set_mac_address(dev, &sa, NULL);
+}
+EXPORT_SYMBOL(cfg80211_set_mac_to_use);