From de499573006ab4f32ded9fd66a62ec5e0c183e8a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 30 Jun 2021 19:08:59 +0200 Subject: [PATCH] mac80211: backport fix for nl80211 control port tx (fixes FS#3857) Signed-off-by: Felix Fietkau --- ...le-QoS-support-for-nl80211-ctrl-port.patch | 116 ++++++++++++++++++ ...pply-flow-control-on-management-fram.patch | 4 +- ...set-sk_pacing_shift-for-802.3-txpath.patch | 2 +- ...MPDU-session-check-from-minstrel_ht-.patch | 6 +- ...eee80211_tx_h_rate_ctrl-when-dequeue.patch | 12 +- ...te-control-support-for-encap-offload.patch | 2 +- ...rting-aggregation-sessions-on-mesh-i.patch | 8 +- 7 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch 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 0000000000000..4be011ffec0d6 --- /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 +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 +Signed-off-by: Markus Theil +Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de +Signed-off-by: Johannes Berg +--- + +--- 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); + diff --git a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch index b439a3814cc14..8d094a3632eba 100644 --- a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch +++ b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch @@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg * * 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); spin_lock_bh(&fq->lock); @@ -48,7 +48,7 @@ Signed-off-by: Johannes Berg 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) return true; diff --git a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch index 4d8a91a413316..5bc1469a3f127 100644 --- a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch +++ b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch @@ -9,7 +9,7 @@ Signed-off-by: Lorenzo Bianconi --- a/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; int q = info->hw_queue; diff --git a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch index 4e3242e6a9d6f..031f8e16360a8 100644 --- a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch +++ b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch @@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau .rate_init = minstrel_ht_rate_init, --- a/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); @@ -106,7 +106,7 @@ Signed-off-by: Felix Fietkau void __ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev, 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); } @@ -115,7 +115,7 @@ Signed-off-by: Felix Fietkau if (sta) { 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)); diff --git a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch index 49b1212213eff..cf84fca68a349 100644 --- a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch +++ b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch @@ -10,7 +10,7 @@ Signed-off-by: Ryder Lee --- a/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_check_control_port_protocol); CALL_TXH(ieee80211_tx_h_select_key); @@ -19,7 +19,7 @@ Signed-off-by: Ryder Lee txh_done: 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; } @@ -29,7 +29,7 @@ Signed-off-by: Ryder Lee CALL_TXH(ieee80211_tx_h_michael_mic_add); CALL_TXH(ieee80211_tx_h_sequence); 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 * be generated will cause deadlock! */ @@ -55,7 +55,7 @@ Signed-off-by: Ryder Lee if (key) 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; } } @@ -64,7 +64,7 @@ Signed-off-by: Ryder Lee } 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.key = fast_tx->key; @@ -97,7 +97,7 @@ Signed-off-by: Ryder Lee if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, -@@ -3672,8 +3674,12 @@ begin: +@@ -3670,8 +3672,12 @@ begin: (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) pn_offs = ieee80211_hdrlen(hdr->frame_control); diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch index eefeaa4a8d663..43a4a1334df0e 100644 --- a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch +++ b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch @@ -99,7 +99,7 @@ Signed-off-by: Ryder Lee tx->sta->tx_stats.last_rate = txrc.reported_rate; } else if (tx->sta) tx->sta->tx_stats.last_rate = txrc.reported_rate; -@@ -3662,8 +3664,16 @@ begin: +@@ -3660,8 +3662,16 @@ begin: else info->flags &= ~IEEE80211_TX_CTL_AMPDU; diff --git a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch index 56eafaf847950..2ad083f1507e3 100644 --- a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch +++ b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch @@ -54,8 +54,8 @@ Signed-off-by: Felix Fietkau int tid; memset(tx, 0, sizeof(*tx)); -@@ -1202,8 +1226,10 @@ ieee80211_tx_prepare(struct ieee80211_su - tx->sdata->control_port_protocol == tx->skb->protocol) { +@@ -1200,8 +1224,10 @@ ieee80211_tx_prepare(struct ieee80211_su + } 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)) @@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau } 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; tid = ieee80211_get_tid(hdr); @@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau if (tid_tx) { 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);