aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c10
-rw-r--r--net/mac80211/sta_info.h5
-rw-r--r--net/mac80211/tx.c42
3 files changed, 52 insertions, 5 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 119a573af14b..bdf9852eec5b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2427,6 +2427,7 @@ fail:
2427static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, 2427static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2428 u8 *peer, enum nl80211_tdls_operation oper) 2428 u8 *peer, enum nl80211_tdls_operation oper)
2429{ 2429{
2430 struct sta_info *sta;
2430 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2431 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2431 2432
2432 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) 2433 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
@@ -2441,6 +2442,15 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2441 2442
2442 switch (oper) { 2443 switch (oper) {
2443 case NL80211_TDLS_ENABLE_LINK: 2444 case NL80211_TDLS_ENABLE_LINK:
2445 rcu_read_lock();
2446 sta = sta_info_get(sdata, peer);
2447 if (!sta) {
2448 rcu_read_unlock();
2449 return -ENOLINK;
2450 }
2451
2452 set_sta_flags(sta, WLAN_STA_TDLS_PEER_AUTH);
2453 rcu_read_unlock();
2444 break; 2454 break;
2445 case NL80211_TDLS_DISABLE_LINK: 2455 case NL80211_TDLS_DISABLE_LINK:
2446 return sta_info_destroy_addr(sdata, peer); 2456 return sta_info_destroy_addr(sdata, peer);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index b6bd4e9d8722..c10e2e8632b5 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -45,7 +45,9 @@
45 * station in power-save mode, reply when the driver unblocks. 45 * station in power-save mode, reply when the driver unblocks.
46 * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal 46 * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal
47 * buffers. Automatically cleared on station wake-up. 47 * buffers. Automatically cleared on station wake-up.
48 * @WLAN_STA_TDLS_PEER: station is a TDLS peer. 48 * @WLAN_STA_TDLS_PEER: Station is a TDLS peer.
49 * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct
50 * packets. This means the link is enabled.
49 */ 51 */
50enum ieee80211_sta_info_flags { 52enum ieee80211_sta_info_flags {
51 WLAN_STA_AUTH = 1<<0, 53 WLAN_STA_AUTH = 1<<0,
@@ -63,6 +65,7 @@ enum ieee80211_sta_info_flags {
63 WLAN_STA_PSPOLL = 1<<13, 65 WLAN_STA_PSPOLL = 1<<13,
64 WLAN_STA_PS_DRIVER_BUF = 1<<14, 66 WLAN_STA_PS_DRIVER_BUF = 1<<14,
65 WLAN_STA_TDLS_PEER = 1<<15, 67 WLAN_STA_TDLS_PEER = 1<<15,
68 WLAN_STA_TDLS_PEER_AUTH = 1<<16,
66}; 69};
67 70
68#define STA_TID_NUM 16 71#define STA_TID_NUM 16
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 542272acfc1a..0ca16880bbb4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1726,6 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1726 struct sta_info *sta = NULL; 1726 struct sta_info *sta = NULL;
1727 u32 sta_flags = 0; 1727 u32 sta_flags = 0;
1728 struct sk_buff *tmp_skb; 1728 struct sk_buff *tmp_skb;
1729 bool tdls_direct = false;
1729 1730
1730 if (unlikely(skb->len < ETH_HLEN)) { 1731 if (unlikely(skb->len < ETH_HLEN)) {
1731 ret = NETDEV_TX_OK; 1732 ret = NETDEV_TX_OK;
@@ -1837,11 +1838,43 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1837 break; 1838 break;
1838#endif 1839#endif
1839 case NL80211_IFTYPE_STATION: 1840 case NL80211_IFTYPE_STATION:
1840 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); 1841 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1841 if (sdata->u.mgd.use_4addr && 1842 rcu_read_lock();
1842 cpu_to_be16(ethertype) != sdata->control_port_protocol) { 1843 sta = sta_info_get(sdata, skb->data);
1843 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1844 if (sta)
1845 sta_flags = get_sta_flags(sta);
1846 rcu_read_unlock();
1847
1848 /*
1849 * If the TDLS link is enabled, send everything
1850 * directly. Otherwise, allow TDLS setup frames
1851 * to be transmitted indirectly.
1852 */
1853 tdls_direct =
1854 (sta_flags & WLAN_STA_TDLS_PEER) &&
1855 ((sta_flags & WLAN_STA_TDLS_PEER_AUTH) ||
1856 !(ethertype == ETH_P_TDLS && skb->len > 14 &&
1857 skb->data[14] == WLAN_TDLS_SNAP_RFTYPE));
1858 }
1859
1860 if (tdls_direct) {
1861 /* link during setup - throw out frames to peer */
1862 if (!(sta_flags & WLAN_STA_TDLS_PEER_AUTH)) {
1863 ret = NETDEV_TX_OK;
1864 goto fail;
1865 }
1866
1867 /* DA SA BSSID */
1868 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1869 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
1870 memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
1871 hdrlen = 24;
1872 } else if (sdata->u.mgd.use_4addr &&
1873 cpu_to_be16(ethertype) != sdata->control_port_protocol) {
1874 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
1875 IEEE80211_FCTL_TODS);
1844 /* RA TA DA SA */ 1876 /* RA TA DA SA */
1877 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
1845 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); 1878 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1846 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1879 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1847 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1880 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
@@ -1849,6 +1882,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1849 } else { 1882 } else {
1850 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 1883 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
1851 /* BSSID SA DA */ 1884 /* BSSID SA DA */
1885 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
1852 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1886 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
1853 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1887 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1854 hdrlen = 24; 1888 hdrlen = 24;