Commit 4d797fce authored by Jouni Malinen's avatar Jouni Malinen Committed by Johannes Berg

cfg80211: Unprotected Beacon frame RX indication

Extend cfg80211_rx_unprot_mlme_mgmt() to cover indication of unprotected
Beacon frames in addition to the previously used Deauthentication and
Disassociation frames. The Beacon frame case is quite similar, but has
couple of exceptions: this is used both with fully unprotected and also
incorrectly protected frames and there is a rate limit on the events to
avoid unnecessary flooding netlink events in case something goes wrong.
Signed-off-by: default avatarJouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20200401142548.6990-1-jouni@codeaurora.org
[add missing kernel-doc]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 90e8f58d
...@@ -5045,6 +5045,8 @@ struct cfg80211_cqm_config; ...@@ -5045,6 +5045,8 @@ struct cfg80211_cqm_config;
* @pmsr_list: (private) peer measurement requests * @pmsr_list: (private) peer measurement requests
* @pmsr_lock: (private) peer measurements requests/results lock * @pmsr_lock: (private) peer measurements requests/results lock
* @pmsr_free_wk: (private) peer measurements cleanup work * @pmsr_free_wk: (private) peer measurements cleanup work
* @unprot_beacon_reported: (private) timestamp of last
* unprotected beacon report
*/ */
struct wireless_dev { struct wireless_dev {
struct wiphy *wiphy; struct wiphy *wiphy;
...@@ -5121,6 +5123,8 @@ struct wireless_dev { ...@@ -5121,6 +5123,8 @@ struct wireless_dev {
struct list_head pmsr_list; struct list_head pmsr_list;
spinlock_t pmsr_lock; spinlock_t pmsr_lock;
struct work_struct pmsr_free_wk; struct work_struct pmsr_free_wk;
unsigned long unprot_beacon_reported;
}; };
static inline u8 *wdev_address(struct wireless_dev *wdev) static inline u8 *wdev_address(struct wireless_dev *wdev)
...@@ -6135,12 +6139,16 @@ void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len); ...@@ -6135,12 +6139,16 @@ void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len);
/** /**
* cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame
* @dev: network device * @dev: network device
* @buf: deauthentication frame (header + body) * @buf: received management frame (header + body)
* @len: length of the frame data * @len: length of the frame data
* *
* This function is called whenever a received deauthentication or dissassoc * This function is called whenever a received deauthentication or dissassoc
* frame has been dropped in station mode because of MFP being used but the * frame has been dropped in station mode because of MFP being used but the
* frame was not protected. This function may sleep. * frame was not protected. This is also used to notify reception of a Beacon
* frame that was dropped because it did not include a valid MME MIC while
* beacon protection was enabled (BIGTK configured in station mode).
*
* This function may sleep.
*/ */
void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev,
const u8 *buf, size_t len); const u8 *buf, size_t len);
......
...@@ -1151,6 +1151,11 @@ ...@@ -1151,6 +1151,11 @@
* @NL80211_CMD_SET_TID_CONFIG: Data frame TID specific configuration * @NL80211_CMD_SET_TID_CONFIG: Data frame TID specific configuration
* is passed using %NL80211_ATTR_TID_CONFIG attribute. * is passed using %NL80211_ATTR_TID_CONFIG attribute.
* *
* @NL80211_CMD_UNPROT_BEACON: Unprotected or incorrectly protected Beacon
* frame. This event is used to indicate that a received Beacon frame was
* dropped because it did not include a valid MME MIC while beacon
* protection was enabled (BIGTK configured in station mode).
*
* @NL80211_CMD_MAX: highest used command number * @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use * @__NL80211_CMD_AFTER_LAST: internal use
*/ */
...@@ -1377,6 +1382,8 @@ enum nl80211_commands { ...@@ -1377,6 +1382,8 @@ enum nl80211_commands {
NL80211_CMD_SET_TID_CONFIG, NL80211_CMD_SET_TID_CONFIG,
NL80211_CMD_UNPROT_BEACON,
/* add new commands above here */ /* add new commands above here */
/* used to define NL80211_CMD_MAX below */ /* used to define NL80211_CMD_MAX below */
......
...@@ -15542,10 +15542,19 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, ...@@ -15542,10 +15542,19 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
if (WARN_ON(len < 2)) if (WARN_ON(len < 2))
return; return;
if (ieee80211_is_deauth(mgmt->frame_control)) if (ieee80211_is_deauth(mgmt->frame_control)) {
cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE; cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
else } else if (ieee80211_is_disassoc(mgmt->frame_control)) {
cmd = NL80211_CMD_UNPROT_DISASSOCIATE; cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
} else if (ieee80211_is_beacon(mgmt->frame_control)) {
if (wdev->unprot_beacon_reported &&
elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
return;
cmd = NL80211_CMD_UNPROT_BEACON;
wdev->unprot_beacon_reported = jiffies;
} else {
return;
}
trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1, nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
......
...@@ -694,6 +694,7 @@ void __cfg80211_connect_result(struct net_device *dev, ...@@ -694,6 +694,7 @@ void __cfg80211_connect_result(struct net_device *dev,
return; return;
} }
wdev->unprot_beacon_reported = 0;
nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr, nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
GFP_KERNEL); GFP_KERNEL);
...@@ -921,6 +922,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, ...@@ -921,6 +922,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
cfg80211_hold_bss(bss_from_pub(info->bss)); cfg80211_hold_bss(bss_from_pub(info->bss));
wdev->current_bss = bss_from_pub(info->bss); wdev->current_bss = bss_from_pub(info->bss);
wdev->unprot_beacon_reported = 0;
nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
wdev->netdev, info, GFP_KERNEL); wdev->netdev, info, GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment