Commit 7be5086d authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: add probe request filter flag

Using the frame registration notification, we
can see when probe requests are requested and
notify the low-level driver via filtering. The
flag is also set in AP and IBSS modes.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 271733cf
...@@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, ...@@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* honour this flag if possible. * honour this flag if possible.
* *
* @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
* is not set then only those addressed to this station. * is not set then only those addressed to this station.
* *
* @FIF_OTHER_BSS: pass frames destined to other BSSes * @FIF_OTHER_BSS: pass frames destined to other BSSes
* *
* @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
* those addressed to this station. * those addressed to this station.
*
* @FIF_PROBE_REQ: pass probe request frames
*/ */
enum ieee80211_filter_flags { enum ieee80211_filter_flags {
FIF_PROMISC_IN_BSS = 1<<0, FIF_PROMISC_IN_BSS = 1<<0,
...@@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags { ...@@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags {
FIF_CONTROL = 1<<5, FIF_CONTROL = 1<<5,
FIF_OTHER_BSS = 1<<6, FIF_OTHER_BSS = 1<<6,
FIF_PSPOLL = 1<<7, FIF_PSPOLL = 1<<7,
FIF_PROBE_REQ = 1<<8,
}; };
/** /**
......
...@@ -1604,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, ...@@ -1604,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
return 0; return 0;
} }
static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
struct net_device *dev,
u16 frame_type, bool reg)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
return;
if (reg)
local->probe_req_reg++;
else
local->probe_req_reg--;
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
}
struct cfg80211_ops mac80211_config_ops = { struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface, .add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface, .del_virtual_intf = ieee80211_del_iface,
...@@ -1655,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = { ...@@ -1655,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
.mgmt_tx = ieee80211_mgmt_tx, .mgmt_tx = ieee80211_mgmt_tx,
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
.mgmt_frame_register = ieee80211_mgmt_frame_register,
}; };
...@@ -707,7 +707,9 @@ struct ieee80211_local { ...@@ -707,7 +707,9 @@ struct ieee80211_local {
int open_count; int open_count;
int monitors, cooked_mntrs; int monitors, cooked_mntrs;
/* number of interfaces with corresponding FIF_ flags */ /* number of interfaces with corresponding FIF_ flags */
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
fif_probe_req;
int probe_req_reg;
unsigned int filter_flags; /* FIF_* */ unsigned int filter_flags; /* FIF_* */
bool wiphy_ciphers_allocated; bool wiphy_ciphers_allocated;
......
...@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) ...@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
ieee80211_start_mesh(sdata); ieee80211_start_mesh(sdata);
} else if (sdata->vif.type == NL80211_IFTYPE_AP) { } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll++; local->fif_pspoll++;
local->fif_probe_req++;
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
local->fif_probe_req++;
} }
changed |= ieee80211_reset_erp_info(sdata); changed |= ieee80211_reset_erp_info(sdata);
...@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ...@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if (sdata->flags & IEEE80211_SDATA_PROMISC) if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_dec(&local->iff_promiscs); atomic_dec(&local->iff_promiscs);
if (sdata->vif.type == NL80211_IFTYPE_AP) if (sdata->vif.type == NL80211_IFTYPE_AP) {
local->fif_pspoll--; local->fif_pspoll--;
local->fif_probe_req--;
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
local->fif_probe_req--;
}
netif_addr_lock_bh(sdata->dev); netif_addr_lock_bh(sdata->dev);
spin_lock_bh(&local->filter_lock); spin_lock_bh(&local->filter_lock);
......
...@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) ...@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
if (local->monitors || local->scanning) if (local->monitors || local->scanning)
new_flags |= FIF_BCN_PRBRESP_PROMISC; new_flags |= FIF_BCN_PRBRESP_PROMISC;
if (local->fif_probe_req || local->probe_req_reg)
new_flags |= FIF_PROBE_REQ;
if (local->fif_fcsfail) if (local->fif_fcsfail)
new_flags |= FIF_FCSFAIL; new_flags |= FIF_FCSFAIL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment