Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: Use the right headroom size for mesh mgmt frames

Use local->tx_headroom instad of local->hw.extra_tx_headroom.
local->tx_headroom is the max of hw.extra_tx_headroom required by the
driver and the headroom required by mac80211 for status reporting. On
drivers where hw.extra_tx_headroom is smaller than what mac80211
requires (e.g. ath5k), we would not reserve sufficient buffer space to
report tx status.

Also, don't reserve local->tx_headroom + local->hw.extra_tx_headroom.

Reported-by: Simon Morgenthaler <s.morgenthaler@students.unibe.ch>
Reported-by: Kai Scharwies <kai@scharwies.de>
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Javier Cardona and committed by
John W. Linville
65e8b0cc f96b08a7

+6 -6
+4 -4
net/mac80211/mesh_hwmp.c
··· 119 119 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + 120 120 sizeof(mgmt->u.action.u.mesh_action); 121 121 122 - skb = dev_alloc_skb(local->hw.extra_tx_headroom + 122 + skb = dev_alloc_skb(local->tx_headroom + 123 123 hdr_len + 124 124 2 + 37); /* max HWMP IE */ 125 125 if (!skb) 126 126 return -1; 127 - skb_reserve(skb, local->hw.extra_tx_headroom); 127 + skb_reserve(skb, local->tx_headroom); 128 128 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 129 129 memset(mgmt, 0, hdr_len); 130 130 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | ··· 250 250 if (time_before(jiffies, ifmsh->next_perr)) 251 251 return -EAGAIN; 252 252 253 - skb = dev_alloc_skb(local->hw.extra_tx_headroom + 253 + skb = dev_alloc_skb(local->tx_headroom + 254 254 hdr_len + 255 255 2 + 15 /* PERR IE */); 256 256 if (!skb) 257 257 return -1; 258 - skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); 258 + skb_reserve(skb, local->tx_headroom); 259 259 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 260 260 memset(mgmt, 0, hdr_len); 261 261 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+2 -2
net/mac80211/mesh_plink.c
··· 172 172 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + 173 173 sizeof(mgmt->u.action.u.self_prot); 174 174 175 - skb = dev_alloc_skb(local->hw.extra_tx_headroom + 175 + skb = dev_alloc_skb(local->tx_headroom + 176 176 hdr_len + 177 177 2 + /* capability info */ 178 178 2 + /* AID */ ··· 186 186 sdata->u.mesh.ie_len); 187 187 if (!skb) 188 188 return -1; 189 - skb_reserve(skb, local->hw.extra_tx_headroom); 189 + skb_reserve(skb, local->tx_headroom); 190 190 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 191 191 memset(mgmt, 0, hdr_len); 192 192 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |