diff options
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 24ade5f68e02..8d87897d7eb7 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
@@ -227,7 +227,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
227 | rts_required; | 227 | rts_required; |
228 | unsigned long flags; | 228 | unsigned long flags; |
229 | struct net_device_stats *stats = &ieee->stats; | 229 | struct net_device_stats *stats = &ieee->stats; |
230 | int ether_type, encrypt, host_encrypt, host_encrypt_msdu; | 230 | int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv; |
231 | int bytes, fc, hdr_len; | 231 | int bytes, fc, hdr_len; |
232 | struct sk_buff *skb_frag; | 232 | struct sk_buff *skb_frag; |
233 | struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */ | 233 | struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */ |
@@ -263,8 +263,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
263 | 263 | ||
264 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && | 264 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && |
265 | ieee->sec.encrypt; | 265 | ieee->sec.encrypt; |
266 | |||
266 | host_encrypt = ieee->host_encrypt && encrypt; | 267 | host_encrypt = ieee->host_encrypt && encrypt; |
267 | host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt; | 268 | host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt; |
269 | host_build_iv = ieee->host_build_iv && encrypt; | ||
268 | 270 | ||
269 | if (!encrypt && ieee->ieee802_1x && | 271 | if (!encrypt && ieee->ieee802_1x && |
270 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { | 272 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { |
@@ -310,8 +312,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
310 | int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len + | 312 | int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len + |
311 | crypt->ops->extra_msdu_postfix_len; | 313 | crypt->ops->extra_msdu_postfix_len; |
312 | struct sk_buff *skb_new = dev_alloc_skb(len); | 314 | struct sk_buff *skb_new = dev_alloc_skb(len); |
315 | |||
313 | if (unlikely(!skb_new)) | 316 | if (unlikely(!skb_new)) |
314 | goto failed; | 317 | goto failed; |
318 | |||
315 | skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len); | 319 | skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len); |
316 | memcpy(skb_put(skb_new, hdr_len), &header, hdr_len); | 320 | memcpy(skb_put(skb_new, hdr_len), &header, hdr_len); |
317 | snapped = 1; | 321 | snapped = 1; |
@@ -418,7 +422,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
418 | for (; i < nr_frags; i++) { | 422 | for (; i < nr_frags; i++) { |
419 | skb_frag = txb->fragments[i]; | 423 | skb_frag = txb->fragments[i]; |
420 | 424 | ||
421 | if (host_encrypt) | 425 | if (host_encrypt || host_build_iv) |
422 | skb_reserve(skb_frag, | 426 | skb_reserve(skb_frag, |
423 | crypt->ops->extra_mpdu_prefix_len); | 427 | crypt->ops->extra_mpdu_prefix_len); |
424 | 428 | ||
@@ -453,6 +457,16 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
453 | * to insert the IV between the header and the payload */ | 457 | * to insert the IV between the header and the payload */ |
454 | if (host_encrypt) | 458 | if (host_encrypt) |
455 | ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); | 459 | ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); |
460 | else if (host_build_iv) { | ||
461 | struct ieee80211_crypt_data *crypt; | ||
462 | |||
463 | crypt = ieee->crypt[ieee->tx_keyidx]; | ||
464 | atomic_inc(&crypt->refcnt); | ||
465 | if (crypt->ops->build_iv) | ||
466 | crypt->ops->build_iv(skb_frag, hdr_len, | ||
467 | crypt->priv); | ||
468 | atomic_dec(&crypt->refcnt); | ||
469 | } | ||
456 | 470 | ||
457 | if (ieee->config & | 471 | if (ieee->config & |
458 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) | 472 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) |