From 8331c9b316eae90c2b1a51c219a1659b68f031a0 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Date: Thu, 8 Dec 2016 21:51:25 +0530 Subject: [PATCH] nl80211: Add support for mgmt_tx with random TA This adds support for specifying a random TA for management frame transmission commands and driver capability flags for indicating whether this is supported in not-connected and connected states. Signed-off-by: Jouni Malinen --- src/drivers/driver.h | 7 +++++++ src/drivers/driver_nl80211.c | 8 ++++++++ src/drivers/driver_nl80211.h | 1 + src/drivers/driver_nl80211_capa.c | 6 ++++++ src/drivers/driver_nl80211_event.c | 2 ++ 5 files changed, 24 insertions(+) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 92688a35d..4fcfaa654 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1393,6 +1393,10 @@ struct wpa_driver_capa { #define WPA_DRIVER_FLAGS_BEACON_RATE_HT 0x0000100000000000ULL /** Driver supports Beacon frame TX rate configuration (VHT rates) */ #define WPA_DRIVER_FLAGS_BEACON_RATE_VHT 0x0000200000000000ULL +/** Driver supports mgmt_tx with random TX address in non-connected state */ +#define WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA 0x0000400000000000ULL +/** Driver supports mgmt_tx with random TX addr in connected state */ +#define WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED 0x0000800000000000ULL u64 flags; #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ @@ -2785,6 +2789,9 @@ struct wpa_driver_ops { * transmitted on that channel; alternatively the frame may be sent on * the current operational channel (if in associated state in station * mode or while operating as an AP.) + * + * If @src differs from the device MAC address, use of a random + * transmitter address is requested for this message exchange. */ int (*send_action)(void *priv, unsigned int freq, unsigned int wait, const u8 *dst, const u8 *src, const u8 *bssid, diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 27e22c6d3..e9107b3bb 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -6881,6 +6881,14 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, os_memcpy(hdr->addr2, src, ETH_ALEN); os_memcpy(hdr->addr3, bssid, ETH_ALEN); + if (os_memcmp(bss->addr, src, ETH_ALEN) != 0) { + wpa_printf(MSG_DEBUG, "nl80211: Use random TA " MACSTR, + MAC2STR(src)); + os_memcpy(bss->rand_addr, src, ETH_ALEN); + } else { + os_memset(bss->rand_addr, 0, ETH_ALEN); + } + if (is_ap_interface(drv->nlmode) && (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) || (int) freq == bss->freq || drv->device_ap_sme || diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 94b8bdf19..c73895c6a 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -78,6 +78,7 @@ struct i802_bss { struct nl80211_wiphy_data *wiphy_data; struct dl_list wiphy_list; + u8 rand_addr[ETH_ALEN]; }; struct wpa_driver_nl80211_data { diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 3d8531684..bc8c94e3f 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -389,6 +389,12 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info, ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_SET_SCAN_DWELL)) capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT; + if (ext_feature_isset(ext_features, len, + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA)) + capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA; + if (ext_feature_isset(ext_features, len, + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED)) + capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED; } diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index c18fc223f..f6014aaec 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -860,6 +860,8 @@ static void mlme_event(struct i802_bss *bss, MAC2STR(data + 4 + ETH_ALEN)); if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) && os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 && + (is_zero_ether_addr(bss->rand_addr) || + os_memcmp(bss->rand_addr, data + 4, ETH_ALEN) != 0) && os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) { wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event " "for foreign address", bss->ifname);