From 697a00af3b2e22e85b46fc5ebbe2662523fdfa34 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Dec 2011 10:39:40 +0100 Subject: [PATCH] --- yaml --- r: 278624 b: refs/heads/master c: 3df6eaea76a9e1351b539541c0314129a0e4b10c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/ieee80211.h | 17 +++++++++++++++++ trunk/net/mac80211/rx.c | 13 ++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 7c54baf26d94..d0ececd7221d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: aa5b549215f85cf48a7040bc9d33c4dae0c7d11a +refs/heads/master: 3df6eaea76a9e1351b539541c0314129a0e4b10c diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h index 66cedf6eb5c2..17f2a768e2ad 100644 --- a/trunk/include/linux/ieee80211.h +++ b/trunk/include/linux/ieee80211.h @@ -1694,6 +1694,23 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) return false; } +/** + * ieee80211_is_public_action - check if frame is a public action frame + * @hdr: the frame + * @len: length of the frame + */ +static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr, + size_t len) +{ + struct ieee80211_mgmt *mgmt = (void *)hdr; + + if (len < IEEE80211_MIN_ACTION_SIZE) + return false; + if (!ieee80211_is_action(hdr->frame_control)) + return false; + return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC; +} + /** * ieee80211_fhss_chan_to_freq - get channel frequency * @channel: the FHSS channel diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 2a85fdfebde2..7d226417ef46 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -2797,10 +2797,17 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { + /* + * Accept public action frames even when the + * BSSID doesn't match, this is used for P2P + * and location updates. Note that mac80211 + * itself never looks at these frames. + */ + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && + ieee80211_is_public_action(hdr, skb->len)) + return 1; if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && - !ieee80211_is_beacon(hdr->frame_control) && - !(ieee80211_is_action(hdr->frame_control) && - sdata->vif.p2p)) + !ieee80211_is_beacon(hdr->frame_control)) return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; }