diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-12-06 04:39:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-06 16:07:07 -0500 |
commit | 3df6eaea76a9e1351b539541c0314129a0e4b10c (patch) | |
tree | d5dcdafdcf236e3293eeca39db9715292389e88b | |
parent | aa5b549215f85cf48a7040bc9d33c4dae0c7d11a (diff) |
mac80211: accept public action frames with mismatched BSSID
Arik's patch "mac80211: allow action frames with unknown
BSSID in GO mode" allowed any action frames in P2P mode
to go through, but only to cooked monitor interfaces as
the IEEE80211_RX_RA_MATCH was still cleared. As a result
my no-monitor patches broke invitation responses.
Instead of allowing any action frames in P2P GO mode to
go through with a wrong BSSID like that patch did, allow
all public action frames. They will never be processed
by mac80211, but can be reported via nl80211 then.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/ieee80211.h | 17 | ||||
-rw-r--r-- | net/mac80211/rx.c | 13 |
2 files changed, 27 insertions, 3 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 66cedf6eb5c2..17f2a768e2ad 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -1695,6 +1695,23 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) | |||
1695 | } | 1695 | } |
1696 | 1696 | ||
1697 | /** | 1697 | /** |
1698 | * ieee80211_is_public_action - check if frame is a public action frame | ||
1699 | * @hdr: the frame | ||
1700 | * @len: length of the frame | ||
1701 | */ | ||
1702 | static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr, | ||
1703 | size_t len) | ||
1704 | { | ||
1705 | struct ieee80211_mgmt *mgmt = (void *)hdr; | ||
1706 | |||
1707 | if (len < IEEE80211_MIN_ACTION_SIZE) | ||
1708 | return false; | ||
1709 | if (!ieee80211_is_action(hdr->frame_control)) | ||
1710 | return false; | ||
1711 | return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC; | ||
1712 | } | ||
1713 | |||
1714 | /** | ||
1698 | * ieee80211_fhss_chan_to_freq - get channel frequency | 1715 | * ieee80211_fhss_chan_to_freq - get channel frequency |
1699 | * @channel: the FHSS channel | 1716 | * @channel: the FHSS channel |
1700 | * | 1717 | * |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2a85fdfebde2..7d226417ef46 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2797,10 +2797,17 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2797 | return 0; | 2797 | return 0; |
2798 | } else if (!ieee80211_bssid_match(bssid, | 2798 | } else if (!ieee80211_bssid_match(bssid, |
2799 | sdata->vif.addr)) { | 2799 | sdata->vif.addr)) { |
2800 | /* | ||
2801 | * Accept public action frames even when the | ||
2802 | * BSSID doesn't match, this is used for P2P | ||
2803 | * and location updates. Note that mac80211 | ||
2804 | * itself never looks at these frames. | ||
2805 | */ | ||
2806 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | ||
2807 | ieee80211_is_public_action(hdr, skb->len)) | ||
2808 | return 1; | ||
2800 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2809 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && |
2801 | !ieee80211_is_beacon(hdr->frame_control) && | 2810 | !ieee80211_is_beacon(hdr->frame_control)) |
2802 | !(ieee80211_is_action(hdr->frame_control) && | ||
2803 | sdata->vif.p2p)) | ||
2804 | return 0; | 2811 | return 0; |
2805 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 2812 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2806 | } | 2813 | } |