mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-12 18:05:15 +00:00
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 <nbd@nbd.name>
This commit is contained in:
parent
82625374ee
commit
6e7e2f4421
@ -24,11 +24,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
--- a/net/mac80211/ieee80211_i.h
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
+++ b/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,
|
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||||
const u8 *buf, size_t len,
|
const u8 *buf, size_t len,
|
||||||
const u8 *dest, __be16 proto, bool unencrypted);
|
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);
|
+ struct sk_buff *skb, int hdrlen, int hdr_add);
|
||||||
|
|
||||||
/* HT */
|
/* 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);
|
+ dev_kfree_skb(skb);
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
@ -57,28 +58,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
-static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
|
-static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
|
||||||
- struct sk_buff *skb,
|
- struct sk_buff *skb,
|
||||||
- int head_need, bool may_encrypt)
|
- 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 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_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
- bool enc_tailroom;
|
- bool enc_tailroom;
|
||||||
- int tail_need = 0;
|
- int tail_need = 0;
|
||||||
-
|
+ int head_need, head_max;
|
||||||
|
+ int tail_need, tail_max;
|
||||||
|
+ bool enc_tailroom = false;
|
||||||
|
|
||||||
- hdr = (struct ieee80211_hdr *) skb->data;
|
- hdr = (struct ieee80211_hdr *) skb->data;
|
||||||
- enc_tailroom = may_encrypt &&
|
- enc_tailroom = may_encrypt &&
|
||||||
- (sdata->crypto_tx_tailroom_needed_cnt ||
|
- (sdata->crypto_tx_tailroom_needed_cnt ||
|
||||||
- ieee80211_is_mgmt(hdr->frame_control));
|
- 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 &&
|
+ if (sdata && !hdr_len &&
|
||||||
+ !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
|
+ !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
|
||||||
+ hdr = (struct ieee80211_hdr *) skb->data;
|
+ hdr = (struct ieee80211_hdr *) skb->data;
|
||||||
@ -86,7 +82,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ ieee80211_is_mgmt(hdr->frame_control));
|
+ ieee80211_is_mgmt(hdr->frame_control));
|
||||||
+ hdr_len += sdata->encrypt_headroom;
|
+ 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;
|
+ head_need = head_max = hdr_len;
|
||||||
+ tail_need = tail_max = 0;
|
+ tail_need = tail_max = 0;
|
||||||
+ if (!sdata) {
|
+ if (!sdata) {
|
||||||
@ -129,15 +129,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
- bool may_encrypt;
|
- bool may_encrypt;
|
||||||
-
|
-
|
||||||
- may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
|
- may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
|
||||||
|
-
|
||||||
- headroom = local->tx_headroom;
|
- headroom = local->tx_headroom;
|
||||||
- if (may_encrypt)
|
- if (may_encrypt)
|
||||||
- headroom += sdata->encrypt_headroom;
|
- headroom += sdata->encrypt_headroom;
|
||||||
- headroom -= skb_headroom(skb);
|
- headroom -= skb_headroom(skb);
|
||||||
- headroom = max_t(int, 0, headroom);
|
- headroom = max_t(int, 0, headroom);
|
||||||
-
|
|
||||||
- if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
|
- 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);
|
ieee80211_free_txskb(&local->hw, skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -170,7 +170,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
- skb = NULL;
|
- skb = NULL;
|
||||||
- return ERR_PTR(-ENOMEM);
|
- return ERR_PTR(-ENOMEM);
|
||||||
- }
|
- }
|
||||||
+ if (ieee80211_skb_resize(sdata, skb, head_need,
|
+ if (ieee80211_skb_resize(local, sdata, skb, head_need,
|
||||||
+ sdata->encrypt_headroom)) {
|
+ sdata->encrypt_headroom)) {
|
||||||
+ ieee80211_free_txskb(&local->hw, skb);
|
+ ieee80211_free_txskb(&local->hw, skb);
|
||||||
+ skb = NULL;
|
+ skb = NULL;
|
||||||
@ -194,7 +194,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
- max_t(int, extra_head + hw_headroom -
|
- max_t(int, extra_head + hw_headroom -
|
||||||
- skb_headroom(skb), 0),
|
- skb_headroom(skb), 0),
|
||||||
- false))) {
|
- 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);
|
kfree_skb(skb);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user