aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-04-16 06:51:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-22 15:20:15 -0400
commitab11bb28fb3b047f0e5c275d4530519cd2323c8d (patch)
treef9f57a4491ffaab9671af0daad50add089997774 /drivers/net/wireless/ath
parentecbbed32e7c2ad7d9a6305b02e11502b51f2605c (diff)
ath9k: always set common->macaddr to the MAC adress of a virtual interface
In some cases it can be useful to change the MAC address of a virtual interface to something that's completely different from the EEPROM stored MAC address. In this case it is a bad idea to use the EEPROM MAC address for calculating the BSSID mask, as that would make it too wide. In one case a few devices have been observed to send ACKs for many packets on the channel not directed at them, which results in a neat Denial of Service attack on the channel. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c9
2 files changed, 10 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 86d35726edb4..1915f12328b3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -658,11 +658,10 @@ enum sc_op_flags {
658struct ath_rate_table; 658struct ath_rate_table;
659 659
660struct ath9k_vif_iter_data { 660struct ath9k_vif_iter_data {
661 const u8 *hw_macaddr; /* phy's hardware address, set 661 u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
662 * before starting iteration for
663 * valid bssid mask.
664 */
665 u8 mask[ETH_ALEN]; /* bssid mask */ 662 u8 mask[ETH_ALEN]; /* bssid mask */
663 bool has_hw_macaddr;
664
666 int naps; /* number of AP vifs */ 665 int naps; /* number of AP vifs */
667 int nmeshes; /* number of mesh vifs */ 666 int nmeshes; /* number of mesh vifs */
668 int nstations; /* number of station vifs */ 667 int nstations; /* number of station vifs */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a383483d0387..6963862a1872 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
839 struct ath9k_vif_iter_data *iter_data = data; 839 struct ath9k_vif_iter_data *iter_data = data;
840 int i; 840 int i;
841 841
842 if (iter_data->hw_macaddr) 842 if (iter_data->has_hw_macaddr) {
843 for (i = 0; i < ETH_ALEN; i++) 843 for (i = 0; i < ETH_ALEN; i++)
844 iter_data->mask[i] &= 844 iter_data->mask[i] &=
845 ~(iter_data->hw_macaddr[i] ^ mac[i]); 845 ~(iter_data->hw_macaddr[i] ^ mac[i]);
846 } else {
847 memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
848 iter_data->has_hw_macaddr = true;
849 }
846 850
847 switch (vif->type) { 851 switch (vif->type) {
848 case NL80211_IFTYPE_AP: 852 case NL80211_IFTYPE_AP:
@@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
891 * together with the BSSID mask when matching addresses. 895 * together with the BSSID mask when matching addresses.
892 */ 896 */
893 memset(iter_data, 0, sizeof(*iter_data)); 897 memset(iter_data, 0, sizeof(*iter_data));
894 iter_data->hw_macaddr = common->macaddr;
895 memset(&iter_data->mask, 0xff, ETH_ALEN); 898 memset(&iter_data->mask, 0xff, ETH_ALEN);
896 899
897 if (vif) 900 if (vif)
@@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
901 ieee80211_iterate_active_interfaces_atomic( 904 ieee80211_iterate_active_interfaces_atomic(
902 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 905 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
903 ath9k_vif_iter, iter_data); 906 ath9k_vif_iter, iter_data);
907
908 memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
904} 909}
905 910
906/* Called with sc->mutex held. */ 911/* Called with sc->mutex held. */