Skip to content

Commit

Permalink
mac80211: protect TDLS discovery session
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arik Nemtsov authored and Johannes Berg committed Jun 23, 2014
1 parent 7adc3e4 commit ee10f2c
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
12 changes: 12 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -2764,6 +2764,15 @@ enum ieee80211_roc_type {
* mac80211 will transmit the frame right away.
* The callback is optional and can (should!) sleep.
*
* @mgd_protect_tdls_discover: Protect a 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.
* mac80211 will call this function just before the transmission of a TDLS
* discovery-request. The recommended period of protection is at least
* 2 * (DTIM period).
* The callback is optional and can sleep.
*
* @add_chanctx: Notifies device driver about new channel context creation.
* @remove_chanctx: Notifies device driver about channel context destruction.
* @change_chanctx: Notifies device driver about channel context changes that
Expand Down Expand Up @@ -2981,6 +2990,9 @@ struct ieee80211_ops {
void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);

void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);

int (*add_chanctx)(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx);
void (*remove_chanctx)(struct ieee80211_hw *hw,
Expand Down
16 changes: 16 additions & 0 deletions net/mac80211/driver-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
10 changes: 9 additions & 1 deletion net/mac80211/tdls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions net/mac80211/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit ee10f2c

Please sign in to comment.