aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 96c594309506..7a637b80a62e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1587 list) { 1587 list) {
1588 if (!ieee80211_sdata_running(tmp_sdata)) 1588 if (!ieee80211_sdata_running(tmp_sdata))
1589 continue; 1589 continue;
1590 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) 1590 if (tmp_sdata->vif.type ==
1591 NL80211_IFTYPE_MONITOR ||
1592 tmp_sdata->vif.type ==
1593 NL80211_IFTYPE_AP_VLAN ||
1594 tmp_sdata->vif.type ==
1595 NL80211_IFTYPE_WDS)
1591 continue; 1596 continue;
1592 if (compare_ether_addr(tmp_sdata->vif.addr, 1597 if (compare_ether_addr(tmp_sdata->vif.addr,
1593 hdr->addr2) == 0) { 1598 hdr->addr2) == 0) {
@@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1732 int nh_pos, h_pos; 1737 int nh_pos, h_pos;
1733 struct sta_info *sta = NULL; 1738 struct sta_info *sta = NULL;
1734 u32 sta_flags = 0; 1739 u32 sta_flags = 0;
1740 struct sk_buff *tmp_skb;
1735 1741
1736 if (unlikely(skb->len < ETH_HLEN)) { 1742 if (unlikely(skb->len < ETH_HLEN)) {
1737 ret = NETDEV_TX_OK; 1743 ret = NETDEV_TX_OK;
1738 goto fail; 1744 goto fail;
1739 } 1745 }
1740 1746
1741 nh_pos = skb_network_header(skb) - skb->data;
1742 h_pos = skb_transport_header(skb) - skb->data;
1743
1744 /* convert Ethernet header to proper 802.11 header (based on 1747 /* convert Ethernet header to proper 802.11 header (based on
1745 * operation mode) */ 1748 * operation mode) */
1746 ethertype = (skb->data[12] << 8) | skb->data[13]; 1749 ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1913 goto fail; 1916 goto fail;
1914 } 1917 }
1915 1918
1919 /*
1920 * If the skb is shared we need to obtain our own copy.
1921 */
1922 if (skb_shared(skb)) {
1923 tmp_skb = skb;
1924 skb = skb_copy(skb, GFP_ATOMIC);
1925 kfree_skb(tmp_skb);
1926
1927 if (!skb) {
1928 ret = NETDEV_TX_OK;
1929 goto fail;
1930 }
1931 }
1932
1916 hdr.frame_control = fc; 1933 hdr.frame_control = fc;
1917 hdr.duration_id = 0; 1934 hdr.duration_id = 0;
1918 hdr.seq_ctrl = 0; 1935 hdr.seq_ctrl = 0;
@@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1931 encaps_len = 0; 1948 encaps_len = 0;
1932 } 1949 }
1933 1950
1951 nh_pos = skb_network_header(skb) - skb->data;
1952 h_pos = skb_transport_header(skb) - skb->data;
1953
1934 skb_pull(skb, skip_header_bytes); 1954 skb_pull(skb, skip_header_bytes);
1935 nh_pos -= skip_header_bytes; 1955 nh_pos -= skip_header_bytes;
1936 h_pos -= skip_header_bytes; 1956 h_pos -= skip_header_bytes;