diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 12 | ||||
-rw-r--r-- | net/mac80211/tdls.c | 23 |
3 files changed, 37 insertions, 1 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 073a8235ae1b..a8af4aafa117 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -2225,6 +2225,9 @@ void ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy, | |||
2225 | const u8 *addr); | 2225 | const u8 *addr); |
2226 | void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata); | 2226 | void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata); |
2227 | void ieee80211_tdls_chsw_work(struct work_struct *wk); | 2227 | void ieee80211_tdls_chsw_work(struct work_struct *wk); |
2228 | void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, | ||
2229 | const u8 *peer, u16 reason); | ||
2230 | const char *ieee80211_get_reason_code_string(u16 reason_code); | ||
2228 | 2231 | ||
2229 | extern const struct ethtool_ops ieee80211_ethtool_ops; | 2232 | extern const struct ethtool_ops ieee80211_ethtool_ops; |
2230 | 2233 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b7a9fe3d5fcb..383b0df100e4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2963,7 +2963,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2963 | #define case_WLAN(type) \ | 2963 | #define case_WLAN(type) \ |
2964 | case WLAN_REASON_##type: return #type | 2964 | case WLAN_REASON_##type: return #type |
2965 | 2965 | ||
2966 | static const char *ieee80211_get_reason_code_string(u16 reason_code) | 2966 | const char *ieee80211_get_reason_code_string(u16 reason_code) |
2967 | { | 2967 | { |
2968 | switch (reason_code) { | 2968 | switch (reason_code) { |
2969 | case_WLAN(UNSPECIFIED); | 2969 | case_WLAN(UNSPECIFIED); |
@@ -3028,6 +3028,11 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
3028 | if (len < 24 + 2) | 3028 | if (len < 24 + 2) |
3029 | return; | 3029 | return; |
3030 | 3030 | ||
3031 | if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) { | ||
3032 | ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code); | ||
3033 | return; | ||
3034 | } | ||
3035 | |||
3031 | if (ifmgd->associated && | 3036 | if (ifmgd->associated && |
3032 | ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) { | 3037 | ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) { |
3033 | const u8 *bssid = ifmgd->associated->bssid; | 3038 | const u8 *bssid = ifmgd->associated->bssid; |
@@ -3077,6 +3082,11 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
3077 | 3082 | ||
3078 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 3083 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
3079 | 3084 | ||
3085 | if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) { | ||
3086 | ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code); | ||
3087 | return; | ||
3088 | } | ||
3089 | |||
3080 | sdata_info(sdata, "disassociated from %pM (Reason: %u=%s)\n", | 3090 | sdata_info(sdata, "disassociated from %pM (Reason: %u=%s)\n", |
3081 | mgmt->sa, reason_code, | 3091 | mgmt->sa, reason_code, |
3082 | ieee80211_get_reason_code_string(reason_code)); | 3092 | ieee80211_get_reason_code_string(reason_code)); |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 24c37f91ca46..ba8fe48952d9 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -1994,3 +1994,26 @@ void ieee80211_tdls_chsw_work(struct work_struct *wk) | |||
1994 | } | 1994 | } |
1995 | rtnl_unlock(); | 1995 | rtnl_unlock(); |
1996 | } | 1996 | } |
1997 | |||
1998 | void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, | ||
1999 | const u8 *peer, u16 reason) | ||
2000 | { | ||
2001 | struct ieee80211_sta *sta; | ||
2002 | |||
2003 | rcu_read_lock(); | ||
2004 | sta = ieee80211_find_sta(&sdata->vif, peer); | ||
2005 | if (!sta || !sta->tdls) { | ||
2006 | rcu_read_unlock(); | ||
2007 | return; | ||
2008 | } | ||
2009 | rcu_read_unlock(); | ||
2010 | |||
2011 | tdls_dbg(sdata, "disconnected from TDLS peer %pM (Reason: %u=%s)\n", | ||
2012 | peer, reason, | ||
2013 | ieee80211_get_reason_code_string(reason)); | ||
2014 | |||
2015 | ieee80211_tdls_oper_request(&sdata->vif, peer, | ||
2016 | NL80211_TDLS_TEARDOWN, | ||
2017 | WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, | ||
2018 | GFP_ATOMIC); | ||
2019 | } | ||