diff options
author | Johannes Berg | 2014-08-12 20:34:30 +0200 |
---|---|---|
committer | Johannes Berg | 2014-08-26 11:16:01 +0200 |
commit | 0e227084aee36b3ba27b4fc9cd9e425be6ce2ab8 (patch) | |
tree | 5a862e85d25ad5cf05e8f47800e20de792592e91 /net/wireless/scan.c | |
parent | f41ef64853fb1e02728e56b2d0d55aef8ed12b26 (diff) |
cfg80211: clarify BSS probe response vs. beacon data
There are a few possible cases of where BSS data came from:
1) only a beacon has been received
2) only a probe response has been received
3) the driver didn't report what it received (this happens when
using cfg80211_inform_bss[_width]())
4) both probe response and beacon data has been received
Unfortunately, in the userspace API, a few things weren't there:
a) there was no way to differentiate cases 1) and 4) above
without comparing the data of the IEs
b) the TSF was always from the last frame, instead of being
exposed for beacon/probe response separately like IEs
Fix this by
i) exporting a new flag attribute that indicates whether or
not probe response data has been received - this addresses (a)
ii) exporting a BEACON_TSF attribute that holds the beacon's TSF
if a beacon has been received
iii) not exporting the beacon attributes in case (3) above as that
would just lead userspace into thinking the data actually came
from a beacon when that isn't clear
To implement this, track inside the IEs struct whether or not it
(definitely) came from a beacon.
Reported-by: William Seto
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0798c62e6085..ad1a1a2808d3 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -918,11 +918,12 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, * override the IEs pointer should we have received an earlier * indication of Probe Response data. */ - ies = kmalloc(sizeof(*ies) + ielen, gfp); + ies = kzalloc(sizeof(*ies) + ielen, gfp); if (!ies) return NULL; ies->len = ielen; ies->tsf = tsf; + ies->from_beacon = false; memcpy(ies->data, ie, ielen); rcu_assign_pointer(tmp.pub.beacon_ies, ies); @@ -982,11 +983,12 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, if (!channel) return NULL; - ies = kmalloc(sizeof(*ies) + ielen, gfp); + ies = kzalloc(sizeof(*ies) + ielen, gfp); if (!ies) return NULL; ies->len = ielen; ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); + ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); if (ieee80211_is_probe_resp(mgmt->frame_control)) |