From: Shaul Triebitz <[email protected]>
In MFP, do not disconnect if an unprotected deauth
or disassoc was received during D3.
For that, need to configure wowlan with MFP (IS_11W_ASSOC).
Now, in case of an unprotected deauth/disassoc, the wakeup
reason returned by the firmware will be:
IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC
(and not IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH
which will cause a disconnection).
Also, report this reason to cfg80211.
In another patch, the driver will send an SA query.
Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Miri Korenblit <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index e1c77276557d..26c01d740d0d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -925,6 +925,9 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
+ if (ap_sta->mfp)
+ wowlan_config_cmd->flags |= IS_11W_ASSOC;
+
if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) {
/* Query the last used seqno and set it */
int ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
@@ -1511,6 +1514,9 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
wakeup.tcp_match = true;
+ if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC)
+ wakeup.unprot_deauth_disassoc = true;
+
if (status->wake_packet) {
int pktsize = status->wake_packet_bufsize;
int pktlen = status->wake_packet_length;
--
2.34.1
Hi Miri,
kernel test robot noticed the following build errors:
[auto build test ERROR on wireless-next/main]
[also build test ERROR on next-20240206]
[cannot apply to wireless/main linus/master v6.8-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Miri-Korenblit/wifi-iwlwifi-mvm-fix-a-crash-when-we-run-out-of-stations/20240207-000459
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link: https://lore.kernel.org/r/20240206175739.fde438a22e3f.I3c8497520aaa95a22febff727b0ad08146965d47%40changeid
patch subject: [PATCH 09/11] wifi: iwlwifi: iwlmvm: handle unprotected deauth/disassoc in d3
config: loongarch-defconfig (https://download.01.org/0day-ci/archive/20240207/[email protected]/config)
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240207/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
drivers/net/wireless/intel/iwlwifi/mvm/d3.c: In function 'iwl_mvm_report_wakeup_reasons':
>> drivers/net/wireless/intel/iwlwifi/mvm/d3.c:1518:23: error: 'struct cfg80211_wowlan_wakeup' has no member named 'unprot_deauth_disassoc'
1518 | wakeup.unprot_deauth_disassoc = true;
| ^
vim +1518 drivers/net/wireless/intel/iwlwifi/mvm/d3.c
1465
1466 static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1467 struct ieee80211_vif *vif,
1468 struct iwl_wowlan_status_data *status)
1469 {
1470 struct sk_buff *pkt = NULL;
1471 struct cfg80211_wowlan_wakeup wakeup = {
1472 .pattern_idx = -1,
1473 };
1474 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1475 u32 reasons = status->wakeup_reasons;
1476
1477 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1478 wakeup_report = NULL;
1479 goto report;
1480 }
1481
1482 pm_wakeup_event(mvm->dev, 0);
1483
1484 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
1485 wakeup.magic_pkt = true;
1486
1487 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
1488 wakeup.pattern_idx =
1489 status->pattern_number;
1490
1491 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1492 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH |
1493 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE))
1494 wakeup.disconnect = true;
1495
1496 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
1497 wakeup.gtk_rekey_failure = true;
1498
1499 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1500 wakeup.rfkill_release = true;
1501
1502 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
1503 wakeup.eap_identity_req = true;
1504
1505 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
1506 wakeup.four_way_handshake = true;
1507
1508 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1509 wakeup.tcp_connlost = true;
1510
1511 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1512 wakeup.tcp_nomoretokens = true;
1513
1514 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1515 wakeup.tcp_match = true;
1516
1517 if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC)
> 1518 wakeup.unprot_deauth_disassoc = true;
1519
1520 if (status->wake_packet) {
1521 int pktsize = status->wake_packet_bufsize;
1522 int pktlen = status->wake_packet_length;
1523 const u8 *pktdata = status->wake_packet;
1524 const struct ieee80211_hdr *hdr = (const void *)pktdata;
1525 int truncated = pktlen - pktsize;
1526
1527 /* this would be a firmware bug */
1528 if (WARN_ON_ONCE(truncated < 0))
1529 truncated = 0;
1530
1531 if (ieee80211_is_data(hdr->frame_control)) {
1532 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
1533 int ivlen = 0, icvlen = 4; /* also FCS */
1534
1535 pkt = alloc_skb(pktsize, GFP_KERNEL);
1536 if (!pkt)
1537 goto report;
1538
1539 skb_put_data(pkt, pktdata, hdrlen);
1540 pktdata += hdrlen;
1541 pktsize -= hdrlen;
1542
1543 if (ieee80211_has_protected(hdr->frame_control)) {
1544 /*
1545 * This is unlocked and using gtk_i(c)vlen,
1546 * but since everything is under RTNL still
1547 * that's not really a problem - changing
1548 * it would be difficult.
1549 */
1550 if (is_multicast_ether_addr(hdr->addr1)) {
1551 ivlen = mvm->gtk_ivlen;
1552 icvlen += mvm->gtk_icvlen;
1553 } else {
1554 ivlen = mvm->ptk_ivlen;
1555 icvlen += mvm->ptk_icvlen;
1556 }
1557 }
1558
1559 /* if truncated, FCS/ICV is (partially) gone */
1560 if (truncated >= icvlen) {
1561 icvlen = 0;
1562 truncated -= icvlen;
1563 } else {
1564 icvlen -= truncated;
1565 truncated = 0;
1566 }
1567
1568 pktsize -= ivlen + icvlen;
1569 pktdata += ivlen;
1570
1571 skb_put_data(pkt, pktdata, pktsize);
1572
1573 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
1574 goto report;
1575 wakeup.packet = pkt->data;
1576 wakeup.packet_present_len = pkt->len;
1577 wakeup.packet_len = pkt->len - truncated;
1578 wakeup.packet_80211 = false;
1579 } else {
1580 int fcslen = 4;
1581
1582 if (truncated >= 4) {
1583 truncated -= 4;
1584 fcslen = 0;
1585 } else {
1586 fcslen -= truncated;
1587 truncated = 0;
1588 }
1589 pktsize -= fcslen;
1590 wakeup.packet = status->wake_packet;
1591 wakeup.packet_present_len = pktsize;
1592 wakeup.packet_len = pktlen - truncated;
1593 wakeup.packet_80211 = true;
1594 }
1595 }
1596
1597 report:
1598 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1599 kfree_skb(pkt);
1600 }
1601
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Miri,
kernel test robot noticed the following build errors:
[auto build test ERROR on wireless-next/main]
[also build test ERROR on next-20240206]
[cannot apply to wireless/main linus/master v6.8-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Miri-Korenblit/wifi-iwlwifi-mvm-fix-a-crash-when-we-run-out-of-stations/20240207-000459
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link: https://lore.kernel.org/r/20240206175739.fde438a22e3f.I3c8497520aaa95a22febff727b0ad08146965d47%40changeid
patch subject: [PATCH 09/11] wifi: iwlwifi: iwlmvm: handle unprotected deauth/disassoc in d3
config: powerpc-randconfig-001-20240207 (https://download.01.org/0day-ci/archive/20240207/[email protected]/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 7dd790db8b77c4a833c06632e903dc4f13877a64)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240207/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
>> drivers/net/wireless/intel/iwlwifi/mvm/d3.c:1518:10: error: no member named 'unprot_deauth_disassoc' in 'struct cfg80211_wowlan_wakeup'
1518 | wakeup.unprot_deauth_disassoc = true;
| ~~~~~~ ^
1 error generated.
vim +1518 drivers/net/wireless/intel/iwlwifi/mvm/d3.c
1465
1466 static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1467 struct ieee80211_vif *vif,
1468 struct iwl_wowlan_status_data *status)
1469 {
1470 struct sk_buff *pkt = NULL;
1471 struct cfg80211_wowlan_wakeup wakeup = {
1472 .pattern_idx = -1,
1473 };
1474 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1475 u32 reasons = status->wakeup_reasons;
1476
1477 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1478 wakeup_report = NULL;
1479 goto report;
1480 }
1481
1482 pm_wakeup_event(mvm->dev, 0);
1483
1484 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
1485 wakeup.magic_pkt = true;
1486
1487 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
1488 wakeup.pattern_idx =
1489 status->pattern_number;
1490
1491 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1492 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH |
1493 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE))
1494 wakeup.disconnect = true;
1495
1496 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
1497 wakeup.gtk_rekey_failure = true;
1498
1499 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1500 wakeup.rfkill_release = true;
1501
1502 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
1503 wakeup.eap_identity_req = true;
1504
1505 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
1506 wakeup.four_way_handshake = true;
1507
1508 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1509 wakeup.tcp_connlost = true;
1510
1511 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1512 wakeup.tcp_nomoretokens = true;
1513
1514 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1515 wakeup.tcp_match = true;
1516
1517 if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC)
> 1518 wakeup.unprot_deauth_disassoc = true;
1519
1520 if (status->wake_packet) {
1521 int pktsize = status->wake_packet_bufsize;
1522 int pktlen = status->wake_packet_length;
1523 const u8 *pktdata = status->wake_packet;
1524 const struct ieee80211_hdr *hdr = (const void *)pktdata;
1525 int truncated = pktlen - pktsize;
1526
1527 /* this would be a firmware bug */
1528 if (WARN_ON_ONCE(truncated < 0))
1529 truncated = 0;
1530
1531 if (ieee80211_is_data(hdr->frame_control)) {
1532 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
1533 int ivlen = 0, icvlen = 4; /* also FCS */
1534
1535 pkt = alloc_skb(pktsize, GFP_KERNEL);
1536 if (!pkt)
1537 goto report;
1538
1539 skb_put_data(pkt, pktdata, hdrlen);
1540 pktdata += hdrlen;
1541 pktsize -= hdrlen;
1542
1543 if (ieee80211_has_protected(hdr->frame_control)) {
1544 /*
1545 * This is unlocked and using gtk_i(c)vlen,
1546 * but since everything is under RTNL still
1547 * that's not really a problem - changing
1548 * it would be difficult.
1549 */
1550 if (is_multicast_ether_addr(hdr->addr1)) {
1551 ivlen = mvm->gtk_ivlen;
1552 icvlen += mvm->gtk_icvlen;
1553 } else {
1554 ivlen = mvm->ptk_ivlen;
1555 icvlen += mvm->ptk_icvlen;
1556 }
1557 }
1558
1559 /* if truncated, FCS/ICV is (partially) gone */
1560 if (truncated >= icvlen) {
1561 icvlen = 0;
1562 truncated -= icvlen;
1563 } else {
1564 icvlen -= truncated;
1565 truncated = 0;
1566 }
1567
1568 pktsize -= ivlen + icvlen;
1569 pktdata += ivlen;
1570
1571 skb_put_data(pkt, pktdata, pktsize);
1572
1573 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
1574 goto report;
1575 wakeup.packet = pkt->data;
1576 wakeup.packet_present_len = pkt->len;
1577 wakeup.packet_len = pkt->len - truncated;
1578 wakeup.packet_80211 = false;
1579 } else {
1580 int fcslen = 4;
1581
1582 if (truncated >= 4) {
1583 truncated -= 4;
1584 fcslen = 0;
1585 } else {
1586 fcslen -= truncated;
1587 truncated = 0;
1588 }
1589 pktsize -= fcslen;
1590 wakeup.packet = status->wake_packet;
1591 wakeup.packet_present_len = pktsize;
1592 wakeup.packet_len = pktlen - truncated;
1593 wakeup.packet_80211 = true;
1594 }
1595 }
1596
1597 report:
1598 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1599 kfree_skb(pkt);
1600 }
1601
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki