Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 102786
b: refs/heads/master
c: 23c0752
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jun 3, 2008
1 parent f3203b3 commit f146aa0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 71 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f622360bce6facb05fdce4bce5ee4beb2432222d
refs/heads/master: 23c0752a25d73ccc4547700e8a57d5ae2f2edf56
97 changes: 68 additions & 29 deletions trunk/net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,13 +1215,53 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)

/* device xmit handlers */

static int ieee80211_skb_resize(struct ieee80211_local *local,
struct sk_buff *skb,
int head_need, bool may_encrypt)
{
int tail_need = 0;

/*
* This could be optimised, devices that do full hardware
* crypto (including TKIP MMIC) need no tailroom... But we
* have no drivers for such devices currently.
*/
if (may_encrypt) {
tail_need = IEEE80211_ENCRYPT_TAILROOM;
tail_need -= skb_tailroom(skb);
tail_need = max_t(int, tail_need, 0);
}

if (head_need || tail_need) {
/* Sorry. Can't account for this any more */
skb_orphan(skb);
}

if (skb_header_cloned(skb))
I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
else
I802_DEBUG_INC(local->tx_expand_skb_head);

if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n",
wiphy_name(local->hw.wiphy));
return -ENOMEM;
}

/* update truesize too */
skb->truesize += head_need + tail_need;

return 0;
}

int ieee80211_master_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct net_device *odev = NULL;
struct ieee80211_sub_if_data *osdata;
int headroom;
bool may_encrypt;
int ret;

if (info->control.ifindex)
Expand All @@ -1241,13 +1281,18 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,

osdata = IEEE80211_DEV_TO_SUB_IF(odev);

headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM;
if (skb_headroom(skb) < headroom) {
if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
dev_kfree_skb(skb);
dev_put(odev);
return 0;
}
may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT);

headroom = osdata->local->tx_headroom;
if (may_encrypt)
headroom += IEEE80211_ENCRYPT_HEADROOM;
headroom -= skb_headroom(skb);
headroom = max_t(int, 0, headroom);

if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) {
dev_kfree_skb(skb);
dev_put(odev);
return 0;
}

info->control.vif = &osdata->vif;
Expand Down Expand Up @@ -1509,32 +1554,26 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
* build in headroom in __dev_alloc_skb() (linux/skbuff.h) and
* alloc_skb() (net/core/skbuff.c)
*/
head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom;
head_need -= skb_headroom(skb);
head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);

/* We are going to modify skb data, so make a copy of it if happens to
* be cloned. This could happen, e.g., with Linux bridge code passing
* us broadcast frames. */
/*
* So we need to modify the skb header and hence need a copy of
* that. The head_need variable above doesn't, so far, include
* the needed header space that we don't need right away. If we
* can, then we don't reallocate right now but only after the
* frame arrives at the master device (if it does...)
*
* If we cannot, however, then we will reallocate to include all
* the ever needed space. Also, if we need to reallocate it anyway,
* make it big enough for everything we may ever need.
*/

if (head_need > 0 || skb_header_cloned(skb)) {
#if 0
printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes "
"of headroom\n", dev->name, head_need);
#endif

if (skb_header_cloned(skb))
I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
else
I802_DEBUG_INC(local->tx_expand_skb_head);
/* Since we have to reallocate the buffer, make sure that there
* is enough room for possible WEP IV/ICV and TKIP (8 bytes
* before payload and 12 after). */
if (pskb_expand_head(skb, (head_need > 0 ? head_need + 8 : 8),
12, GFP_ATOMIC)) {
printk(KERN_DEBUG "%s: failed to reallocate TX buffer"
"\n", dev->name);
head_need += IEEE80211_ENCRYPT_HEADROOM;
head_need += local->tx_headroom;
head_need = max_t(int, 0, head_need);
if (ieee80211_skb_resize(local, skb, head_need, true))
goto fail;
}
}

