diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-29 04:38:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-03 15:00:14 -0400 |
commit | 23c0752a25d73ccc4547700e8a57d5ae2f2edf56 (patch) | |
tree | 225631645bf52c07931adc7aeb766344b05be7eb /net/mac80211/wpa.c | |
parent | f622360bce6facb05fdce4bce5ee4beb2432222d (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.c | 58 |
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); |