aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2021-06-30 19:08:59 +0200
committerFelix Fietkau <nbd@nbd.name>2021-06-30 19:09:31 +0200
commitde499573006ab4f32ded9fd66a62ec5e0c183e8a (patch)
treed6799945f361239aaf9394859f941700cb3e830d /package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch
parent8bb4437c01ca35a5ac67e391630a1b24cb52dbb7 (diff)
downloadupstream-de499573006ab4f32ded9fd66a62ec5e0c183e8a.tar.gz
upstream-de499573006ab4f32ded9fd66a62ec5e0c183e8a.tar.bz2
upstream-de499573006ab4f32ded9fd66a62ec5e0c183e8a.zip
mac80211: backport fix for nl80211 control port tx (fixes FS#3857)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch
new file mode 100644
index 0000000000..4be011ffec
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch
@@ -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, &ethertype, 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);
+