* [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data
@ 2014-08-12 19:03 Johannes Berg
2014-08-12 19:03 ` [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() Johannes Berg
2014-08-13 10:57 ` [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Eliad Peller
0 siblings, 2 replies; 11+ messages in thread
From: Johannes Berg @ 2014-08-12 19:03 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
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
Reported-by: William Seto
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/uapi/linux/nl80211.h | 16 ++++++++++++++--
net/wireless/core.h | 2 ++
net/wireless/nl80211.c | 16 ++++++++++++----
net/wireless/scan.c | 10 ++++++++++
4 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f1db15b9c041..d097568da690 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3055,14 +3055,20 @@ enum nl80211_bss_scan_width {
* @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
* @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
* @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ * (if @NL80211_BSS_PRESP_DATA is present then this is known to be
+ * from a probe response, otherwise it may be from the same beacon
+ * that the NL80211_BSS_BEACON_TSF will be from)
* @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
* @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
* @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
* raw information elements from the probe response/beacon (bin);
- * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
- * from a Probe Response frame; otherwise they are from a Beacon frame.
+ * if the %NL80211_BSS_BEACON_IES attribute is present and the data is
+ * different then the IEs here are from a Probe Response frame; otherwise
+ * they are from a Beacon frame.
* However, if the driver does not indicate the source of the IEs, these
* IEs may be from either frame subtype.
+ * If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the
+ * data here is known to be from a probe response, without any heuristics.
* @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
* in mBm (100 * dBm) (s32)
* @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
@@ -3074,6 +3080,10 @@ enum nl80211_bss_scan_width {
* yet been received
* @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
* (u32, enum nl80211_bss_scan_width)
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ * (not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+ * @NL80211_BSS_TSF is known to be from a probe response (flag attribute)
* @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute
*/
@@ -3091,6 +3101,8 @@ enum nl80211_bss {
NL80211_BSS_SEEN_MS_AGO,
NL80211_BSS_BEACON_IES,
NL80211_BSS_CHAN_WIDTH,
+ NL80211_BSS_BEACON_TSF,
+ NL80211_BSS_PRESP_DATA,
/* keep last */
__NL80211_BSS_AFTER_LAST,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index e9afbf10e756..08d17c1c5a47 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -127,6 +127,8 @@ struct cfg80211_internal_bss {
unsigned long refcount;
atomic_t hold;
+ bool known_frame_type;
+
/* must be last because of priv member */
struct cfg80211_bss pub;
};
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 13997c954249..2fdb8bc01a32 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6034,7 +6034,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
const struct cfg80211_bss_ies *ies;
void *hdr;
struct nlattr *bss;
- bool tsf = false;
ASSERT_WDEV_LOCK(wdev);
@@ -6061,18 +6060,27 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
goto nla_put_failure;
rcu_read_lock();
+ /* indicate whether we have probe response data or not */
+ if (rcu_access_pointer(res->proberesp_ies) &&
+ nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
+ goto fail_unlock_rcu;
+
+ /* this pointer prefers to be pointed to probe response data
+ * but is always valid
+ */
ies = rcu_dereference(res->ies);
if (ies) {
if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
goto fail_unlock_rcu;
- tsf = true;
if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
ies->len, ies->data))
goto fail_unlock_rcu;
}
+
+ /* and this pointer is always (unless driver didn't know) beacon data */
ies = rcu_dereference(res->beacon_ies);
- if (ies) {
- if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
+ if (intbss->known_frame_type && ies) {
+ if (nla_put_u64(msg, NL80211_BSS_BEACON_TSF, ies->tsf))
goto fail_unlock_rcu;
if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
ies->len, ies->data))
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0798c62e6085..b5904bae74f2 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -925,6 +925,10 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
ies->tsf = tsf;
memcpy(ies->data, ie, ielen);
+ /* assume from beacon in absence of info - needed so it's freed,
+ * but see known_frame_type below - we set it to false so no
+ * assumptions are made
+ */
rcu_assign_pointer(tmp.pub.beacon_ies, ies);
rcu_assign_pointer(tmp.pub.ies, ies);
@@ -937,6 +941,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
if (res->pub.capability & WLAN_CAPABILITY_ESS)
regulatory_hint_found_beacon(wiphy, channel, gfp);
+ /* assume drivers don't mix and match too badly */
+ res->known_frame_type = false;
+
trace_cfg80211_return_bss(&res->pub);
/* cfg80211_bss_update gives us a referenced result */
return &res->pub;
@@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
if (res->pub.capability & WLAN_CAPABILITY_ESS)
regulatory_hint_found_beacon(wiphy, channel, gfp);
+ /* assume drivers don't mix and match too badly */
+ res->known_frame_type = true;
+
trace_cfg80211_return_bss(&res->pub);
/* cfg80211_bss_update gives us a referenced result */
return &res->pub;
--
2.0.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() 2014-08-12 19:03 [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Johannes Berg @ 2014-08-12 19:03 ` Johannes Berg 2014-08-14 8:57 ` Kalle Valo 2014-08-14 9:23 ` Arend van Spriel 2014-08-13 10:57 ` [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Eliad Peller 1 sibling, 2 replies; 11+ messages in thread From: Johannes Berg @ 2014-08-12 19:03 UTC (permalink / raw) To: linux-wireless; +Cc: kvalo, Johannes Berg From: Johannes Berg <johannes.berg@intel.com> When using the cfg80211_inform_bss[_width]() functions drivers cannot currently indicate whether the data was received in a beacon or probe response. Fix that by passing a new enum that indicates such (or unknown). For good measure, use it in ath6kl. Signed-off-by: Johannes Berg <johannes.berg@intel.com> --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 + drivers/net/wireless/ath/ath6kl/wmi.c | 43 +++++----------------- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 18 ++++++--- drivers/net/wireless/libertas/cfg.c | 2 + drivers/net/wireless/mwifiex/cfg80211.c | 1 + drivers/net/wireless/mwifiex/scan.c | 3 +- drivers/net/wireless/orinoco/scan.c | 14 ++++--- drivers/net/wireless/rndis_wlan.c | 14 ++++--- drivers/staging/wlan-ng/cfg80211.c | 1 + include/net/cfg80211.h | 20 +++++++++- net/wireless/scan.c | 21 ++++++++--- 12 files changed, 78 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 0e26f4a34fda..357515b1c882 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -717,6 +717,7 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, memcpy(ie + 2, vif->ssid, vif->ssid_len); memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len); bss = cfg80211_inform_bss(ar->wiphy, chan, + CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0, cap_val, 100, ie, 2 + vif->ssid_len + beacon_ie_len, 0, GFP_KERNEL); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index eca3014e9544..929ba5d4bb4b 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1043,7 +1043,6 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, u8 *buf; struct ieee80211_channel *channel; struct ath6kl *ar = wmi->parent_dev; - struct ieee80211_mgmt *mgmt; struct cfg80211_bss *bss; if (len <= sizeof(struct wmi_bss_info_hdr2)) @@ -1089,39 +1088,15 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, } } - /* - * In theory, use of cfg80211_inform_bss() would be more natural here - * since we do not have the full frame. However, at least for now, - * cfg80211 can only distinguish Beacon and Probe Response frames from - * each other when using cfg80211_inform_bss_frame(), so let's build a - * fake IEEE 802.11 header to be able to take benefit of this. - */ - mgmt = kmalloc(24 + len, GFP_ATOMIC); - if (mgmt == NULL) - return -EINVAL; - - if (bih->frame_type == BEACON_FTYPE) { - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_BEACON); - memset(mgmt->da, 0xff, ETH_ALEN); - } else { - struct net_device *dev = vif->ndev; - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - memcpy(mgmt->da, dev->dev_addr, ETH_ALEN); - } - mgmt->duration = cpu_to_le16(0); - memcpy(mgmt->sa, bih->bssid, ETH_ALEN); - memcpy(mgmt->bssid, bih->bssid, ETH_ALEN); - mgmt->seq_ctrl = cpu_to_le16(0); - - memcpy(&mgmt->u.beacon, buf, len); - - bss = cfg80211_inform_bss_frame(ar->wiphy, channel, mgmt, - 24 + len, (bih->snr - 95) * 100, - GFP_ATOMIC); - kfree(mgmt); + bss = cfg80211_inform_bss(ar->wiphy, channel, + bih->frame_type == BEACON_FTYPE ? + CFG80211_BSS_FTYPE_BEACON : + CFG80211_BSS_FTYPE_PRESP, + bih->bssid, get_unaligned_le64((__le64 *)buf), + get_unaligned_le16(((__le16 *)buf) + 5), + get_unaligned_le16(((__le16 *)buf) + 4), + buf + 8 + 2 + 2, len - 8 - 2 - 2, + (bih->snr - 95) * 100, GFP_ATOMIC); if (bss == NULL) return -ENOMEM; cfg80211_put_bss(ar->wiphy, bss); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 16787e9124a2..bc4932142f63 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -335,7 +335,7 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) rx_mgmt_frame->bssid); cfg80211_put_bss(wiphy, bss); } else { - wil_err(wil, "cfg80211_inform_bss() failed\n"); + wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); } } else { cfg80211_rx_mgmt(wil->wdev, freq, signal, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index d8fa276e368b..9a45ef064dd9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2429,9 +2429,13 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "Signal: %d\n", notify_signal); - bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, - 0, notify_capability, notify_interval, notify_ie, - notify_ielen, notify_signal, GFP_KERNEL); + bss = cfg80211_inform_bss(wiphy, notify_channel, + CFG80211_BSS_FTYPE_UNKNOWN, + (const u8 *)bi->BSSID, + 0, notify_capability, + notify_interval, notify_ie, + notify_ielen, notify_signal, + GFP_KERNEL); if (!bss) return -ENOMEM; @@ -2533,9 +2537,11 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "signal: %d\n", notify_signal); - bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, - 0, notify_capability, notify_interval, - notify_ie, notify_ielen, notify_signal, GFP_KERNEL); + bss = cfg80211_inform_bss(wiphy, notify_channel, + CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0, + notify_capability, notify_interval, + notify_ie, notify_ielen, notify_signal, + GFP_KERNEL); if (!bss) { err = -ENOMEM; diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 47a998d8f99e..22884ba7d6cc 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -653,6 +653,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, if (channel && !(channel->flags & IEEE80211_CHAN_DISABLED)) { bss = cfg80211_inform_bss(wiphy, channel, + CFG80211_BSS_FTYPE_UNKNOWN, bssid, get_unaligned_le64(tsfdesc), capa, intvl, ie, ielen, LBS_SCAN_RSSI_TO_MBM(rssi), @@ -1754,6 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv, bss = cfg80211_inform_bss(priv->wdev->wiphy, params->chandef.chan, + CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0, capability, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 149d2e693bdd..00e4d7a3281f 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1588,6 +1588,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) band)); bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, + CFG80211_BSS_FTYPE_UNKNOWN, bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 0, ie_buf, ie_len, 0, GFP_KERNEL); cfg80211_put_bss(priv->wdev->wiphy, bss); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 45c5b3450cf5..f0f3257fe968 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1719,7 +1719,8 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { bss = cfg80211_inform_bss(priv->wdev->wiphy, - chan, bssid, timestamp, + chan, CFG80211_BSS_FTYPE_UNKNOWN, + bssid, timestamp, cap_info_bitmap, beacon_period, ie_buf, ie_len, rssi, GFP_KERNEL); bss_priv = (struct mwifiex_bss_priv *)bss->priv; diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index e175b9b8561b..2c66166add70 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c @@ -123,9 +123,10 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, beacon_interval = le16_to_cpu(bss->a.beacon_interv); signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); - cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, - capability, beacon_interval, ie_buf, ie_len, - signal, GFP_KERNEL); + cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, + bss->a.bssid, timestamp, capability, + beacon_interval, ie_buf, ie_len, signal, + GFP_KERNEL); cfg80211_put_bss(wiphy, cbss); } @@ -156,9 +157,10 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, ie = bss->data; signal = SIGNAL_TO_MBM(bss->level); - cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, - capability, beacon_interval, ie, ie_len, - signal, GFP_KERNEL); + cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, + bss->bssid, timestamp, capability, + beacon_interval, ie, ie_len, signal, + GFP_KERNEL); cfg80211_put_bss(wiphy, cbss); } diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d2a9a08210be..1a4facd1fbf3 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2022,9 +2022,10 @@ static bool rndis_bss_info_update(struct usbnet *usbdev, capability = le16_to_cpu(fixed->capabilities); beacon_interval = le16_to_cpu(fixed->beacon_interval); - bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, - timestamp, capability, beacon_interval, ie, ie_len, signal, - GFP_KERNEL); + bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, + CFG80211_BSS_FTYPE_UNKNOWN, bssid->mac, + timestamp, capability, beacon_interval, + ie, ie_len, signal, GFP_KERNEL); cfg80211_put_bss(priv->wdev.wiphy, bss); return (bss != NULL); @@ -2711,9 +2712,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, bssid, (u32)timestamp, capability, beacon_period, ie_len, ssid.essid, signal); - bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, - timestamp, capability, beacon_period, ie_buf, ie_len, - signal, GFP_KERNEL); + bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, + CFG80211_BSS_FTYPE_UNKNOWN, bssid, + timestamp, capability, beacon_period, + ie_buf, ie_len, signal, GFP_KERNEL); cfg80211_put_bss(priv->wdev.wiphy, bss); } diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 723319ee08f3..955ec2e6a95c 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -420,6 +420,7 @@ static int prism2_scan(struct wiphy *wiphy, IEEE80211_BAND_2GHZ); bss = cfg80211_inform_bss(wiphy, ieee80211_get_channel(wiphy, freq), + CFG80211_BSS_FTYPE_UNKNOWN, (const u8 *) &(msg2.bssid.data.data), msg2.timestamp.data, msg2.capinfo.data, msg2.beaconperiod.data, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7b8dac3efe8f..cd21585e3368 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3765,11 +3765,25 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, } /** - * cfg80211_inform_bss - inform cfg80211 of a new BSS + * enum cfg80211_bss_frame_type - frame type that the BSS data came from + * @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is + * from a beacon or probe response + * @CFG80211_BSS_FTYPE_BEACON: data comes from a beacon + * @CFG80211_BSS_FTYPE_PRESP: data comes from a probe response + */ +enum cfg80211_bss_frame_type { + CFG80211_BSS_FTYPE_UNKNOWN, + CFG80211_BSS_FTYPE_BEACON, + CFG80211_BSS_FTYPE_PRESP, +}; + +/** + * cfg80211_inform_bss_width - inform cfg80211 of a new BSS * * @wiphy: the wiphy reporting the BSS * @rx_channel: The channel the frame was received on * @scan_width: width of the control channel + * @ftype: frame type (if known) * @bssid: the BSSID of the BSS * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) * @capability: the capability field sent by the peer @@ -3789,6 +3803,7 @@ struct cfg80211_bss * __must_check cfg80211_inform_bss_width(struct wiphy *wiphy, struct ieee80211_channel *rx_channel, enum nl80211_bss_scan_width scan_width, + enum cfg80211_bss_frame_type ftype, const u8 *bssid, u64 tsf, u16 capability, u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp); @@ -3796,12 +3811,13 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, static inline struct cfg80211_bss * __must_check cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *rx_channel, + enum cfg80211_bss_frame_type ftype, const u8 *bssid, u64 tsf, u16 capability, u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp) { return cfg80211_inform_bss_width(wiphy, rx_channel, - NL80211_BSS_CHAN_WIDTH_20, + NL80211_BSS_CHAN_WIDTH_20, ftype, bssid, tsf, capability, beacon_interval, ie, ielen, signal, gfp); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b5904bae74f2..87d1e2fe4f1c 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -884,6 +884,7 @@ struct cfg80211_bss* cfg80211_inform_bss_width(struct wiphy *wiphy, struct ieee80211_channel *rx_channel, enum nl80211_bss_scan_width scan_width, + enum cfg80211_bss_frame_type ftype, const u8 *bssid, u64 tsf, u16 capability, u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp) @@ -925,11 +926,19 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, ies->tsf = tsf; memcpy(ies->data, ie, ielen); - /* assume from beacon in absence of info - needed so it's freed, - * but see known_frame_type below - we set it to false so no - * assumptions are made - */ - rcu_assign_pointer(tmp.pub.beacon_ies, ies); + switch (ftype) { + case CFG80211_BSS_FTYPE_UNKNOWN: + /* assume from beacon in absence of info - needed so it's freed, + * but see known_frame_type below - we set it to false so no + * assumptions are made + */ + case CFG80211_BSS_FTYPE_BEACON: + rcu_assign_pointer(tmp.pub.beacon_ies, ies); + break; + case CFG80211_BSS_FTYPE_PRESP: + rcu_assign_pointer(tmp.pub.proberesp_ies, ies); + break; + } rcu_assign_pointer(tmp.pub.ies, ies); signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= @@ -942,7 +951,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, regulatory_hint_found_beacon(wiphy, channel, gfp); /* assume drivers don't mix and match too badly */ - res->known_frame_type = false; + res->known_frame_type = ftype != CFG80211_BSS_FTYPE_UNKNOWN;; trace_cfg80211_return_bss(&res->pub); /* cfg80211_bss_update gives us a referenced result */ -- 2.0.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() 2014-08-12 19:03 ` [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() Johannes Berg @ 2014-08-14 8:57 ` Kalle Valo 2014-08-14 9:23 ` Arend van Spriel 1 sibling, 0 replies; 11+ messages in thread From: Kalle Valo @ 2014-08-14 8:57 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless, Johannes Berg, ath6kl Johannes Berg <johannes@sipsolutions.net> writes: > From: Johannes Berg <johannes.berg@intel.com> > > When using the cfg80211_inform_bss[_width]() functions drivers > cannot currently indicate whether the data was received in a > beacon or probe response. Fix that by passing a new enum that > indicates such (or unknown). > > For good measure, use it in ath6kl. > > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > --- > drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 + > drivers/net/wireless/ath/ath6kl/wmi.c | 43 +++++----------------- Thanks. For the ath6kl part: Acked-by: Kalle Valo <kvalo@qca.qualcomm.com> -- Kalle Valo ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() 2014-08-12 19:03 ` [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() Johannes Berg 2014-08-14 8:57 ` Kalle Valo @ 2014-08-14 9:23 ` Arend van Spriel 1 sibling, 0 replies; 11+ messages in thread From: Arend van Spriel @ 2014-08-14 9:23 UTC (permalink / raw) To: Johannes Berg, linux-wireless; +Cc: kvalo, Johannes Berg On 08/12/2014 09:03 PM, Johannes Berg wrote: > From: Johannes Berg <johannes.berg@intel.com> > > When using the cfg80211_inform_bss[_width]() functions drivers > cannot currently indicate whether the data was received in a > beacon or probe response. Fix that by passing a new enum that > indicates such (or unknown). > > For good measure, use it in ath6kl. > > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > --- > drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 + > drivers/net/wireless/ath/ath6kl/wmi.c | 43 +++++----------------- > drivers/net/wireless/ath/wil6210/wmi.c | 2 +- > .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 18 ++++++--- > drivers/net/wireless/libertas/cfg.c | 2 + > drivers/net/wireless/mwifiex/cfg80211.c | 1 + > drivers/net/wireless/mwifiex/scan.c | 3 +- > drivers/net/wireless/orinoco/scan.c | 14 ++++--- > drivers/net/wireless/rndis_wlan.c | 14 ++++--- > drivers/staging/wlan-ng/cfg80211.c | 1 + > include/net/cfg80211.h | 20 +++++++++- > net/wireless/scan.c | 21 ++++++++--- > 12 files changed, 78 insertions(+), 62 deletions(-) [...] > diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c > index d8fa276e368b..9a45ef064dd9 100644 > --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c > +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c > @@ -2429,9 +2429,13 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, > brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); > brcmf_dbg(CONN, "Signal: %d\n", notify_signal); > > - bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, > - 0, notify_capability, notify_interval, notify_ie, > - notify_ielen, notify_signal, GFP_KERNEL); > + bss = cfg80211_inform_bss(wiphy, notify_channel, > + CFG80211_BSS_FTYPE_UNKNOWN, Checked the firmware API and it does not provide this info. Acked-by: Arend van Spriel <arend@broadcom.com> Regards, Arend ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-12 19:03 [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Johannes Berg 2014-08-12 19:03 ` [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() Johannes Berg @ 2014-08-13 10:57 ` Eliad Peller 2014-08-13 11:08 ` Johannes Berg 1 sibling, 1 reply; 11+ messages in thread From: Eliad Peller @ 2014-08-13 10:57 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Kalle Valo, Johannes Berg On Tue, Aug 12, 2014 at 10:03 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > From: Johannes Berg <johannes.berg@intel.com> > > 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 > > Reported-by: William Seto > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > --- [...] > @@ -937,6 +941,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, > if (res->pub.capability & WLAN_CAPABILITY_ESS) > regulatory_hint_found_beacon(wiphy, channel, gfp); > > + /* assume drivers don't mix and match too badly */ > + res->known_frame_type = false; > + > trace_cfg80211_return_bss(&res->pub); > /* cfg80211_bss_update gives us a referenced result */ > return &res->pub; > @@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, > if (res->pub.capability & WLAN_CAPABILITY_ESS) > regulatory_hint_found_beacon(wiphy, channel, gfp); > > + /* assume drivers don't mix and match too badly */ > + res->known_frame_type = true; > + i think you should set the flag only in case of a beacon. otherwise, you might "validate" res->ies although it contains probe response data. Eliad. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 10:57 ` [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Eliad Peller @ 2014-08-13 11:08 ` Johannes Berg 2014-08-13 11:13 ` Eliad Peller 0 siblings, 1 reply; 11+ messages in thread From: Johannes Berg @ 2014-08-13 11:08 UTC (permalink / raw) To: Eliad Peller; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, 2014-08-13 at 13:57 +0300, Eliad Peller wrote: > > @@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, > > if (res->pub.capability & WLAN_CAPABILITY_ESS) > > regulatory_hint_found_beacon(wiphy, channel, gfp); > > > > + /* assume drivers don't mix and match too badly */ > > + res->known_frame_type = true; > > + > > i think you should set the flag only in case of a beacon. > otherwise, you might "validate" res->ies although it contains probe > response data. Hm, what do you mean? If we have known frametype and we have beacon_ies, then IEs in nl80211 are certain to be proberesp_ies ... johannes ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 11:08 ` Johannes Berg @ 2014-08-13 11:13 ` Eliad Peller 2014-08-13 11:20 ` Johannes Berg 0 siblings, 1 reply; 11+ messages in thread From: Eliad Peller @ 2014-08-13 11:13 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, Aug 13, 2014 at 2:08 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > On Wed, 2014-08-13 at 13:57 +0300, Eliad Peller wrote: > > >> > @@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, >> > if (res->pub.capability & WLAN_CAPABILITY_ESS) >> > regulatory_hint_found_beacon(wiphy, channel, gfp); >> > >> > + /* assume drivers don't mix and match too badly */ >> > + res->known_frame_type = true; >> > + >> >> i think you should set the flag only in case of a beacon. >> otherwise, you might "validate" res->ies although it contains probe >> response data. > > Hm, what do you mean? If we have known frametype and we have beacon_ies, > then IEs in nl80211 are certain to be proberesp_ies ... > sorry, i meant res->beacon_ies. consider the following flow: cfg80211_inform_bss_width(presp1): * beacon_ies = presp1 * known_frame_type = false cfg80211_inform_bss_width_frame(presp2): * proberesp_ies = presp2 * beacon_ies = presp1 * known_frame_type = true Eliad. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 11:13 ` Eliad Peller @ 2014-08-13 11:20 ` Johannes Berg 2014-08-13 11:39 ` Eliad Peller 0 siblings, 1 reply; 11+ messages in thread From: Johannes Berg @ 2014-08-13 11:20 UTC (permalink / raw) To: Eliad Peller; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, 2014-08-13 at 14:13 +0300, Eliad Peller wrote: > On Wed, Aug 13, 2014 at 2:08 PM, Johannes Berg > <johannes@sipsolutions.net> wrote: > > On Wed, 2014-08-13 at 13:57 +0300, Eliad Peller wrote: > > > > > >> > @@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, > >> > if (res->pub.capability & WLAN_CAPABILITY_ESS) > >> > regulatory_hint_found_beacon(wiphy, channel, gfp); > >> > > >> > + /* assume drivers don't mix and match too badly */ > >> > + res->known_frame_type = true; > >> > + > >> > >> i think you should set the flag only in case of a beacon. > >> otherwise, you might "validate" res->ies although it contains probe > >> response data. > > > > Hm, what do you mean? If we have known frametype and we have beacon_ies, > > then IEs in nl80211 are certain to be proberesp_ies ... > > > sorry, i meant res->beacon_ies. > > consider the following flow: > cfg80211_inform_bss_width(presp1): > * beacon_ies = presp1 > * known_frame_type = false > > cfg80211_inform_bss_width_frame(presp2): > * proberesp_ies = presp2 > * beacon_ies = presp1 > * known_frame_type = true Yeah, well, I'm hoping that drivers wouldn't be so stupid? :) Maybe we should just get rid of the requirement to assign beacon_ies with the bss_width() call and make free() smarter? johannes ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 11:20 ` Johannes Berg @ 2014-08-13 11:39 ` Eliad Peller 2014-08-13 11:46 ` Johannes Berg 0 siblings, 1 reply; 11+ messages in thread From: Eliad Peller @ 2014-08-13 11:39 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, Aug 13, 2014 at 2:20 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > On Wed, 2014-08-13 at 14:13 +0300, Eliad Peller wrote: >> On Wed, Aug 13, 2014 at 2:08 PM, Johannes Berg >> <johannes@sipsolutions.net> wrote: >> > On Wed, 2014-08-13 at 13:57 +0300, Eliad Peller wrote: >> > >> > >> >> > @@ -1011,6 +1018,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, >> >> > if (res->pub.capability & WLAN_CAPABILITY_ESS) >> >> > regulatory_hint_found_beacon(wiphy, channel, gfp); >> >> > >> >> > + /* assume drivers don't mix and match too badly */ >> >> > + res->known_frame_type = true; >> >> > + >> >> >> >> i think you should set the flag only in case of a beacon. >> >> otherwise, you might "validate" res->ies although it contains probe >> >> response data. >> > >> > Hm, what do you mean? If we have known frametype and we have beacon_ies, >> > then IEs in nl80211 are certain to be proberesp_ies ... >> > >> sorry, i meant res->beacon_ies. >> >> consider the following flow: >> cfg80211_inform_bss_width(presp1): >> * beacon_ies = presp1 >> * known_frame_type = false >> >> cfg80211_inform_bss_width_frame(presp2): >> * proberesp_ies = presp2 >> * beacon_ies = presp1 >> * known_frame_type = true > > Yeah, well, I'm hoping that drivers wouldn't be so stupid? :) > well, they just use the api... :) > Maybe we should just get rid of the requirement to assign beacon_ies > with the bss_width() call and make free() smarter? this will also require changing cfg80211_bss_update() to take care of this case, etc. not sure we really want to complicate it further more. Eliad. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 11:39 ` Eliad Peller @ 2014-08-13 11:46 ` Johannes Berg 2014-08-13 11:57 ` Eliad Peller 0 siblings, 1 reply; 11+ messages in thread From: Johannes Berg @ 2014-08-13 11:46 UTC (permalink / raw) To: Eliad Peller; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, 2014-08-13 at 14:39 +0300, Eliad Peller wrote: > > Maybe we should just get rid of the requirement to assign beacon_ies > > with the bss_width() call and make free() smarter? > > this will also require changing cfg80211_bss_update() to take care of > this case, etc. > not sure we really want to complicate it further more. Good point. So let's say we change this to "known_from_beacon", is that enough? Debugging now - guess I'll poke again later. johannes ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data 2014-08-13 11:46 ` Johannes Berg @ 2014-08-13 11:57 ` Eliad Peller 0 siblings, 0 replies; 11+ messages in thread From: Eliad Peller @ 2014-08-13 11:57 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Kalle Valo On Wed, Aug 13, 2014 at 2:46 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > On Wed, 2014-08-13 at 14:39 +0300, Eliad Peller wrote: > >> > Maybe we should just get rid of the requirement to assign beacon_ies >> > with the bss_width() call and make free() smarter? >> >> this will also require changing cfg80211_bss_update() to take care of >> this case, etc. >> not sure we really want to complicate it further more. > > Good point. So let's say we change this to "known_from_beacon", is that > enough? > yes. sounds good. Eliad. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-08-14 9:24 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-08-12 19:03 [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Johannes Berg 2014-08-12 19:03 ` [PATCH 2/2] cfg80211: allow passing frame type to cfg80211_inform_bss() Johannes Berg 2014-08-14 8:57 ` Kalle Valo 2014-08-14 9:23 ` Arend van Spriel 2014-08-13 10:57 ` [PATCH 1/2] cfg80211: clarify BSS probe response vs. beacon data Eliad Peller 2014-08-13 11:08 ` Johannes Berg 2014-08-13 11:13 ` Eliad Peller 2014-08-13 11:20 ` Johannes Berg 2014-08-13 11:39 ` Eliad Peller 2014-08-13 11:46 ` Johannes Berg 2014-08-13 11:57 ` Eliad Peller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).