mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
eae0dbf68c
Signed-off-by: Felix Fietkau <nbd@nbd.name>
51 lines
2.1 KiB
Diff
51 lines
2.1 KiB
Diff
From: Nicolas Escande <nico.escande@gmail.com>
|
|
Date: Mon, 14 Feb 2022 18:32:14 +0100
|
|
Subject: [PATCH] mac80211: fix forwarded mesh frames AC & queue selection
|
|
|
|
There are two problems with the current code that have been highlighted
|
|
with the AQL feature that is now enbaled by default.
|
|
|
|
First problem is in ieee80211_rx_h_mesh_fwding(),
|
|
ieee80211_select_queue_80211() is used on received packets to choose
|
|
the sending AC queue of the forwarding packet although this function
|
|
should only be called on TX packet (it uses ieee80211_tx_info).
|
|
This ends with forwarded mesh packets been sent on unrelated random AC
|
|
queue. To fix that, AC queue can directly be infered from skb->priority
|
|
which has been extracted from QOS info (see ieee80211_parse_qos()).
|
|
|
|
Second problem is the value of queue_mapping set on forwarded mesh
|
|
frames via skb_set_queue_mapping() is not the AC of the packet but a
|
|
hardware queue index. This may or may not work depending on AC to HW
|
|
queue mapping which is driver specific.
|
|
|
|
Both of these issues lead to improper AC selection while forwarding
|
|
mesh packets but more importantly due to improper airtime accounting
|
|
(which is done on a per STA, per AC basis) caused traffic stall with
|
|
the introduction of AQL.
|
|
|
|
Fixes: cf44012810cc ("mac80211: fix unnecessary frame drops in mesh fwding")
|
|
Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping")
|
|
Co-developed-by: Remi Pommarel <repk@triplefau.lt>
|
|
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
|
|
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
|
|
---
|
|
|
|
--- a/net/mac80211/rx.c
|
|
+++ b/net/mac80211/rx.c
|
|
@@ -2921,13 +2921,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
|
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
|
return RX_CONTINUE;
|
|
|
|
- ac = ieee80211_select_queue_80211(sdata, skb, hdr);
|
|
+ ac = ieee802_1d_to_ac[skb->priority];
|
|
q = sdata->vif.hw_queue[ac];
|
|
if (ieee80211_queue_stopped(&local->hw, q)) {
|
|
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
|
return RX_DROP_MONITOR;
|
|
}
|
|
- skb_set_queue_mapping(skb, q);
|
|
+ skb_set_queue_mapping(skb, ac);
|
|
|
|
if (!--mesh_hdr->ttl) {
|
|
if (!is_multicast_ether_addr(hdr->addr1))
|