diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-10 12:51:02 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-10 12:51:02 -0800 |
commit | e91db5cd6f2203ef2a93ce8770f2728e9107c4f7 (patch) | |
tree | 210668b645b5d63cecf6c876c011b2cf3f9a5122 /net | |
parent | 5f75a1042feca37c0a436ba42a4b1f7f75c35778 (diff) | |
parent | 0a54917c3fc295cb61f3fb52373c173fd3b69f48 (diff) | |
download | op-kernel-dev-e91db5cd6f2203ef2a93ce8770f2728e9107c4f7.zip op-kernel-dev-e91db5cd6f2203ef2a93ce8770f2728e9107c4f7.tar.gz |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'net')
-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 df6aac5..7a637b8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1737,15 +1737,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]; @@ -1918,6 +1916,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; @@ -1936,6 +1948,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; |