6109bc2e8754ef4de8e5e0a1300228424005e437
[openwrt.git] / package / kernel / mac80211 / patches / 312-mac80211-don-t-look-up-destination-station-twice.patch
1 From: Johannes Berg <johannes.berg@intel.com>
2 Date: Fri, 20 Mar 2015 16:24:21 +0100
3 Subject: [PATCH] mac80211: don't look up destination station twice
4
5 There's no need to look up the destination station twice while
6 building the 802.11 header for a given frame if the frame will
7 actually be transmitted to the station we initially looked up.
8
9 This happens for 4-addr VLAN interfaces and TDLS connections, which
10 both directly send the frame to the station they looked up, though
11 in the case of TDLS some station conditions need to be checked.
12
13 To avoid that, add a variable indicating that we've looked up the
14 station that the frame is going to be transmitted to, and avoid the
15 lookup/flag checking if it already has been done.
16
17 In the TDLS case, also move the authorized/wme_sta flag assignment
18 to the correct place, i.e. only when that station is really used.
19 Before this change, the new lookup should always have succeeded so
20 that the potentially erroneous data would be overwritten.
21
22 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
23 ---
24
25 --- a/net/mac80211/tx.c
26 +++ b/net/mac80211/tx.c
27 @@ -1895,6 +1895,7 @@ static struct sk_buff *ieee80211_build_h
28         bool wme_sta = false, authorized = false, tdls_auth = false;
29         bool tdls_peer = false, tdls_setup_frame = false;
30         bool multicast;
31 +       bool have_station = false;
32         u16 info_id = 0;
33         struct ieee80211_chanctx_conf *chanctx_conf;
34         struct ieee80211_sub_if_data *ap_sdata;
35 @@ -1919,6 +1920,7 @@ static struct sk_buff *ieee80211_build_h
36                         hdrlen = 30;
37                         authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
38                         wme_sta = sta->sta.wme;
39 +                       have_station = true;
40                 }
41                 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
42                                         u.ap);
43 @@ -2035,9 +2037,6 @@ static struct sk_buff *ieee80211_build_h
44                 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
45                         sta = sta_info_get(sdata, skb->data);
46                         if (sta) {
47 -                               authorized = test_sta_flag(sta,
48 -                                                       WLAN_STA_AUTHORIZED);
49 -                               wme_sta = sta->sta.wme;
50                                 tdls_peer = test_sta_flag(sta,
51                                                           WLAN_STA_TDLS_PEER);
52                                 tdls_auth = test_sta_flag(sta,
53 @@ -2069,6 +2068,9 @@ static struct sk_buff *ieee80211_build_h
54                         memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
55                         memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
56                         hdrlen = 24;
57 +                       have_station = true;
58 +                       authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
59 +                       wme_sta = sta->sta.wme;
60                 }  else if (sdata->u.mgd.use_4addr &&
61                             cpu_to_be16(ethertype) != sdata->control_port_protocol) {
62                         fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
63 @@ -2131,7 +2133,7 @@ static struct sk_buff *ieee80211_build_h
64          * in AP mode)
65          */
66         multicast = is_multicast_ether_addr(hdr.addr1);
67 -       if (!multicast) {
68 +       if (!multicast && !have_station) {
69                 sta = sta_info_get(sdata, hdr.addr1);
70                 if (sta) {
71                         authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);