diff options
author | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-01-09 23:24:16 -0500 |
---|---|---|
committer | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-01-09 23:24:16 -0500 |
commit | a12fc999485eb5d9ecad74554f0baac9688d28e2 (patch) | |
tree | c2ef18a92cb72512ee340ff02298403c6368043b /net/mac80211/tx.c | |
parent | b1d76b202e451fcb8909b7686a6bc54127c2411a (diff) | |
parent | d77cf23f1befd3922d81b91cb01fd3da619e0206 (diff) |
Merge commit 'v2.6.36.3' into linaro-2.6.36
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926..ab6355dd4ac 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1705,15 +1705,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, int nh_pos, h_pos; struct sta_info *sta = NULL; u32 sta_flags = 0; + struct sk_buff *tmp_skb; if (unlikely(skb->len < ETH_HLEN)) { ret = NETDEV_TX_OK; goto fail; } - nh_pos = skb_network_header(skb) - skb->data; - h_pos = skb_transport_header(skb) - skb->data; - /* convert Ethernet header to proper 802.11 header (based on * operation mode) */ ethertype = (skb->data[12] << 8) | skb->data[13]; @@ -1885,6 +1883,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, goto fail; } + /* + * If the skb is shared we need to obtain our own copy. + */ + if (skb_shared(skb)) { + tmp_skb = skb; + skb = skb_copy(skb, GFP_ATOMIC); + kfree_skb(tmp_skb); + + if (!skb) { + ret = NETDEV_TX_OK; + goto fail; + } + } + hdr.frame_control = fc; hdr.duration_id = 0; hdr.seq_ctrl = 0; @@ -1903,6 +1915,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, encaps_len = 0; } + nh_pos = skb_network_header(skb) - skb->data; + h_pos = skb_transport_header(skb) - skb->data; + skb_pull(skb, skip_header_bytes); nh_pos -= skip_header_bytes; h_pos -= skip_header_bytes; |