]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
mac80211: always account for A-MSDU header changes
authorJohannes Berg <johannes.berg@intel.com>
Thu, 30 Aug 2018 08:55:49 +0000 (10:55 +0200)
committerJuerg Haefliger <juergh@canonical.com>
Wed, 24 Jul 2019 01:52:01 +0000 (19:52 -0600)
BugLink: https://bugs.launchpad.net/bugs/1836426
[ Upstream commit aa58acf325b4aadeecae2bfc90658273b47dbace ]

In the error path of changing the SKB headroom of the second
A-MSDU subframe, we would not account for the already-changed
length of the first frame that just got converted to be in
A-MSDU format and thus is a bit longer now.

Fix this by doing the necessary accounting.

It would be possible to reorder the operations, but that would
make the code more complex (to calculate the necessary pad),
and the headroom expansion should not fail frequently enough
to make that worthwhile.

Fixes: 6e0456b54545 ("mac80211: add A-MSDU tx support")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
net/mac80211/tx.c

index 21d7d868e218ce9299bef7a012127b8cd59ad270..ca7874cb9303f8e942f59b43701e9ee261a93ad4 100644 (file)
@@ -3222,7 +3222,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
 
        if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
                                                     2 + pad))
-               goto out;
+               goto out_recalc;
 
        ret = true;
        data = skb_push(skb, ETH_ALEN + 2);
@@ -3239,11 +3239,13 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
        head->data_len += skb->len;
        *frag_tail = skb;
 
-       flow->backlog += head->len - orig_len;
-       tin->backlog_bytes += head->len - orig_len;
-
-       fq_recalc_backlog(fq, tin, flow);
+out_recalc:
+       if (head->len != orig_len) {
+               flow->backlog += head->len - orig_len;
+               tin->backlog_bytes += head->len - orig_len;
 
+               fq_recalc_backlog(fq, tin, flow);
+       }
 out:
        spin_unlock_bh(&fq->lock);