aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-29 04:38:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-03 15:00:14 -0400
commit23c0752a25d73ccc4547700e8a57d5ae2f2edf56 (patch)
tree225631645bf52c07931adc7aeb766344b05be7eb /net/mac80211/wpa.c
parentf622360bce6facb05fdce4bce5ee4beb2432222d (diff)
mac80211: clean up skb reallocation code
This cleans up the skb reallocation code to avoid problems with skb->truesize, not resize an skb twice for a single output path because we didn't expand it enough during the first copy and also removes the code to further expand it during crypto operations which will no longer be necessary. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r--net/mac80211/wpa.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index d6635f6e5618..9f6fd20374e1 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -79,6 +79,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
79 struct sk_buff *skb = tx->skb; 79 struct sk_buff *skb = tx->skb;
80 int authenticator; 80 int authenticator;
81 int wpa_test = 0; 81 int wpa_test = 0;
82 int tail;
82 83
83 fc = tx->fc; 84 fc = tx->fc;
84 85
@@ -98,16 +99,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
98 return TX_CONTINUE; 99 return TX_CONTINUE;
99 } 100 }
100 101
101 if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { 102 tail = MICHAEL_MIC_LEN;
102 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 103 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
103 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, 104 tail += TKIP_ICV_LEN;
104 MICHAEL_MIC_LEN + TKIP_ICV_LEN, 105
105 GFP_ATOMIC))) { 106 if (WARN_ON(skb_tailroom(skb) < tail ||
106 printk(KERN_DEBUG "%s: failed to allocate more memory " 107 skb_headroom(skb) < TKIP_IV_LEN))
107 "for Michael MIC\n", tx->dev->name); 108 return TX_DROP;
108 return TX_DROP;
109 }
110 }
111 109
112#if 0 110#if 0
113 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ 111 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
@@ -188,7 +186,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
188 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 186 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
189 struct ieee80211_key *key = tx->key; 187 struct ieee80211_key *key = tx->key;
190 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 188 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
191 int hdrlen, len, tailneed; 189 int hdrlen, len, tail;
192 u16 fc; 190 u16 fc;
193 u8 *pos; 191 u8 *pos;
194 192
@@ -199,7 +197,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
199 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 197 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
200 /* hwaccel - with no need for preallocated room for IV/ICV */ 198 /* hwaccel - with no need for preallocated room for IV/ICV */
201 info->control.hw_key = &tx->key->conf; 199 info->control.hw_key = &tx->key->conf;
202 return TX_CONTINUE; 200 return 0;
203 } 201 }
204 202
205 fc = le16_to_cpu(hdr->frame_control); 203 fc = le16_to_cpu(hdr->frame_control);
@@ -207,17 +205,13 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
207 len = skb->len - hdrlen; 205 len = skb->len - hdrlen;
208 206
209 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 207 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
210 tailneed = 0; 208 tail = 0;
211 else 209 else
212 tailneed = TKIP_ICV_LEN; 210 tail = TKIP_ICV_LEN;
213 211
214 if ((skb_headroom(skb) < TKIP_IV_LEN || 212 if (WARN_ON(skb_tailroom(skb) < tail ||
215 skb_tailroom(skb) < tailneed)) { 213 skb_headroom(skb) < TKIP_IV_LEN))
216 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 214 return -1;
217 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed,
218 GFP_ATOMIC)))
219 return -1;
220 }
221 215
222 pos = skb_push(skb, TKIP_IV_LEN); 216 pos = skb_push(skb, TKIP_IV_LEN);
223 memmove(pos, pos + TKIP_IV_LEN, hdrlen); 217 memmove(pos, pos + TKIP_IV_LEN, hdrlen);
@@ -432,7 +426,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
432 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 426 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
433 struct ieee80211_key *key = tx->key; 427 struct ieee80211_key *key = tx->key;
434 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 428 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
435 int hdrlen, len, tailneed; 429 int hdrlen, len, tail;
436 u16 fc; 430 u16 fc;
437 u8 *pos, *pn, *b_0, *aad, *scratch; 431 u8 *pos, *pn, *b_0, *aad, *scratch;
438 int i; 432 int i;
@@ -445,7 +439,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
445 /* hwaccel - with no need for preallocated room for CCMP " 439 /* hwaccel - with no need for preallocated room for CCMP "
446 * header or MIC fields */ 440 * header or MIC fields */
447 info->control.hw_key = &tx->key->conf; 441 info->control.hw_key = &tx->key->conf;
448 return TX_CONTINUE; 442 return 0;
449 } 443 }
450 444
451 scratch = key->u.ccmp.tx_crypto_buf; 445 scratch = key->u.ccmp.tx_crypto_buf;
@@ -457,17 +451,13 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
457 len = skb->len - hdrlen; 451 len = skb->len - hdrlen;
458 452
459 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 453 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
460 tailneed = 0; 454 tail = 0;
461 else 455 else
462 tailneed = CCMP_MIC_LEN; 456 tail = CCMP_MIC_LEN;
463 457
464 if ((skb_headroom(skb) < CCMP_HDR_LEN || 458 if (WARN_ON(skb_tailroom(skb) < tail ||
465 skb_tailroom(skb) < tailneed)) { 459 skb_headroom(skb) < CCMP_HDR_LEN))
466 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 460 return -1;
467 if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed,
468 GFP_ATOMIC)))
469 return -1;
470 }
471 461
472 pos = skb_push(skb, CCMP_HDR_LEN); 462 pos = skb_push(skb, CCMP_HDR_LEN);
473 memmove(pos, pos + CCMP_HDR_LEN, hdrlen); 463 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);