diff options
author | Arik Nemtsov <arik@wizery.com> | 2014-06-11 17:18:27 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-06-23 14:28:19 +0200 |
commit | ee10f2c779b28c1d6e87ac3e1bbb1aa8b62fa891 (patch) | |
tree | 03619136498fe1a91731bad32ac70592168ce230 /net/mac80211 | |
parent | 7adc3e4664bc5bd382fa181e6a4506f5b5b583d8 (diff) |
mac80211: protect TDLS discovery session
After sending a TDLS discovery-request, we expect a reply to arrive on
the AP's channel. We must stay on the channel (no PSM, scan, etc.), since
a TDLS setup-response is a direct packet not buffered by the AP.
Add a new mac80211 driver callback to allow discovery session protection.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/driver-ops.h | 16 | ||||
-rw-r--r-- | net/mac80211/tdls.c | 10 | ||||
-rw-r--r-- | net/mac80211/trace.h | 7 |
3 files changed, 32 insertions, 1 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index bd782dcffcc..2265bd7a44b 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -970,6 +970,22 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline void +drv_mgd_protect_tdls_discover(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + might_sleep(); + + if (!check_sdata_in_driver(sdata)) + return; + WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); + + trace_drv_mgd_protect_tdls_discover(local, sdata); + if (local->ops->mgd_protect_tdls_discover) + local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); + trace_drv_return_void(local); +} + static inline int drv_add_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index b87e369561f..f7185338a0f 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -10,6 +10,7 @@ #include <linux/ieee80211.h> #include <net/cfg80211.h> #include "ieee80211_i.h" +#include "driver-ops.h" /* give usermode some time for retries in setting up the TDLS session */ #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) @@ -442,8 +443,15 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, peer_capability, initiator, extra_ies, extra_ies_len); break; - case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_DISCOVERY_REQUEST: + /* + * Protect the discovery so we can hear the TDLS discovery + * response frame. It is transmitted directly and not buffered + * by the AP. + */ + drv_mgd_protect_tdls_discover(sdata->local, sdata); + /* fall-through */ + case WLAN_TDLS_SETUP_CONFIRM: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: /* no special handling */ ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index cfe1a0688b5..02ac535d127 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1330,6 +1330,13 @@ DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, TP_ARGS(local, sdata) ); +DEFINE_EVENT(local_sdata_evt, drv_mgd_protect_tdls_discover, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata), + + TP_ARGS(local, sdata) +); + DECLARE_EVENT_CLASS(local_chanctx, TP_PROTO(struct ieee80211_local *local, struct ieee80211_chanctx *ctx), |