aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h10
-rw-r--r--include/net/cfg80211.h26
-rw-r--r--net/mac80211/rx.c22
-rw-r--r--net/wireless/mlme.c22
-rw-r--r--net/wireless/nl80211.c16
-rw-r--r--net/wireless/nl80211.h6
6 files changed, 100 insertions, 2 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1cee56b3a79a..7483a89cee8f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -399,6 +399,13 @@
399 * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the 399 * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
400 * network is determined by the network interface. 400 * network is determined by the network interface.
401 * 401 *
402 * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
403 * notification. This event is used to indicate that an unprotected
404 * deauthentication frame was dropped when MFP is in use.
405 * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
406 * notification. This event is used to indicate that an unprotected
407 * disassociation frame was dropped when MFP is in use.
408 *
402 * @NL80211_CMD_MAX: highest used command number 409 * @NL80211_CMD_MAX: highest used command number
403 * @__NL80211_CMD_AFTER_LAST: internal use 410 * @__NL80211_CMD_AFTER_LAST: internal use
404 */ 411 */
@@ -508,6 +515,9 @@ enum nl80211_commands {
508 NL80211_CMD_JOIN_MESH, 515 NL80211_CMD_JOIN_MESH,
509 NL80211_CMD_LEAVE_MESH, 516 NL80211_CMD_LEAVE_MESH,
510 517
518 NL80211_CMD_UNPROT_DEAUTHENTICATE,
519 NL80211_CMD_UNPROT_DISASSOCIATE,
520
511 /* add new commands above here */ 521 /* add new commands above here */
512 522
513 /* used to define NL80211_CMD_MAX below */ 523 /* used to define NL80211_CMD_MAX below */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f45e15f12446..3d1c09b777e8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2360,6 +2360,32 @@ void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf,
2360 size_t len); 2360 size_t len);
2361 2361
2362/** 2362/**
2363 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
2364 * @dev: network device
2365 * @buf: deauthentication frame (header + body)
2366 * @len: length of the frame data
2367 *
2368 * This function is called whenever a received Deauthentication frame has been
2369 * dropped in station mode because of MFP being used but the Deauthentication
2370 * frame was not protected. This function may sleep.
2371 */
2372void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
2373 size_t len);
2374
2375/**
2376 * cfg80211_send_unprot_disassoc - notification of unprotected disassociation
2377 * @dev: network device
2378 * @buf: disassociation frame (header + body)
2379 * @len: length of the frame data
2380 *
2381 * This function is called whenever a received Disassociation frame has been
2382 * dropped in station mode because of MFP being used but the Disassociation
2383 * frame was not protected. This function may sleep.
2384 */
2385void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
2386 size_t len);
2387
2388/**
2363 * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) 2389 * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
2364 * @dev: network device 2390 * @dev: network device
2365 * @addr: The source MAC address of the frame 2391 * @addr: The source MAC address of the frame
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 052789ef4745..4573ce1e1d15 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1540,12 +1540,30 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1540 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1540 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1541 if (unlikely(!ieee80211_has_protected(fc) && 1541 if (unlikely(!ieee80211_has_protected(fc) &&
1542 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1542 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1543 rx->key)) 1543 rx->key)) {
1544 if (ieee80211_is_deauth(fc))
1545 cfg80211_send_unprot_deauth(rx->sdata->dev,
1546 rx->skb->data,
1547 rx->skb->len);
1548 else if (ieee80211_is_disassoc(fc))
1549 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1550 rx->skb->data,
1551 rx->skb->len);
1544 return -EACCES; 1552 return -EACCES;
1553 }
1545 /* BIP does not use Protected field, so need to check MMIE */ 1554 /* BIP does not use Protected field, so need to check MMIE */
1546 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1555 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1547 ieee80211_get_mmie_keyidx(rx->skb) < 0)) 1556 ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
1557 if (ieee80211_is_deauth(fc))
1558 cfg80211_send_unprot_deauth(rx->sdata->dev,
1559 rx->skb->data,
1560 rx->skb->len);
1561 else if (ieee80211_is_disassoc(fc))
1562 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1563 rx->skb->data,
1564 rx->skb->len);
1548 return -EACCES; 1565 return -EACCES;
1566 }
1549 /* 1567 /*
1550 * When using MFP, Action frames are not allowed prior to 1568 * When using MFP, Action frames are not allowed prior to
1551 * having configured keys. 1569 * having configured keys.
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d7680f2a4c5b..aa5df8865ff7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
263} 263}
264EXPORT_SYMBOL(cfg80211_send_disassoc); 264EXPORT_SYMBOL(cfg80211_send_disassoc);
265 265
266void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
267 size_t len)
268{
269 struct wireless_dev *wdev = dev->ieee80211_ptr;
270 struct wiphy *wiphy = wdev->wiphy;
271 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
272
273 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
274}
275EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
276
277void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
278 size_t len)
279{
280 struct wireless_dev *wdev = dev->ieee80211_ptr;
281 struct wiphy *wiphy = wdev->wiphy;
282 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
283
284 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
285}
286EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
287
266static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) 288static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
267{ 289{
268 int i; 290 int i;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 594a6ac8b9d2..aefce54d47e2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5473,6 +5473,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
5473 NL80211_CMD_DISASSOCIATE, gfp); 5473 NL80211_CMD_DISASSOCIATE, gfp);
5474} 5474}
5475 5475
5476void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
5477 struct net_device *netdev, const u8 *buf,
5478 size_t len, gfp_t gfp)
5479{
5480 nl80211_send_mlme_event(rdev, netdev, buf, len,
5481 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
5482}
5483
5484void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
5485 struct net_device *netdev, const u8 *buf,
5486 size_t len, gfp_t gfp)
5487{
5488 nl80211_send_mlme_event(rdev, netdev, buf, len,
5489 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
5490}
5491
5476static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 5492static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
5477 struct net_device *netdev, int cmd, 5493 struct net_device *netdev, int cmd,
5478 const u8 *addr, gfp_t gfp) 5494 const u8 *addr, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 16c2f7190768..e3f7fa886966 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
26 struct net_device *netdev, 26 struct net_device *netdev,
27 const u8 *buf, size_t len, gfp_t gfp); 27 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev,
30 const u8 *buf, size_t len, gfp_t gfp);
31void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
32 struct net_device *netdev,
33 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, 34void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev, 35 struct net_device *netdev,
30 const u8 *addr, gfp_t gfp); 36 const u8 *addr, gfp_t gfp);