From 6e7e2f4421011435053997c059db61c3e090ab64 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 24 Apr 2019 09:32:22 +0200 Subject: [PATCH] mac80211: fix regression in skb resizing optimization in monitor mode (FS#2254) struct ieee80211_local needs to be passed in separately instead of dereferencing the (potentially NULL) sdata Signed-off-by: Felix Fietkau --- .../357-mac80211-optimize-skb-resizing.patch | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch index 98b2342265..919aa36a48 100644 --- a/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch +++ b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch @@ -24,11 +24,12 @@ Signed-off-by: Felix Fietkau --- 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 } } -+ 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 -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 + 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 - 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 - 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 - 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; } -- 2.30.2