mac80211: accept public action frames with mismatched BSSID
authorJohannes Berg <johannes.berg@intel.com>
Tue, 6 Dec 2011 09:39:40 +0000 (10:39 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 6 Dec 2011 21:07:07 +0000 (16:07 -0500)
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>
include/linux/ieee80211.h
net/mac80211/rx.c

index 66cedf6..17f2a76 100644 (file)
@@ -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
index 2a85fdf..7d22641 100644 (file)
@@ -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;
                }