aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-09 11:50:10 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-11-19 12:44:38 -0500
commit4c9451ed94087abf0e45835f133e0fa44b809f96 (patch)
tree978e19f77041210d534027b898a2527a13701b95 /net/mac80211/tx.c
parent73c4e195e6396eea04e11f88dc0336e1bc3c8e66 (diff)
mac80211: factor out 802.11 header building code
Factor out the 802.11 header building code from the xmit function to be able to use it separately in a later commit. While at it, fix up some documentation. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c144
1 files changed, 92 insertions, 52 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c4a5494c2ac6..55d69fda4c6a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1784,24 +1784,26 @@ static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
1784} 1784}
1785 1785
1786/** 1786/**
1787 * __ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type 1787 * ieee80211_build_hdr - build 802.11 header in the given frame
1788 * subinterfaces (wlan#, WDS, and VLAN interfaces) 1788 * @sdata: virtual interface to build the header for
1789 * @skb: packet to be sent 1789 * @skb: the skb to build the header in
1790 * @dev: incoming interface
1791 * @info_flags: skb flags to set 1790 * @info_flags: skb flags to set
1792 * 1791 *
1793 * On failure skb will be freed. 1792 * This function takes the skb with 802.3 header and reformats the header to
1793 * the appropriate IEEE 802.11 header based on which interface the packet is
1794 * being transmitted on.
1795 *
1796 * Note that this function also takes care of the TX status request and
1797 * potential unsharing of the SKB - this needs to be interleaved with the
1798 * header building.
1799 *
1800 * The function requires the read-side RCU lock held
1794 * 1801 *
1795 * This function takes in an Ethernet header and encapsulates it with suitable 1802 * Returns: the (possibly reallocated) skb or an ERR_PTR() code
1796 * IEEE 802.11 header based on which interface the packet is coming in. The
1797 * encapsulated packet will then be passed to master interface, wlan#.11, for
1798 * transmission (through low-level driver).
1799 */ 1803 */
1800void __ieee80211_subif_start_xmit(struct sk_buff *skb, 1804static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
1801 struct net_device *dev, 1805 struct sk_buff *skb, u32 info_flags)
1802 u32 info_flags)
1803{ 1806{
1804 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1805 struct ieee80211_local *local = sdata->local; 1807 struct ieee80211_local *local = sdata->local;
1806 struct ieee80211_tx_info *info; 1808 struct ieee80211_tx_info *info;
1807 int head_need; 1809 int head_need;
@@ -1821,20 +1823,13 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
1821 struct ieee80211_chanctx_conf *chanctx_conf; 1823 struct ieee80211_chanctx_conf *chanctx_conf;
1822 struct ieee80211_sub_if_data *ap_sdata; 1824 struct ieee80211_sub_if_data *ap_sdata;
1823 enum ieee80211_band band; 1825 enum ieee80211_band band;
1824 1826 int ret;
1825 if (unlikely(skb->len < ETH_HLEN))
1826 goto fail;
1827 1827
1828 /* convert Ethernet header to proper 802.11 header (based on 1828 /* convert Ethernet header to proper 802.11 header (based on
1829 * operation mode) */ 1829 * operation mode) */
1830 ethertype = (skb->data[12] << 8) | skb->data[13]; 1830 ethertype = (skb->data[12] << 8) | skb->data[13];
1831 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); 1831 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
1832 1832
1833 rcu_read_lock();
1834
1835 /* Measure frame arrival for Tx latency statistics calculation */
1836 ieee80211_tx_latency_start_msrmnt(local, skb);
1837
1838 switch (sdata->vif.type) { 1833 switch (sdata->vif.type) {
1839 case NL80211_IFTYPE_AP_VLAN: 1834 case NL80211_IFTYPE_AP_VLAN:
1840 sta = rcu_dereference(sdata->u.vlan.sta); 1835 sta = rcu_dereference(sdata->u.vlan.sta);
@@ -1852,8 +1847,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
1852 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 1847 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
1853 u.ap); 1848 u.ap);
1854 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); 1849 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf);
1855 if (!chanctx_conf) 1850 if (!chanctx_conf) {
1856 goto fail_rcu; 1851 ret = -ENOTCONN;
1852 goto free;
1853 }
1857 band = chanctx_conf->def.chan->band; 1854 band = chanctx_conf->def.chan->band;
1858 if (sta) 1855 if (sta)
1859 break; 1856 break;
@@ -1861,8 +1858,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
1861 case NL80211_IFTYPE_AP: 1858 case NL80211_IFTYPE_AP:
1862 if (sdata->vif.type == NL80211_IFTYPE_AP) 1859 if (sdata->vif.type == NL80211_IFTYPE_AP)
1863 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1860 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1864 if (!chanctx_conf) 1861 if (!chanctx_conf) {
1865 goto fail_rcu; 1862 ret = -ENOTCONN;
1863 goto free;
1864 }
1866 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 1865 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1867 /* DA BSSID SA */ 1866 /* DA BSSID SA */
1868 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1867 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -1949,8 +1948,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
1949 1948
1950 } 1949 }
1951 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1950 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1952 if (!chanctx_conf) 1951 if (!chanctx_conf) {
1953 goto fail_rcu; 1952 ret = -ENOTCONN;
1953 goto free;
1954 }
1954 band = chanctx_conf->def.chan->band; 1955 band = chanctx_conf->def.chan->band;
1955 break; 1956 break;
1956#endif 1957#endif
@@ -1980,8 +1981,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
1980 * of a link teardown after a TDLS sta is removed due to being 1981 * of a link teardown after a TDLS sta is removed due to being
1981 * unreachable. 1982 * unreachable.
1982 */ 1983 */
1983 if (tdls_peer && !tdls_auth && !tdls_setup_frame) 1984 if (tdls_peer && !tdls_auth && !tdls_setup_frame) {
1984 goto fail_rcu; 1985 ret = -EINVAL;
1986 goto free;
1987 }
1985 1988
1986 /* send direct packets to authorized TDLS peers */ 1989 /* send direct packets to authorized TDLS peers */
1987 if (tdls_peer && tdls_auth) { 1990 if (tdls_peer && tdls_auth) {
@@ -2009,8 +2012,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2009 hdrlen = 24; 2012 hdrlen = 24;
2010 } 2013 }
2011 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2014 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2012 if (!chanctx_conf) 2015 if (!chanctx_conf) {
2013 goto fail_rcu; 2016 ret = -ENOTCONN;
2017 goto free;
2018 }
2014 band = chanctx_conf->def.chan->band; 2019 band = chanctx_conf->def.chan->band;
2015 break; 2020 break;
2016 case NL80211_IFTYPE_OCB: 2021 case NL80211_IFTYPE_OCB:
@@ -2020,8 +2025,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2020 eth_broadcast_addr(hdr.addr3); 2025 eth_broadcast_addr(hdr.addr3);
2021 hdrlen = 24; 2026 hdrlen = 24;
2022 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2027 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2023 if (!chanctx_conf) 2028 if (!chanctx_conf) {
2024 goto fail_rcu; 2029 ret = -ENOTCONN;
2030 goto free;
2031 }
2025 band = chanctx_conf->def.chan->band; 2032 band = chanctx_conf->def.chan->band;
2026 break; 2033 break;
2027 case NL80211_IFTYPE_ADHOC: 2034 case NL80211_IFTYPE_ADHOC:
@@ -2031,12 +2038,15 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2031 memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); 2038 memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN);
2032 hdrlen = 24; 2039 hdrlen = 24;
2033 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2040 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2034 if (!chanctx_conf) 2041 if (!chanctx_conf) {
2035 goto fail_rcu; 2042 ret = -ENOTCONN;
2043 goto free;
2044 }
2036 band = chanctx_conf->def.chan->band; 2045 band = chanctx_conf->def.chan->band;
2037 break; 2046 break;
2038 default: 2047 default:
2039 goto fail_rcu; 2048 ret = -EINVAL;
2049 goto free;
2040 } 2050 }
2041 2051
2042 /* 2052 /*
@@ -2074,12 +2084,13 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2074 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { 2084 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
2075#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2085#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2076 net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", 2086 net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n",
2077 dev->name, hdr.addr1); 2087 sdata->name, hdr.addr1);
2078#endif 2088#endif
2079 2089
2080 I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); 2090 I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
2081 2091
2082 goto fail_rcu; 2092 ret = -EPERM;
2093 goto free;
2083 } 2094 }
2084 2095
2085 if (unlikely(!multicast && skb->sk && 2096 if (unlikely(!multicast && skb->sk &&
@@ -2116,8 +2127,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2116 skb = skb_clone(skb, GFP_ATOMIC); 2127 skb = skb_clone(skb, GFP_ATOMIC);
2117 kfree_skb(tmp_skb); 2128 kfree_skb(tmp_skb);
2118 2129
2119 if (!skb) 2130 if (!skb) {
2120 goto fail_rcu; 2131 ret = -ENOMEM;
2132 goto free;
2133 }
2121 } 2134 }
2122 2135
2123 hdr.frame_control = fc; 2136 hdr.frame_control = fc;
@@ -2166,7 +2179,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2166 if (ieee80211_skb_resize(sdata, skb, head_need, true)) { 2179 if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
2167 ieee80211_free_txskb(&local->hw, skb); 2180 ieee80211_free_txskb(&local->hw, skb);
2168 skb = NULL; 2181 skb = NULL;
2169 goto fail_rcu; 2182 return ERR_PTR(-ENOMEM);
2170 } 2183 }
2171 } 2184 }
2172 2185
@@ -2200,9 +2213,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2200 nh_pos += hdrlen; 2213 nh_pos += hdrlen;
2201 h_pos += hdrlen; 2214 h_pos += hdrlen;
2202 2215
2203 dev->stats.tx_packets++;
2204 dev->stats.tx_bytes += skb->len;
2205
2206 /* Update skb pointers to various headers since this modified frame 2216 /* Update skb pointers to various headers since this modified frame
2207 * is going to go through Linux networking code that may potentially 2217 * is going to go through Linux networking code that may potentially
2208 * need things like pointer to IP header. */ 2218 * need things like pointer to IP header. */
@@ -2213,23 +2223,53 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2213 info = IEEE80211_SKB_CB(skb); 2223 info = IEEE80211_SKB_CB(skb);
2214 memset(info, 0, sizeof(*info)); 2224 memset(info, 0, sizeof(*info));
2215 2225
2216 dev->trans_start = jiffies;
2217
2218 info->flags = info_flags; 2226 info->flags = info_flags;
2219 info->ack_frame_id = info_id; 2227 info->ack_frame_id = info_id;
2220 info->band = band; 2228 info->band = band;
2221 2229
2222 ieee80211_xmit(sdata, skb); 2230 return skb;
2223 rcu_read_unlock(); 2231 free:
2232 kfree_skb(skb);
2233 return ERR_PTR(ret);
2234}
2235
2236void __ieee80211_subif_start_xmit(struct sk_buff *skb,
2237 struct net_device *dev,
2238 u32 info_flags)
2239{
2240 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2241 struct ieee80211_local *local = sdata->local;
2242
2243 if (unlikely(skb->len < ETH_HLEN)) {
2244 kfree_skb(skb);
2245 return;
2246 }
2247
2248 rcu_read_lock();
2249
2250 /* Measure frame arrival for Tx latency statistics calculation */
2251 ieee80211_tx_latency_start_msrmnt(local, skb);
2252
2253 skb = ieee80211_build_hdr(sdata, skb, info_flags);
2254 if (IS_ERR(skb))
2255 goto out;
2224 2256
2225 return; 2257 dev->stats.tx_packets++;
2258 dev->stats.tx_bytes += skb->len;
2259 dev->trans_start = jiffies;
2226 2260
2227 fail_rcu: 2261 ieee80211_xmit(sdata, skb);
2262 out:
2228 rcu_read_unlock(); 2263 rcu_read_unlock();
2229 fail:
2230 dev_kfree_skb(skb);
2231} 2264}
2232 2265
2266/**
2267 * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs
2268 * @skb: packet to be sent
2269 * @dev: incoming interface
2270 *
2271 * On failure skb will be freed.
2272 */
2233netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, 2273netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2234 struct net_device *dev) 2274 struct net_device *dev)
2235{ 2275{