if (encaps_data) {
Expand Down
10 changes: 3 additions & 7 deletions trunk/net/mac80211/wep.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,9 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
fc |= IEEE80211_FCTL_PROTECTED;
hdr->frame_control = cpu_to_le16(fc);

if ((skb_headroom(skb) < WEP_IV_LEN ||
skb_tailroom(skb) < WEP_ICV_LEN)) {
I802_DEBUG_INC(local->tx_expand_skb_head);
if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN,
GFP_ATOMIC)))
return NULL;
}
if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN ||
skb_headroom(skb) < WEP_IV_LEN))
return NULL;

hdrlen = ieee80211_get_hdrlen(fc);
newhdr = skb_push(skb, WEP_IV_LEN);
Expand Down
58 changes: 24 additions & 34 deletions trunk/net/mac80211/wpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
struct sk_buff *skb = tx->skb;
int authenticator;
int wpa_test = 0;
int tail;

fc = tx->fc;

Expand All @@ -98,16 +99,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
return TX_CONTINUE;
}

if (skb_tailroom(skb) < MICHAEL_MIC_LEN) {
I802_DEBUG_INC(tx->local->tx_expand_skb_head);
if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN,
MICHAEL_MIC_LEN + TKIP_ICV_LEN,
GFP_ATOMIC))) {
printk(KERN_DEBUG "%s: failed to allocate more memory "
"for Michael MIC\n", tx->dev->name);
return TX_DROP;
}
}
tail = MICHAEL_MIC_LEN;
if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
tail += TKIP_ICV_LEN;

if (WARN_ON(skb_tailroom(skb) < tail ||
skb_headroom(skb) < TKIP_IV_LEN))
return TX_DROP;

#if 0
authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
Expand Down Expand Up @@ -188,7 +186,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_key *key = tx->key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int hdrlen, len, tailneed;
int hdrlen, len, tail;
u16 fc;
u8 *pos;

Expand All @@ -199,25 +197,21 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
/* hwaccel - with no need for preallocated room for IV/ICV */
info->control.hw_key = &tx->key->conf;
return TX_CONTINUE;
return 0;
}

fc = le16_to_cpu(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);
len = skb->len - hdrlen;

if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
tailneed = 0;
tail = 0;
else
tailneed = TKIP_ICV_LEN;

if ((skb_headroom(skb) < TKIP_IV_LEN ||
skb_tailroom(skb) < tailneed)) {
I802_DEBUG_INC(tx->local->tx_expand_skb_head);
if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed,
GFP_ATOMIC)))
return -1;
}
tail = TKIP_ICV_LEN;

if (WARN_ON(skb_tailroom(skb) < tail ||
skb_headroom(skb) < TKIP_IV_LEN))
return -1;

pos = skb_push(skb, TKIP_IV_LEN);
memmove(pos, pos + TKIP_IV_LEN, hdrlen);
Expand Down Expand Up @@ -432,7 +426,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_key *key = tx->key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int hdrlen, len, tailneed;
int hdrlen, len, tail;
u16 fc;
u8 *pos, *pn, *b_0, *aad, *scratch;
int i;
Expand All @@ -445,7 +439,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
/* hwaccel - with no need for preallocated room for CCMP "
* header or MIC fields */
info->control.hw_key = &tx->key->conf;
return TX_CONTINUE;
return 0;
}

scratch = key->u.ccmp.tx_crypto_buf;
Expand All @@ -457,17 +451,13 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
len = skb->len - hdrlen;

if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
tailneed = 0;
tail = 0;
else
tailneed = CCMP_MIC_LEN;

if ((skb_headroom(skb) < CCMP_HDR_LEN ||
skb_tailroom(skb) < tailneed)) {
I802_DEBUG_INC(tx->local->tx_expand_skb_head);
if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed,
GFP_ATOMIC)))
return -1;
}
tail = CCMP_MIC_LEN;

if (WARN_ON(skb_tailroom(skb) < tail ||
skb_headroom(skb) < CCMP_HDR_LEN))
return -1;

pos = skb_push(skb, CCMP_HDR_LEN);
memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
Expand Down

0 comments on commit f146aa0

Please sign in to comment.