aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-03-20 08:29:29 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-03-20 11:27:34 -0400
commit5041006c42537cce1d3619521f50c29b3bf0a633 (patch)
tree480a880dc5e7884cd4ff03052e14e39b92215af9
parente8f4fb7c7c6b25dc0495f1fd43b03444f0a5c6e3 (diff)
mac80211: don't look up destination station twice
There's no need to look up the destination station twice while building the 802.11 header for a given frame if the frame will actually be transmitted to the station we initially looked up. This happens for 4-addr VLAN interfaces and TDLS connections, which both directly send the frame to the station they looked up, though in the case of TDLS some station conditions need to be checked. To avoid that, add a variable indicating that we've looked up the station that the frame is going to be transmitted to, and avoid the lookup/flag checking if it already has been done. In the TDLS case, also move the authorized/wme_sta flag assignment to the correct place, i.e. only when that station is really used. Before this change, the new lookup should always have succeeded so that the potentially erroneous data would be overwritten. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/tx.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0bae03bca49e..dcf60ee38b93 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1816,6 +1816,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
1816 bool wme_sta = false, authorized = false, tdls_auth = false; 1816 bool wme_sta = false, authorized = false, tdls_auth = false;
1817 bool tdls_peer = false, tdls_setup_frame = false; 1817 bool tdls_peer = false, tdls_setup_frame = false;
1818 bool multicast; 1818 bool multicast;
1819 bool have_station = false;
1819 u16 info_id = 0; 1820 u16 info_id = 0;
1820 struct ieee80211_chanctx_conf *chanctx_conf; 1821 struct ieee80211_chanctx_conf *chanctx_conf;
1821 struct ieee80211_sub_if_data *ap_sdata; 1822 struct ieee80211_sub_if_data *ap_sdata;
@@ -1840,6 +1841,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
1840 hdrlen = 30; 1841 hdrlen = 30;
1841 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); 1842 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
1842 wme_sta = sta->sta.wme; 1843 wme_sta = sta->sta.wme;
1844 have_station = true;
1843 } 1845 }
1844 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 1846 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
1845 u.ap); 1847 u.ap);
@@ -1956,9 +1958,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
1956 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { 1958 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1957 sta = sta_info_get(sdata, skb->data); 1959 sta = sta_info_get(sdata, skb->data);
1958 if (sta) { 1960 if (sta) {
1959 authorized = test_sta_flag(sta,
1960 WLAN_STA_AUTHORIZED);
1961 wme_sta = sta->sta.wme;
1962 tdls_peer = test_sta_flag(sta, 1961 tdls_peer = test_sta_flag(sta,
1963 WLAN_STA_TDLS_PEER); 1962 WLAN_STA_TDLS_PEER);
1964 tdls_auth = test_sta_flag(sta, 1963 tdls_auth = test_sta_flag(sta,
@@ -1990,6 +1989,9 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
1990 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1989 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
1991 memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN); 1990 memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
1992 hdrlen = 24; 1991 hdrlen = 24;
1992 have_station = true;
1993 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
1994 wme_sta = sta->sta.wme;
1993 } else if (sdata->u.mgd.use_4addr && 1995 } else if (sdata->u.mgd.use_4addr &&
1994 cpu_to_be16(ethertype) != sdata->control_port_protocol) { 1996 cpu_to_be16(ethertype) != sdata->control_port_protocol) {
1995 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | 1997 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
@@ -2052,7 +2054,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
2052 * in AP mode) 2054 * in AP mode)
2053 */ 2055 */
2054 multicast = is_multicast_ether_addr(hdr.addr1); 2056 multicast = is_multicast_ether_addr(hdr.addr1);
2055 if (!multicast) { 2057 if (!multicast && !have_station) {
2056 sta = sta_info_get(sdata, hdr.addr1); 2058 sta = sta_info_get(sdata, hdr.addr1);
2057 if (sta) { 2059 if (sta) {
2058 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); 2060 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);