Message ID | 1476118360-29009-1-git-send-email-michael-dev@fami-braun.de (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Johannes Berg |
Headers | show |
On Mon, 2016-10-10 at 18:52 +0200, Michael Braun wrote: > According to IEEE 802.11-2012 section 8.3.2 table 8-19, the outer > SA/DA of A-MSDU frames need to be changed depending on FromDS/ToDS > values. "Need to" is perhaps a bit strongly worded, but whatever :) I was going to write a long reply and whatever - but I think that's all moot. As far as I can tell, you got this completely wrong, as you're changing the *inner* headers, not the *outer* header as you should? johannes
On Wed, 2016-10-12 at 09:53 +0200, Johannes Berg wrote: > On Mon, 2016-10-10 at 18:52 +0200, Michael Braun wrote: > > > > According to IEEE 802.11-2012 section 8.3.2 table 8-19, the outer > > SA/DA of A-MSDU frames need to be changed depending on FromDS/ToDS > > values. > > "Need to" is perhaps a bit strongly worded, but whatever :) > > I was going to write a long reply and whatever - but I think that's > all moot. As far as I can tell, you got this completely wrong, as > you're changing the *inner* headers, not the *outer* header as you > should? Oh, no, my mistake - this happens before 802.3->.11 conversion. So this does look correct, but I don't like that you write to amsdu_hdr.h_{source,dest} twice after the patch. I think you should have da and sa variables and set those, and then memcpy only once. johannes
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5023966..acd334c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3050,7 +3050,7 @@ static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata, int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header); int subframe_len = skb->len - hdr_len; void *data; - u8 *qc; + u8 *qc, *bssid; if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) return false; @@ -3062,10 +3062,32 @@ static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata, &subframe_len)) return false; + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: + bssid = sdata->u.mgd.bssid; + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + bssid = sdata->vif.addr; + break; + default: + bssid = NULL; + } + amsdu_hdr.h_proto = cpu_to_be16(subframe_len); memcpy(amsdu_hdr.h_source, skb->data + fast_tx->sa_offs, ETH_ALEN); memcpy(amsdu_hdr.h_dest, skb->data + fast_tx->da_offs, ETH_ALEN); + /* according to IEEE 802.11-2012 8.3.2 table 8-19, the outer SA/DA + * fields needs to be changed to BSSID for A-MSDU frames depending + * on FromDS/ToDS values. + */ + hdr = data; + if (bssid && ieee80211_has_fromds(hdr->frame_control)) + memcpy(amsdu_hdr.h_source, bssid, ETH_ALEN); + if (bssid && ieee80211_has_tods(hdr->frame_control)) + memcpy(amsdu_hdr.h_dest, bssid, ETH_ALEN); + data = skb_push(skb, sizeof(amsdu_hdr)); memmove(data, data + sizeof(amsdu_hdr), hdr_len); memcpy(data + hdr_len, &amsdu_hdr, sizeof(amsdu_hdr));
According to IEEE 802.11-2012 section 8.3.2 table 8-19, the outer SA/DA of A-MSDU frames need to be changed depending on FromDS/ToDS values. Signed-off-by: Michael Braun <michael-dev@fami-braun.de> --- net/mac80211/tx.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)