mac80211: backport fix for nl80211 control port tx (fixes FS#3857)
authorFelix Fietkau <nbd@nbd.name>
Wed, 30 Jun 2021 17:08:59 +0000 (19:08 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 30 Jun 2021 17:24:55 +0000 (19:24 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry-picked from commit de499573006ab4f32ded9fd66a62ec5e0c183e8a)

package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch
package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch
package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch
package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch
package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch
package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.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 (file)
index 0000000..4be011f
--- /dev/null
@@ -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);
index b439a3814cc14d3eba080cfd533786aa77977ffa..8d094a3632eba5736283b3a7fc5242ef910bfa42 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
   *
   * 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 <johannes.berg@intel.com>
        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;
  
index 4d8a91a413316dacee2d30910eedad9ee2937e05..5bc1469a3f1273502a39e1a9ec5fe03d7ecac131 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- 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;
  
index 4e3242e6a9d6fd1b34117c50bec723b211542cba..031f8e16360a8412c2b776d520f3a6d68095e197 100644 (file)
@@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        .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 <nbd@nbd.name>
  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 <nbd@nbd.name>
        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));
  
index 49b1212213eff4b000bf72be936be9bfbaeb7d89..cf84fca68a3496c5c3f8a3985973b7e4ccd7ba56 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
 
 --- 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 <ryder.lee@mediatek.com>
  
   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 <ryder.lee@mediatek.com>
        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 <ryder.lee@mediatek.com>
        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 <ryder.lee@mediatek.com>
  }
  
  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 <ryder.lee@mediatek.com>
  
        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);
  
index eefeaa4a8d663519cd7567becf921556ff01b5b0..43a4a1334df0e47276071ba38ee16671c7247f7d 100644 (file)
@@ -99,7 +99,7 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
                        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;
  
index 56eafaf847950febe49939c62986d1219417f88e..2ad083f1507e325cc03f43a0cbf1c627863107ed 100644 (file)
@@ -54,8 +54,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        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 <nbd@nbd.name>
        }
  
        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 <nbd@nbd.name>
                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);