mac80211: fix regression in skb resizing optimization in monitor mode (FS#2254)
authorFelix Fietkau <nbd@nbd.name>
Wed, 24 Apr 2019 07:32:22 +0000 (09:32 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 24 Apr 2019 07:33:38 +0000 (09:33 +0200)
struct ieee80211_local needs to be passed in separately instead of
dereferencing the (potentially NULL) sdata

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch

index 98b23422653d271122e42c191bb0fd36edff5282..919aa36a48ac52b564ff9bd62d8ec0fbc6ee19fc 100644 (file)
@@ -24,11 +24,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -1761,6 +1761,8 @@ void ieee80211_clear_fast_xmit(struct st
+@@ -1761,6 +1761,9 @@ void ieee80211_clear_fast_xmit(struct st
  int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
                              const u8 *buf, size_t len,
                              const u8 *dest, __be16 proto, bool unencrypted);
-+int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
++int ieee80211_skb_resize(struct ieee80211_local *local,
++                       struct ieee80211_sub_if_data *sdata,
 +                       struct sk_buff *skb, int hdrlen, int hdr_add);
  
  /* HT */
@@ -39,7 +40,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                }
        }
  
-+      if (ieee80211_skb_resize(NULL, skb, 0, 0)) {
++      if (ieee80211_skb_resize(local, NULL, skb, 0, 0)) {
 +              dev_kfree_skb(skb);
 +              return;
 +      }
@@ -57,28 +58,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
 -                              struct sk_buff *skb,
 -                              int head_need, bool may_encrypt)
-+int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
++int ieee80211_skb_resize(struct ieee80211_local *local,
++                       struct ieee80211_sub_if_data *sdata,
 +                       struct sk_buff *skb, int hdr_len, int hdr_extra)
  {
-       struct ieee80211_local *local = sdata->local;
+-      struct ieee80211_local *local = sdata->local;
 +      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr;
 -      bool enc_tailroom;
 -      int tail_need = 0;
--
++      int head_need, head_max;
++      int tail_need, tail_max;
++      bool enc_tailroom = false;
 -      hdr = (struct ieee80211_hdr *) skb->data;
 -      enc_tailroom = may_encrypt &&
 -                     (sdata->crypto_tx_tailroom_needed_cnt ||
 -                      ieee80211_is_mgmt(hdr->frame_control));
--
--      if (enc_tailroom) {
--              tail_need = IEEE80211_ENCRYPT_TAILROOM;
--              tail_need -= skb_tailroom(skb);
--              tail_need = max_t(int, tail_need, 0);
-+      int head_need, head_max;
-+      int tail_need, tail_max;
-+      bool enc_tailroom = false;
-+
 +      if (sdata && !hdr_len &&
 +          !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
 +              hdr = (struct ieee80211_hdr *) skb->data;
@@ -86,7 +82,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +                              ieee80211_is_mgmt(hdr->frame_control));
 +              hdr_len += sdata->encrypt_headroom;
 +      }
-+
+-      if (enc_tailroom) {
+-              tail_need = IEEE80211_ENCRYPT_TAILROOM;
+-              tail_need -= skb_tailroom(skb);
+-              tail_need = max_t(int, tail_need, 0);
 +      head_need = head_max = hdr_len;
 +      tail_need = tail_max = 0;
 +      if (!sdata) {
@@ -129,15 +129,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -      bool may_encrypt;
 -
 -      may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
+-
 -      headroom = local->tx_headroom;
 -      if (may_encrypt)
 -              headroom += sdata->encrypt_headroom;
 -      headroom -= skb_headroom(skb);
 -      headroom = max_t(int, 0, headroom);
--
 -      if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
-+      if (ieee80211_skb_resize(sdata, skb, 0, 0)) {
++      if (ieee80211_skb_resize(local, sdata, skb, 0, 0)) {
                ieee80211_free_txskb(&local->hw, skb);
                return;
        }
@@ -170,7 +170,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -                      skb = NULL;
 -                      return ERR_PTR(-ENOMEM);
 -              }
-+      if (ieee80211_skb_resize(sdata, skb, head_need,
++      if (ieee80211_skb_resize(local, sdata, skb, head_need,
 +                               sdata->encrypt_headroom)) {
 +              ieee80211_free_txskb(&local->hw, skb);
 +              skb = NULL;
@@ -194,7 +194,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -                                        max_t(int, extra_head + hw_headroom -
 -                                                   skb_headroom(skb), 0),
 -                                        false))) {
-+      if (unlikely(ieee80211_skb_resize(sdata, skb, extra_head, 0))) {
++      if (unlikely(ieee80211_skb_resize(local, sdata, skb, extra_head, 0))) {
                kfree_skb(skb);
                return true;
        }