mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-17 10:20:01 +00:00
mac80211: backport fix for nl80211 control port tx (fixes FS#3857)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry-picked from commit de49957300
)
This commit is contained in:
parent
4c29ff7cb8
commit
ccbe535604
@ -0,0 +1,116 @@
|
|||||||
|
From: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||||
|
Date: Sat, 6 Feb 2021 12:51:12 +0100
|
||||||
|
Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port
|
||||||
|
|
||||||
|
This patch unifies sending control port frames
|
||||||
|
over nl80211 and AF_PACKET sockets a little more.
|
||||||
|
|
||||||
|
Before this patch, EAPOL frames got QoS prioritization
|
||||||
|
only when using AF_PACKET sockets.
|
||||||
|
|
||||||
|
__ieee80211_select_queue only selects a QoS-enabled queue
|
||||||
|
for control port frames, when the control port protocol
|
||||||
|
is set correctly on the skb. For the AF_PACKET path this
|
||||||
|
works, but the nl80211 path used ETH_P_802_3.
|
||||||
|
|
||||||
|
Another check for injected frames in wme.c then prevented
|
||||||
|
the QoS TID to be copied in the frame.
|
||||||
|
|
||||||
|
In order to fix this, get rid of the frame injection marking
|
||||||
|
for nl80211 ctrl port and set the correct ethernet protocol.
|
||||||
|
|
||||||
|
Please note:
|
||||||
|
An erlier version of this path tried to prevent
|
||||||
|
frame aggregation for control port frames in order to speed up
|
||||||
|
the initial connection setup a little. This seemed to cause
|
||||||
|
issues on my older Intel dvm-based hardware, and was therefore
|
||||||
|
removed again. Future commits which try to reintroduce this
|
||||||
|
have to check carefully how hw behaves with aggregated and
|
||||||
|
non-aggregated traffic for the same TID.
|
||||||
|
My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74
|
||||||
|
|
||||||
|
Reported-by: kernel test robot <lkp@intel.com>
|
||||||
|
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||||
|
Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/status.c
|
||||||
|
+++ b/net/mac80211/status.c
|
||||||
|
@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str
|
||||||
|
u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
|
||||||
|
struct ieee80211_sub_if_data *sdata;
|
||||||
|
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||||
|
- __be16 ethertype = 0;
|
||||||
|
-
|
||||||
|
- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
|
||||||
|
- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
sdata = ieee80211_sdata_from_skb(local, skb);
|
||||||
|
if (sdata) {
|
||||||
|
- if (ethertype == sdata->control_port_protocol ||
|
||||||
|
- ethertype == cpu_to_be16(ETH_P_PREAUTH))
|
||||||
|
+ if (skb->protocol == sdata->control_port_protocol ||
|
||||||
|
+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH))
|
||||||
|
cfg80211_control_port_tx_status(&sdata->wdev,
|
||||||
|
cookie,
|
||||||
|
skb->data,
|
||||||
|
--- a/net/mac80211/tx.c
|
||||||
|
+++ b/net/mac80211/tx.c
|
||||||
|
@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||||
|
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||||
|
if (!tx->sta && sdata->wdev.use_4addr)
|
||||||
|
return TX_DROP;
|
||||||
|
- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||||
|
- IEEE80211_TX_CTL_INJECTED) ||
|
||||||
|
- tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||||
|
+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||||
|
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||||
|
}
|
||||||
|
if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||||
|
@@ -5421,6 +5419,7 @@ int ieee80211_tx_control_port(struct wip
|
||||||
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
+ struct sta_info *sta;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct ethhdr *ehdr;
|
||||||
|
u32 ctrl_flags = 0;
|
||||||
|
@@ -5443,8 +5442,7 @@ int ieee80211_tx_control_port(struct wip
|
||||||
|
if (cookie)
|
||||||
|
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||||
|
|
||||||
|
- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||||
|
- IEEE80211_TX_CTL_INJECTED;
|
||||||
|
+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
|
||||||
|
|
||||||
|
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||||
|
sizeof(struct ethhdr) + len);
|
||||||
|
@@ -5461,10 +5459,25 @@ int ieee80211_tx_control_port(struct wip
|
||||||
|
ehdr->h_proto = proto;
|
||||||
|
|
||||||
|
skb->dev = dev;
|
||||||
|
- skb->protocol = htons(ETH_P_802_3);
|
||||||
|
+ skb->protocol = proto;
|
||||||
|
skb_reset_network_header(skb);
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
|
|
||||||
|
+ /* update QoS header to prioritize control port frames if possible,
|
||||||
|
+ * priorization also happens for control port frames send over
|
||||||
|
+ * AF_PACKET
|
||||||
|
+ */
|
||||||
|
+ rcu_read_lock();
|
||||||
|
+
|
||||||
|
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) {
|
||||||
|
+ u16 queue = __ieee80211_select_queue(sdata, sta, skb);
|
||||||
|
+
|
||||||
|
+ skb_set_queue_mapping(skb, queue);
|
||||||
|
+ skb_get_hash(skb);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+
|
||||||
|
/* mutex lock is only needed for incrementing the cookie counter */
|
||||||
|
mutex_lock(&local->mtx);
|
||||||
|
|
@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|||||||
*
|
*
|
||||||
* Transmit and frame generation functions.
|
* Transmit and frame generation functions.
|
||||||
*/
|
*/
|
||||||
@@ -1403,8 +1403,17 @@ static void ieee80211_txq_enqueue(struct
|
@@ -1401,8 +1401,17 @@ static void ieee80211_txq_enqueue(struct
|
||||||
ieee80211_set_skb_enqueue_time(skb);
|
ieee80211_set_skb_enqueue_time(skb);
|
||||||
|
|
||||||
spin_lock_bh(&fq->lock);
|
spin_lock_bh(&fq->lock);
|
||||||
@ -48,7 +48,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|||||||
spin_unlock_bh(&fq->lock);
|
spin_unlock_bh(&fq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3846,6 +3855,9 @@ bool ieee80211_txq_airtime_check(struct
|
@@ -3844,6 +3853,9 @@ bool ieee80211_txq_airtime_check(struct
|
||||||
if (!txq->sta)
|
if (!txq->sta)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|||||||
|
|
||||||
--- a/net/mac80211/tx.c
|
--- a/net/mac80211/tx.c
|
||||||
+++ b/net/mac80211/tx.c
|
+++ b/net/mac80211/tx.c
|
||||||
@@ -4173,6 +4173,9 @@ static bool ieee80211_tx_8023(struct iee
|
@@ -4171,6 +4171,9 @@ static bool ieee80211_tx_8023(struct iee
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int q = info->hw_queue;
|
int q = info->hw_queue;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
.rate_init = minstrel_ht_rate_init,
|
.rate_init = minstrel_ht_rate_init,
|
||||||
--- a/net/mac80211/tx.c
|
--- a/net/mac80211/tx.c
|
||||||
+++ b/net/mac80211/tx.c
|
+++ b/net/mac80211/tx.c
|
||||||
@@ -3933,6 +3933,29 @@ void ieee80211_txq_schedule_start(struct
|
@@ -3931,6 +3931,29 @@ void ieee80211_txq_schedule_start(struct
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
u32 info_flags,
|
u32 info_flags,
|
||||||
@@ -3963,6 +3986,8 @@ void __ieee80211_subif_start_xmit(struct
|
@@ -3961,6 +3984,8 @@ void __ieee80211_subif_start_xmit(struct
|
||||||
skb_get_hash(skb);
|
skb_get_hash(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
if (sta) {
|
if (sta) {
|
||||||
struct ieee80211_fast_tx *fast_tx;
|
struct ieee80211_fast_tx *fast_tx;
|
||||||
|
|
||||||
@@ -4226,6 +4251,8 @@ static void ieee80211_8023_xmit(struct i
|
@@ -4224,6 +4249,8 @@ static void ieee80211_8023_xmit(struct i
|
||||||
|
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
|
|
||||||
--- a/net/mac80211/tx.c
|
--- a/net/mac80211/tx.c
|
||||||
+++ b/net/mac80211/tx.c
|
+++ b/net/mac80211/tx.c
|
||||||
@@ -1780,8 +1780,6 @@ static int invoke_tx_handlers_early(stru
|
@@ -1778,8 +1778,6 @@ static int invoke_tx_handlers_early(stru
|
||||||
CALL_TXH(ieee80211_tx_h_ps_buf);
|
CALL_TXH(ieee80211_tx_h_ps_buf);
|
||||||
CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
|
CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
|
||||||
CALL_TXH(ieee80211_tx_h_select_key);
|
CALL_TXH(ieee80211_tx_h_select_key);
|
||||||
@ -19,7 +19,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
|
|
||||||
txh_done:
|
txh_done:
|
||||||
if (unlikely(res == TX_DROP)) {
|
if (unlikely(res == TX_DROP)) {
|
||||||
@@ -1814,6 +1812,9 @@ static int invoke_tx_handlers_late(struc
|
@@ -1812,6 +1810,9 @@ static int invoke_tx_handlers_late(struc
|
||||||
goto txh_done;
|
goto txh_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||||
CALL_TXH(ieee80211_tx_h_sequence);
|
CALL_TXH(ieee80211_tx_h_sequence);
|
||||||
CALL_TXH(ieee80211_tx_h_fragment);
|
CALL_TXH(ieee80211_tx_h_fragment);
|
||||||
@@ -3384,15 +3385,21 @@ out:
|
@@ -3382,15 +3383,21 @@ out:
|
||||||
* Can be called while the sta lock is held. Anything that can cause packets to
|
* Can be called while the sta lock is held. Anything that can cause packets to
|
||||||
* be generated will cause deadlock!
|
* be generated will cause deadlock!
|
||||||
*/
|
*/
|
||||||
@ -55,7 +55,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
if (key)
|
if (key)
|
||||||
info->control.hw_key = &key->conf;
|
info->control.hw_key = &key->conf;
|
||||||
|
|
||||||
@@ -3441,6 +3448,8 @@ static void ieee80211_xmit_fast_finish(s
|
@@ -3439,6 +3446,8 @@ static void ieee80211_xmit_fast_finish(s
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||||
@@ -3544,24 +3553,17 @@ static bool ieee80211_xmit_fast(struct i
|
@@ -3542,24 +3551,17 @@ static bool ieee80211_xmit_fast(struct i
|
||||||
tx.sta = sta;
|
tx.sta = sta;
|
||||||
tx.key = fast_tx->key;
|
tx.key = fast_tx->key;
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||||
sdata = container_of(sdata->bss,
|
sdata = container_of(sdata->bss,
|
||||||
@@ -3672,8 +3674,12 @@ begin:
|
@@ -3670,8 +3672,12 @@ begin:
|
||||||
(tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
|
(tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
|
||||||
pn_offs = ieee80211_hdrlen(hdr->frame_control);
|
pn_offs = ieee80211_hdrlen(hdr->frame_control);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
|||||||
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
||||||
} else if (tx->sta)
|
} else if (tx->sta)
|
||||||
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
||||||
@@ -3662,8 +3664,16 @@ begin:
|
@@ -3660,8 +3662,16 @@ begin:
|
||||||
else
|
else
|
||||||
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
int tid;
|
int tid;
|
||||||
|
|
||||||
memset(tx, 0, sizeof(*tx));
|
memset(tx, 0, sizeof(*tx));
|
||||||
@@ -1202,8 +1226,10 @@ ieee80211_tx_prepare(struct ieee80211_su
|
@@ -1200,8 +1224,10 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||||
tx->sdata->control_port_protocol == tx->skb->protocol) {
|
} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||||
}
|
}
|
||||||
- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||||
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
|
if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
|
||||||
@@ -1213,8 +1239,12 @@ ieee80211_tx_prepare(struct ieee80211_su
|
@@ -1211,8 +1237,12 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||||
struct tid_ampdu_tx *tid_tx;
|
struct tid_ampdu_tx *tid_tx;
|
||||||
|
|
||||||
tid = ieee80211_get_tid(hdr);
|
tid = ieee80211_get_tid(hdr);
|
||||||
@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
if (tid_tx) {
|
if (tid_tx) {
|
||||||
bool queued;
|
bool queued;
|
||||||
|
|
||||||
@@ -3949,29 +3979,6 @@ void ieee80211_txq_schedule_start(struct
|
@@ -3947,29 +3977,6 @@ void ieee80211_txq_schedule_start(struct
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user