mac80211: report OBSS beacons
authorJohannes Berg <johannes.berg@intel.com>
Fri, 4 Nov 2011 10:18:18 +0000 (11:18 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 9 Nov 2011 21:13:52 +0000 (16:13 -0500)
If there's an interface in AP mode, OBSS beacons
are needed by hostapd/wpa_s to implement logic to
enable/disable protection etc. Report the frames
and set the capability flag.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/rx.c

index 386330c89bafe019f60914da460cb894ad96d75c..4bef6eca1722b4dd9f0c557b0c048b94eace29ec 100644 (file)
@@ -184,12 +184,15 @@ enum ieee80211_packet_rx_flags {
  * enum ieee80211_rx_flags - RX data flags
  *
  * @IEEE80211_RX_CMNTR: received on cooked monitor already
+ * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
+ *     to cfg80211_report_obss_beacon().
  *
  * These flags are used across handling multiple interfaces
  * for a single frame.
  */
 enum ieee80211_rx_flags {
        IEEE80211_RX_CMNTR              = BIT(0),
+       IEEE80211_RX_BEACON_REPORTED    = BIT(1),
 };
 
 struct ieee80211_rx_data {
index 7217019d1ed9be35d4d68a3a74cfaa455b063dd5..8e9327bca910a6c4578ad9113502a71400d10fc9 100644 (file)
@@ -593,7 +593,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        wiphy->flags |= WIPHY_FLAG_NETNS_OK |
                        WIPHY_FLAG_4ADDR_AP |
-                       WIPHY_FLAG_4ADDR_STATION;
+                       WIPHY_FLAG_4ADDR_STATION |
+                       WIPHY_FLAG_REPORTS_OBSS;
 
        if (!ops->set_key)
                wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
index e832e0dcab3c6d51bb8e6e60dd20af117ff8254e..2ed882f8a9f8018b1eadbdd9c286d67c987d3ea5 100644 (file)
@@ -2188,6 +2188,18 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
        if (!ieee80211_is_mgmt(mgmt->frame_control))
                return RX_DROP_MONITOR;
 
+       if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
+           ieee80211_is_beacon(mgmt->frame_control) &&
+           !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
+               struct ieee80211_rx_status *status;
+
+               status = IEEE80211_SKB_RXCB(rx->skb);
+               cfg80211_report_obss_beacon(rx->local->hw.wiphy,
+                                           rx->skb->data, rx->skb->len,
+                                           status->freq, GFP_ATOMIC);
+               rx->flags |= IEEE80211_RX_BEACON_REPORTED;
+       }
+
        if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
                return RX_DROP_MONITOR;