aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2011-01-09 23:24:16 -0500
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-01-09 23:24:16 -0500
commita12fc999485eb5d9ecad74554f0baac9688d28e2 (patch)
treec2ef18a92cb72512ee340ff02298403c6368043b /net/mac80211
parentb1d76b202e451fcb8909b7686a6bc54127c2411a (diff)
parentd77cf23f1befd3922d81b91cb01fd3da619e0206 (diff)
Merge commit 'v2.6.36.3' into linaro-2.6.36
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/rx.c5
-rw-r--r--net/mac80211/tx.c21
2 files changed, 22 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 28624282c5f..a09196afafa 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1712,9 +1712,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
fwd_skb = skb_copy(skb, GFP_ATOMIC);
- if (!fwd_skb && net_ratelimit())
+ if (!fwd_skb && net_ratelimit()) {
printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
sdata->name);
+ goto out;
+ }
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
@@ -1752,6 +1754,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
}
+ out:
if (is_multicast_ether_addr(hdr->addr1) ||
sdata->dev->flags & IFF_PROMISC)
return RX_CONTINUE;
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;