Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: move action code from per-type frame structs

The action code actually serves to identify the type of action
frame, so it really isn't part of the per-type structure. Pull
it out and have it in the general action frame format.

In theory, whether or not the action code is present in this
way is up to each category, but all categories that are defined
right now all have that value.

While at it, and since this change requires changing all users,
remove the 'u' and make it an anonymous union in this case, so
that all code using this changes.

Change IEEE80211_MIN_ACTION_SIZE to take an argument which says
how much of the frame is needed, e.g. category, action_code or
the specific frame type that's defined in the union. Again this
also ensures that all code is updated.

In some cases, fix bugs where the SKB length was checked after
having accessed beyond the checked length, in particular in FTM
code, e.g. ieee80211_is_ftm().

Link: https://patch.msgid.link/20260226183607.67e71846b59e.I9a24328e3ffcaae179466a935f1c3345029f9961@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+308 -392
+2 -2
drivers/net/wireless/ath/ath11k/mac.c
··· 6288 6288 lockdep_assert_held(&ar->conf_mutex); 6289 6289 6290 6290 /* make sure category field is present */ 6291 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 6291 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 6292 6292 return -EINVAL; 6293 6293 6294 - remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE; 6294 + remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category); 6295 6295 has_protected = ieee80211_has_protected(hdr->frame_control); 6296 6296 6297 6297 /* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
+2 -2
drivers/net/wireless/ath/ath12k/mac.c
··· 9119 9119 lockdep_assert_wiphy(wiphy); 9120 9120 9121 9121 /* make sure category field is present */ 9122 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 9122 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 9123 9123 return -EINVAL; 9124 9124 9125 - remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE; 9125 + remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category); 9126 9126 has_protected = ieee80211_has_protected(hdr->frame_control); 9127 9127 9128 9128 /* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
+1 -1
drivers/net/wireless/ath/ath12k/wifi7/hw.c
··· 104 104 if (mgmt->u.action.category != WLAN_CATEGORY_BACK) 105 105 return false; 106 106 107 - if (mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP) 107 + if (mgmt->u.action.action_code != WLAN_ACTION_ADDBA_RESP) 108 108 return false; 109 109 110 110 return true;
+3 -3
drivers/net/wireless/intel/iwlwifi/mld/time_sync.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2025 Intel Corporation 3 + * Copyright (C) 2025-2026 Intel Corporation 4 4 */ 5 5 6 6 #include "mld.h" ··· 116 116 u8 skb_dialog_token; 117 117 118 118 if (ieee80211_is_timing_measurement(skb)) 119 - skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token; 119 + skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token; 120 120 else 121 - skb_dialog_token = mgmt->u.action.u.ftm.dialog_token; 121 + skb_dialog_token = mgmt->u.action.ftm.dialog_token; 122 122 123 123 if ((ether_addr_equal(mgmt->sa, addr) || 124 124 ether_addr_equal(mgmt->da, addr)) &&
+3 -4
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 3 * Copyright (C) 2015-2017 Intel Deutschland GmbH 4 - * Copyright (C) 2018-2025 Intel Corporation 4 + * Copyright (C) 2018-2026 Intel Corporation 5 5 */ 6 6 #include <linux/etherdevice.h> 7 7 #include <linux/math64.h> ··· 1409 1409 struct iwl_mvm_loc_entry *entry; 1410 1410 const u8 *ies, *lci, *civic, *msr_ie; 1411 1411 size_t ies_len, lci_len = 0, civic_len = 0; 1412 - size_t baselen = IEEE80211_MIN_ACTION_SIZE + 1413 - sizeof(mgmt->u.action.u.ftm); 1412 + size_t baselen = IEEE80211_MIN_ACTION_SIZE(ftm); 1414 1413 static const u8 rprt_type_lci = IEEE80211_SPCT_MSR_RPRT_TYPE_LCI; 1415 1414 static const u8 rprt_type_civic = IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC; 1416 1415 ··· 1418 1419 1419 1420 lockdep_assert_held(&mvm->mutex); 1420 1421 1421 - ies = mgmt->u.action.u.ftm.variable; 1422 + ies = mgmt->u.action.ftm.variable; 1422 1423 ies_len = len - baselen; 1423 1424 1424 1425 msr_ie = cfg80211_find_ie_match(WLAN_EID_MEASURE_REPORT, ies, ies_len,
+3 -3
drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2022 Intel Corporation 3 + * Copyright (C) 2022, 2026 Intel Corporation 4 4 */ 5 5 6 6 #include "mvm.h" ··· 18 18 u8 skb_dialog_token; 19 19 20 20 if (ieee80211_is_timing_measurement(skb)) 21 - skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token; 21 + skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token; 22 22 else 23 - skb_dialog_token = mgmt->u.action.u.ftm.dialog_token; 23 + skb_dialog_token = mgmt->u.action.ftm.dialog_token; 24 24 25 25 if ((ether_addr_equal(mgmt->sa, addr) || 26 26 ether_addr_equal(mgmt->da, addr)) &&
+4 -8
drivers/net/wireless/marvell/mwifiex/tdls.c
··· 755 755 switch (action_code) { 756 756 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 757 757 /* See the layout of 'struct ieee80211_mgmt'. */ 758 - extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + 759 - sizeof(mgmt->u.action.category); 758 + extra = IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp) - 24; 760 759 skb_put(skb, extra); 761 760 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 762 - mgmt->u.action.u.tdls_discover_resp.action_code = 763 - WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 764 - mgmt->u.action.u.tdls_discover_resp.dialog_token = 765 - dialog_token; 766 - mgmt->u.action.u.tdls_discover_resp.capability = 767 - cpu_to_le16(capab); 761 + mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 762 + mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token; 763 + mgmt->u.action.tdls_discover_resp.capability = cpu_to_le16(capab); 768 764 /* move back for addr4 */ 769 765 memmove(pos + ETH_ALEN, &mgmt->u.action, extra); 770 766 /* init address 4 */
+2 -2
drivers/net/wireless/marvell/mwl8k.c
··· 1985 1985 */ 1986 1986 if (unlikely(ieee80211_is_action(wh->frame_control) && 1987 1987 mgmt->u.action.category == WLAN_CATEGORY_BACK && 1988 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ && 1988 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ && 1989 1989 priv->ap_fw)) { 1990 - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 1990 + u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 1991 1991 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1992 1992 index = mwl8k_tid_queue_mapping(tid); 1993 1993 }
+3 -3
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
··· 413 413 u32 val; 414 414 415 415 if (ieee80211_is_action(fc) && 416 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + 1 + 2 && 416 + skb->len >= IEEE80211_MIN_ACTION_SIZE(addba_req.capab) && 417 417 mgmt->u.action.category == WLAN_CATEGORY_BACK && 418 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { 419 - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 418 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) { 419 + u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 420 420 421 421 txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); 422 422 tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
+2 -2
drivers/net/wireless/mediatek/mt76/mt7925/mac.c
··· 668 668 u32 val; 669 669 670 670 if (ieee80211_is_action(fc) && 671 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && 671 + skb->len >= IEEE80211_MIN_ACTION_SIZE(action_code) && 672 672 mgmt->u.action.category == WLAN_CATEGORY_BACK && 673 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) 673 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) 674 674 tid = MT_TX_ADDBA; 675 675 else if (ieee80211_is_mgmt(hdr->frame_control)) 676 676 tid = MT_TX_NORMAL;
+2 -2
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
··· 800 800 u32 val; 801 801 802 802 if (ieee80211_is_action(fc) && 803 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && 803 + skb->len >= IEEE80211_MIN_ACTION_SIZE(action_code) && 804 804 mgmt->u.action.category == WLAN_CATEGORY_BACK && 805 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { 805 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) { 806 806 if (is_mt7990(&dev->mt76)) 807 807 txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TID_ADDBA, tid)); 808 808 else
+7 -7
drivers/net/wireless/realtek/rtl8xxxu/core.c
··· 5146 5146 if (!(rtl8xxxu_debug & RTL8XXXU_DEBUG_ACTION)) 5147 5147 return; 5148 5148 5149 - switch (mgmt->u.action.u.addba_resp.action_code) { 5149 + switch (mgmt->u.action.action_code) { 5150 5150 case WLAN_ACTION_ADDBA_RESP: 5151 - cap = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 5152 - timeout = le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); 5151 + cap = le16_to_cpu(mgmt->u.action.addba_resp.capab); 5152 + timeout = le16_to_cpu(mgmt->u.action.addba_resp.timeout); 5153 5153 dev_info(dev, "WLAN_ACTION_ADDBA_RESP: " 5154 5154 "timeout %i, tid %02x, buf_size %02x, policy %02x, " 5155 5155 "status %02x\n", ··· 5157 5157 (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2, 5158 5158 (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6, 5159 5159 (cap >> 1) & 0x1, 5160 - le16_to_cpu(mgmt->u.action.u.addba_resp.status)); 5160 + le16_to_cpu(mgmt->u.action.addba_resp.status)); 5161 5161 break; 5162 5162 case WLAN_ACTION_ADDBA_REQ: 5163 - cap = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 5164 - timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 5163 + cap = le16_to_cpu(mgmt->u.action.addba_req.capab); 5164 + timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout); 5165 5165 dev_info(dev, "WLAN_ACTION_ADDBA_REQ: " 5166 5166 "timeout %i, tid %02x, buf_size %02x, policy %02x\n", 5167 5167 timeout, ··· 5171 5171 break; 5172 5172 default: 5173 5173 dev_info(dev, "action frame %02x\n", 5174 - mgmt->u.action.u.addba_resp.action_code); 5174 + mgmt->u.action.action_code); 5175 5175 break; 5176 5176 } 5177 5177 }
+14 -14
drivers/net/wireless/realtek/rtlwifi/base.c
··· 1409 1409 sta_entry = 1410 1410 (struct rtl_sta_info *)sta->drv_priv; 1411 1411 capab = 1412 - le16_to_cpu(mgmt->u.action.u.addba_req.capab); 1412 + le16_to_cpu(mgmt->u.action.addba_req.capab); 1413 1413 tid = (capab & 1414 1414 IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1415 1415 if (tid >= MAX_TID_COUNT) { ··· 2392 2392 struct sk_buff *skb; 2393 2393 struct ieee80211_mgmt *action_frame; 2394 2394 2395 - /* 27 = header + category + action + smps mode */ 2396 - skb = dev_alloc_skb(27 + hw->extra_tx_headroom); 2395 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) + 2396 + hw->extra_tx_headroom); 2397 2397 if (!skb) 2398 2398 return NULL; 2399 2399 2400 2400 skb_reserve(skb, hw->extra_tx_headroom); 2401 - action_frame = skb_put_zero(skb, 27); 2401 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps)); 2402 2402 memcpy(action_frame->da, da, ETH_ALEN); 2403 2403 memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); 2404 2404 memcpy(action_frame->bssid, bssid, ETH_ALEN); 2405 2405 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2406 2406 IEEE80211_STYPE_ACTION); 2407 2407 action_frame->u.action.category = WLAN_CATEGORY_HT; 2408 - action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; 2408 + action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS; 2409 2409 switch (smps) { 2410 2410 case IEEE80211_SMPS_AUTOMATIC:/* 0 */ 2411 2411 case IEEE80211_SMPS_NUM_MODES:/* 4 */ 2412 2412 WARN_ON(1); 2413 2413 fallthrough; 2414 2414 case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ 2415 - action_frame->u.action.u.ht_smps.smps_control = 2415 + action_frame->u.action.ht_smps.smps_control = 2416 2416 WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ 2417 2417 break; 2418 2418 case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ 2419 - action_frame->u.action.u.ht_smps.smps_control = 2419 + action_frame->u.action.ht_smps.smps_control = 2420 2420 WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ 2421 2421 break; 2422 2422 case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ 2423 - action_frame->u.action.u.ht_smps.smps_control = 2423 + action_frame->u.action.ht_smps.smps_control = 2424 2424 WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ 2425 2425 break; 2426 2426 } ··· 2519 2519 struct ieee80211_mgmt *action_frame; 2520 2520 u16 params; 2521 2521 2522 - /* 27 = header + category + action + smps mode */ 2523 - skb = dev_alloc_skb(34 + hw->extra_tx_headroom); 2522 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) + 2523 + hw->extra_tx_headroom); 2524 2524 if (!skb) 2525 2525 return NULL; 2526 2526 2527 2527 skb_reserve(skb, hw->extra_tx_headroom); 2528 - action_frame = skb_put_zero(skb, 34); 2528 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(delba)); 2529 2529 memcpy(action_frame->sa, sa, ETH_ALEN); 2530 2530 memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN); 2531 2531 memcpy(action_frame->bssid, bssid, ETH_ALEN); 2532 2532 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2533 2533 IEEE80211_STYPE_ACTION); 2534 2534 action_frame->u.action.category = WLAN_CATEGORY_BACK; 2535 - action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 2535 + action_frame->u.action.action_code = WLAN_ACTION_DELBA; 2536 2536 params = (u16)(1 << 11); /* bit 11 initiator */ 2537 2537 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 2538 2538 2539 - action_frame->u.action.u.delba.params = cpu_to_le16(params); 2540 - action_frame->u.action.u.delba.reason_code = 2539 + action_frame->u.action.delba.params = cpu_to_le16(params); 2540 + action_frame->u.action.delba.reason_code = 2541 2541 cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); 2542 2542 2543 2543 return skb;
+1 -1
drivers/net/wireless/realtek/rtlwifi/pci.c
··· 507 507 if (ieee80211_is_action(fc)) { 508 508 struct ieee80211_mgmt *action_frame = 509 509 (struct ieee80211_mgmt *)skb->data; 510 - if (action_frame->u.action.u.ht_smps.action == 510 + if (action_frame->u.action.action_code == 511 511 WLAN_HT_ACTION_SMPS) { 512 512 dev_kfree_skb(skb); 513 513 goto tx_status_ok;
+4 -4
drivers/net/wireless/silabs/wfx/data_rx.c
··· 21 21 if (wfx_api_older_than(wvif->wdev, 3, 6)) 22 22 return; 23 23 24 - switch (mgmt->u.action.u.addba_req.action_code) { 24 + switch (mgmt->u.action.action_code) { 25 25 case WLAN_ACTION_ADDBA_REQ: 26 - params = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 26 + params = le16_to_cpu(mgmt->u.action.addba_req.capab); 27 27 tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 28 28 ieee80211_start_rx_ba_session_offl(vif, mgmt->sa, tid); 29 29 break; 30 30 case WLAN_ACTION_DELBA: 31 - params = le16_to_cpu(mgmt->u.action.u.delba.params); 31 + params = le16_to_cpu(mgmt->u.action.delba.params); 32 32 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 33 33 ieee80211_stop_rx_ba_session_offl(vif, mgmt->sa, tid); 34 34 break; ··· 80 80 */ 81 81 if (ieee80211_is_action(frame->frame_control) && 82 82 mgmt->u.action.category == WLAN_CATEGORY_BACK && 83 - skb->len > IEEE80211_MIN_ACTION_SIZE) { 83 + skb->len > IEEE80211_MIN_ACTION_SIZE(action_code)) { 84 84 wfx_rx_handle_ba(wvif, mgmt); 85 85 goto drop; 86 86 }
+30 -53
include/linux/ieee80211.h
··· 1046 1046 } __packed probe_resp; 1047 1047 struct { 1048 1048 u8 category; 1049 + u8 action_code; 1049 1050 union { 1050 1051 struct { 1051 - u8 action_code; 1052 1052 u8 dialog_token; 1053 1053 u8 status_code; 1054 1054 u8 variable[]; 1055 1055 } __packed wme_action; 1056 1056 struct{ 1057 - u8 action_code; 1057 + u8 no_fixed_fields[0]; 1058 1058 u8 variable[]; 1059 1059 } __packed chan_switch; 1060 1060 struct{ 1061 - u8 action_code; 1062 1061 struct ieee80211_ext_chansw_ie data; 1063 1062 u8 variable[]; 1064 1063 } __packed ext_chan_switch; 1065 1064 struct{ 1066 - u8 action_code; 1067 1065 u8 dialog_token; 1068 1066 u8 element_id; 1069 1067 u8 length; 1070 1068 struct ieee80211_msrment_ie msr_elem; 1071 1069 } __packed measurement; 1072 1070 struct{ 1073 - u8 action_code; 1074 1071 u8 dialog_token; 1075 1072 __le16 capab; 1076 1073 __le16 timeout; ··· 1076 1079 u8 variable[]; 1077 1080 } __packed addba_req; 1078 1081 struct{ 1079 - u8 action_code; 1080 1082 u8 dialog_token; 1081 1083 __le16 status; 1082 1084 __le16 capab; ··· 1084 1088 u8 variable[]; 1085 1089 } __packed addba_resp; 1086 1090 struct{ 1087 - u8 action_code; 1088 1091 __le16 params; 1089 1092 __le16 reason_code; 1090 1093 } __packed delba; 1091 1094 struct { 1092 - u8 action_code; 1095 + u8 no_fixed_fields[0]; 1093 1096 u8 variable[]; 1094 1097 } __packed self_prot; 1095 1098 struct{ 1096 - u8 action_code; 1099 + u8 no_fixed_fields[0]; 1097 1100 u8 variable[]; 1098 1101 } __packed mesh_action; 1099 1102 struct { 1100 - u8 action; 1101 1103 u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; 1102 1104 } __packed sa_query; 1103 1105 struct { 1104 - u8 action; 1105 1106 u8 smps_control; 1106 1107 } __packed ht_smps; 1107 1108 struct { 1108 - u8 action_code; 1109 1109 u8 chanwidth; 1110 1110 } __packed ht_notify_cw; 1111 1111 struct { 1112 - u8 action_code; 1113 1112 u8 dialog_token; 1114 1113 __le16 capability; 1115 1114 u8 variable[]; 1116 1115 } __packed tdls_discover_resp; 1117 1116 struct { 1118 - u8 action_code; 1119 1117 u8 operating_mode; 1120 1118 } __packed vht_opmode_notif; 1121 1119 struct { 1122 - u8 action_code; 1123 1120 u8 membership[WLAN_MEMBERSHIP_LEN]; 1124 1121 u8 position[WLAN_USER_POSITION_LEN]; 1125 1122 } __packed vht_group_notif; 1126 1123 struct { 1127 - u8 action_code; 1128 1124 u8 dialog_token; 1129 1125 u8 tpc_elem_id; 1130 1126 u8 tpc_elem_length; 1131 1127 struct ieee80211_tpc_report_ie tpc; 1132 1128 } __packed tpc_report; 1133 1129 struct { 1134 - u8 action_code; 1135 1130 u8 dialog_token; 1136 1131 u8 follow_up; 1137 1132 u8 tod[6]; ··· 1132 1145 u8 variable[]; 1133 1146 } __packed ftm; 1134 1147 struct { 1135 - u8 action_code; 1148 + u8 no_fixed_fields[0]; 1136 1149 u8 variable[]; 1137 1150 } __packed s1g; 1138 1151 struct { 1139 - u8 action_code; 1140 1152 u8 dialog_token; 1141 1153 u8 follow_up; 1142 1154 u32 tod; ··· 1144 1158 u8 max_toa_error; 1145 1159 } __packed wnm_timing_msr; 1146 1160 struct { 1147 - u8 action_code; 1148 1161 u8 dialog_token; 1149 1162 u8 variable[]; 1150 1163 } __packed ttlm_req; 1151 1164 struct { 1152 - u8 action_code; 1153 1165 u8 dialog_token; 1154 1166 __le16 status_code; 1155 1167 u8 variable[]; 1156 1168 } __packed ttlm_res; 1157 1169 struct { 1158 - u8 action_code; 1170 + u8 no_fixed_fields[0]; 1171 + /* no variable fields either */ 1159 1172 } __packed ttlm_tear_down; 1160 1173 struct { 1161 - u8 action_code; 1162 1174 u8 dialog_token; 1163 1175 u8 variable[]; 1164 1176 } __packed ml_reconf_req; 1165 1177 struct { 1166 - u8 action_code; 1167 1178 u8 dialog_token; 1168 1179 u8 count; 1169 1180 u8 variable[]; 1170 1181 } __packed ml_reconf_resp; 1171 1182 struct { 1172 - u8 action_code; 1183 + u8 no_fixed_fields[0]; 1173 1184 u8 variable[]; 1174 1185 } __packed epcs; 1175 1186 struct { 1176 - u8 action_code; 1177 1187 u8 dialog_token; 1178 1188 u8 control; 1179 1189 u8 variable[]; 1180 1190 } __packed eml_omn; 1181 - } u; 1191 + }; 1182 1192 } __packed action; 1183 1193 DECLARE_FLEX_ARRAY(u8, body); /* Generic frame body */ 1184 1194 } u; ··· 1192 1210 1193 1211 #define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_UHR_PHY 1194 1212 1195 - /* mgmt header + 1 byte category code */ 1196 - #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) 1213 + #define IEEE80211_MIN_ACTION_SIZE(type) offsetofend(struct ieee80211_mgmt, u.action.type) 1197 1214 1198 1215 1199 1216 /* Management MIC information element (IEEE 802.11w) for CMAC */ ··· 2372 2391 if (!ieee80211_is_action(fc)) 2373 2392 return false; 2374 2393 2375 - if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code)) 2394 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) 2376 2395 return true; 2377 2396 2378 2397 /* action frame - additionally check for non-bufferable FTM */ ··· 2381 2400 mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION) 2382 2401 return true; 2383 2402 2384 - if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST || 2385 - mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_RESPONSE) 2403 + if (mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_REQUEST || 2404 + mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE) 2386 2405 return false; 2387 2406 2388 2407 return true; ··· 2432 2451 */ 2433 2452 static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb) 2434 2453 { 2435 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2454 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 2436 2455 return false; 2437 2456 return _ieee80211_is_robust_mgmt_frame((void *)skb->data); 2438 2457 } ··· 2448 2467 { 2449 2468 struct ieee80211_mgmt *mgmt = (void *)hdr; 2450 2469 2451 - if (len < IEEE80211_MIN_ACTION_SIZE) 2470 + if (len < IEEE80211_MIN_ACTION_SIZE(category)) 2452 2471 return false; 2453 2472 if (!ieee80211_is_action(hdr->frame_control)) 2454 2473 return false; ··· 2466 2485 static inline bool 2467 2486 ieee80211_is_protected_dual_of_public_action(struct sk_buff *skb) 2468 2487 { 2488 + struct ieee80211_mgmt *mgmt = (void *)skb->data; 2469 2489 u8 action; 2470 2490 2471 2491 if (!ieee80211_is_public_action((void *)skb->data, skb->len) || 2472 - skb->len < IEEE80211_MIN_ACTION_SIZE + 1) 2492 + skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) 2473 2493 return false; 2474 2494 2475 - action = *(u8 *)(skb->data + IEEE80211_MIN_ACTION_SIZE); 2495 + action = mgmt->u.action.action_code; 2476 2496 2477 2497 return action != WLAN_PUB_ACTION_20_40_BSS_COEX && 2478 2498 action != WLAN_PUB_ACTION_DSE_REG_LOC_ANN && ··· 2512 2530 */ 2513 2531 static inline bool ieee80211_is_group_privacy_action(struct sk_buff *skb) 2514 2532 { 2515 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2533 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 2516 2534 return false; 2517 2535 return _ieee80211_is_group_privacy_action((void *)skb->data); 2518 2536 } ··· 2608 2626 if (!ieee80211_is_action(mgmt->frame_control)) 2609 2627 return false; 2610 2628 2611 - if (skb->len < IEEE80211_MIN_ACTION_SIZE + 2612 - sizeof(mgmt->u.action.u.tpc_report)) 2629 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(tpc_report)) 2613 2630 return false; 2614 2631 2615 2632 /* ··· 2627 2646 return false; 2628 2647 2629 2648 /* both spectrum mgmt and link measurement have same action code */ 2630 - if (mgmt->u.action.u.tpc_report.action_code != 2631 - WLAN_ACTION_SPCT_TPC_RPRT) 2649 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_TPC_RPRT) 2632 2650 return false; 2633 2651 2634 - if (mgmt->u.action.u.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT || 2635 - mgmt->u.action.u.tpc_report.tpc_elem_length != 2652 + if (mgmt->u.action.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT || 2653 + mgmt->u.action.tpc_report.tpc_elem_length != 2636 2654 sizeof(struct ieee80211_tpc_report_ie)) 2637 2655 return false; 2638 2656 ··· 2647 2667 { 2648 2668 struct ieee80211_mgmt *mgmt = (void *)skb->data; 2649 2669 2650 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2670 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(wnm_timing_msr)) 2651 2671 return false; 2652 2672 2653 2673 if (!ieee80211_is_action(mgmt->frame_control)) 2654 2674 return false; 2655 2675 2656 2676 if (mgmt->u.action.category == WLAN_CATEGORY_WNM_UNPROTECTED && 2657 - mgmt->u.action.u.wnm_timing_msr.action_code == 2658 - WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE && 2659 - skb->len >= offsetofend(typeof(*mgmt), u.action.u.wnm_timing_msr)) 2677 + mgmt->u.action.action_code == 2678 + WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE) 2660 2679 return true; 2661 2680 2662 2681 return false; ··· 2670 2691 { 2671 2692 struct ieee80211_mgmt *mgmt = (void *)skb->data; 2672 2693 2694 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(ftm)) 2695 + return false; 2696 + 2673 2697 if (!ieee80211_is_public_action((void *)mgmt, skb->len)) 2674 2698 return false; 2675 2699 2676 - if (mgmt->u.action.u.ftm.action_code == 2677 - WLAN_PUB_ACTION_FTM_RESPONSE && 2678 - skb->len >= offsetofend(typeof(*mgmt), u.action.u.ftm)) 2679 - return true; 2680 - 2681 - return false; 2700 + return mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE; 2682 2701 } 2683 2702 2684 2703 struct element {
+14 -13
net/mac80211/agg-rx.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright(c) 2015-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018-2025 Intel Corporation 12 + * Copyright (C) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 /** ··· 251 251 skb_reserve(skb, local->hw.extra_tx_headroom); 252 252 mgmt = ieee80211_mgmt_ba(skb, da, sdata); 253 253 254 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp)); 254 + skb_put(skb, 2 + sizeof(mgmt->u.action.addba_resp)); 255 255 mgmt->u.action.category = WLAN_CATEGORY_BACK; 256 - mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; 257 - mgmt->u.action.u.addba_resp.dialog_token = dialog_token; 256 + mgmt->u.action.action_code = WLAN_ACTION_ADDBA_RESP; 257 + 258 + mgmt->u.action.addba_resp.dialog_token = dialog_token; 258 259 259 260 capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); 260 261 capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK); 261 262 capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); 262 263 capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 263 264 264 - mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); 265 - mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); 266 - mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); 265 + mgmt->u.action.addba_resp.capab = cpu_to_le16(capab); 266 + mgmt->u.action.addba_resp.timeout = cpu_to_le16(timeout); 267 + mgmt->u.action.addba_resp.status = cpu_to_le16(status); 267 268 268 269 if (sta->sta.valid_links || sta->sta.deflink.he_cap.has_he) 269 270 ieee80211_add_addbaext(skb, req_addba_ext_data, buf_size); ··· 478 477 u8 dialog_token, addba_ext_data; 479 478 480 479 /* extract session parameters from addba request frame */ 481 - dialog_token = mgmt->u.action.u.addba_req.dialog_token; 482 - timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 480 + dialog_token = mgmt->u.action.addba_req.dialog_token; 481 + timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout); 483 482 start_seq_num = 484 - le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4; 483 + le16_to_cpu(mgmt->u.action.addba_req.start_seq_num) >> 4; 485 484 486 - capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 485 + capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 487 486 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1; 488 487 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 489 488 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; 490 489 491 490 addba_ext_data = 492 491 ieee80211_retrieve_addba_ext_data(sta, 493 - mgmt->u.action.u.addba_req.variable, 492 + mgmt->u.action.addba_req.variable, 494 493 len - 495 494 offsetof(typeof(*mgmt), 496 - u.action.u.addba_req.variable), 495 + u.action.addba_req.variable), 497 496 &buf_size); 498 497 499 498 __ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
+14 -14
net/mac80211/agg-tx.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright(c) 2015-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018 - 2024 Intel Corporation 12 + * Copyright (C) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 68 68 struct ieee80211_mgmt *mgmt; 69 69 u16 capab; 70 70 71 - skb = dev_alloc_skb(sizeof(*mgmt) + 71 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(addba_req) + 72 72 2 + sizeof(struct ieee80211_addba_ext_ie) + 73 73 local->hw.extra_tx_headroom); 74 74 if (!skb) ··· 77 77 skb_reserve(skb, local->hw.extra_tx_headroom); 78 78 mgmt = ieee80211_mgmt_ba(skb, sta->sta.addr, sdata); 79 79 80 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); 80 + skb_put(skb, 2 + sizeof(mgmt->u.action.addba_req)); 81 81 82 82 mgmt->u.action.category = WLAN_CATEGORY_BACK; 83 - mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; 83 + mgmt->u.action.action_code = WLAN_ACTION_ADDBA_REQ; 84 84 85 - mgmt->u.action.u.addba_req.dialog_token = dialog_token; 85 + mgmt->u.action.addba_req.dialog_token = dialog_token; 86 86 capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK; 87 87 capab |= IEEE80211_ADDBA_PARAM_POLICY_MASK; 88 88 capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); 89 89 capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 90 90 91 - mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); 91 + mgmt->u.action.addba_req.capab = cpu_to_le16(capab); 92 92 93 - mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); 94 - mgmt->u.action.u.addba_req.start_seq_num = 93 + mgmt->u.action.addba_req.timeout = cpu_to_le16(timeout); 94 + mgmt->u.action.addba_req.start_seq_num = 95 95 cpu_to_le16(start_seq_num << 4); 96 96 97 97 if (sta->sta.deflink.he_cap.has_he) ··· 978 978 979 979 lockdep_assert_wiphy(sta->local->hw.wiphy); 980 980 981 - capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 981 + capab = le16_to_cpu(mgmt->u.action.addba_resp.capab); 982 982 amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; 983 983 tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK); 984 984 buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 985 985 986 986 ieee80211_retrieve_addba_ext_data(sta, 987 - mgmt->u.action.u.addba_resp.variable, 987 + mgmt->u.action.addba_resp.variable, 988 988 len - offsetof(typeof(*mgmt), 989 - u.action.u.addba_resp.variable), 989 + u.action.addba_resp.variable), 990 990 &buf_size); 991 991 992 992 buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes); ··· 999 999 if (!tid_tx) 1000 1000 return; 1001 1001 1002 - if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { 1002 + if (mgmt->u.action.addba_resp.dialog_token != tid_tx->dialog_token) { 1003 1003 ht_dbg(sta->sdata, "wrong addBA response token, %pM tid %d\n", 1004 1004 sta->sta.addr, tid); 1005 1005 return; ··· 1029 1029 * is set to 0, the Buffer Size subfield is set to a value 1030 1030 * of at least 1. 1031 1031 */ 1032 - if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 1032 + if (le16_to_cpu(mgmt->u.action.addba_resp.status) 1033 1033 == WLAN_STATUS_SUCCESS && buf_size) { 1034 1034 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 1035 1035 &tid_tx->state)) { ··· 1046 1046 sta->ampdu_mlme.addba_req_num[tid] = 0; 1047 1047 1048 1048 tid_tx->timeout = 1049 - le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); 1049 + le16_to_cpu(mgmt->u.action.addba_resp.timeout); 1050 1050 1051 1051 if (tid_tx->timeout) { 1052 1052 mod_timer(&tid_tx->session_timer,
+10 -11
net/mac80211/eht.c
··· 108 108 ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 109 109 struct ieee80211_mgmt *req, int opt_len) 110 110 { 111 - int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 111 + int len = IEEE80211_MIN_ACTION_SIZE(eml_omn); 112 112 struct ieee80211_local *local = sdata->local; 113 113 struct ieee80211_mgmt *mgmt; 114 114 struct sk_buff *skb; ··· 127 127 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 128 128 129 129 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 130 - mgmt->u.action.u.eml_omn.action_code = 131 - WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF; 132 - mgmt->u.action.u.eml_omn.dialog_token = 133 - req->u.action.u.eml_omn.dialog_token; 134 - mgmt->u.action.u.eml_omn.control = req->u.action.u.eml_omn.control & 130 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF; 131 + mgmt->u.action.eml_omn.dialog_token = 132 + req->u.action.eml_omn.dialog_token; 133 + mgmt->u.action.eml_omn.control = req->u.action.eml_omn.control & 135 134 ~(IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE | 136 135 IEEE80211_EML_CTRL_INDEV_COEX_ACT); 137 136 /* Copy optional fields from the received notification frame */ 138 - memcpy(mgmt->u.action.u.eml_omn.variable, 139 - req->u.action.u.eml_omn.variable, opt_len); 137 + memcpy(mgmt->u.action.eml_omn.variable, 138 + req->u.action.eml_omn.variable, opt_len); 140 139 141 140 ieee80211_tx_skb(sdata, skb); 142 141 } ··· 143 144 void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 144 145 struct sk_buff *skb) 145 146 { 146 - int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 147 + int len = IEEE80211_MIN_ACTION_SIZE(eml_omn); 147 148 enum nl80211_iftype type = ieee80211_vif_type_p2p(&sdata->vif); 148 149 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 149 150 const struct wiphy_iftype_ext_capab *ift_ext_capa; 150 151 struct ieee80211_mgmt *mgmt = (void *)skb->data; 151 152 struct ieee80211_local *local = sdata->local; 152 - u8 control = mgmt->u.action.u.eml_omn.control; 153 - u8 *ptr = mgmt->u.action.u.eml_omn.variable; 153 + u8 control = mgmt->u.action.eml_omn.control; 154 + u8 *ptr = mgmt->u.action.eml_omn.variable; 154 155 struct ieee80211_eml_params eml_params = { 155 156 .link_id = status->link_id, 156 157 .control = control,
+16 -15
net/mac80211/ht.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright 2017 Intel Deutschland GmbH 12 - * Copyright(c) 2020-2025 Intel Corporation 12 + * Copyright(c) 2020-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 462 462 struct ieee80211_mgmt *mgmt; 463 463 u16 params; 464 464 465 - skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 465 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) + 466 + local->hw.extra_tx_headroom); 466 467 if (!skb) 467 468 return; 468 469 469 470 skb_reserve(skb, local->hw.extra_tx_headroom); 470 471 mgmt = ieee80211_mgmt_ba(skb, da, sdata); 471 472 472 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba)); 473 + skb_put(skb, 2 + sizeof(mgmt->u.action.delba)); 473 474 474 475 mgmt->u.action.category = WLAN_CATEGORY_BACK; 475 - mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 476 + mgmt->u.action.action_code = WLAN_ACTION_DELBA; 476 477 params = (u16)(initiator << 11); /* bit 11 initiator */ 477 478 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 478 479 479 - mgmt->u.action.u.delba.params = cpu_to_le16(params); 480 - mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); 480 + mgmt->u.action.delba.params = cpu_to_le16(params); 481 + mgmt->u.action.delba.reason_code = cpu_to_le16(reason_code); 481 482 482 483 ieee80211_tx_skb(sdata, skb); 483 484 } ··· 490 489 u16 tid, params; 491 490 u16 initiator; 492 491 493 - params = le16_to_cpu(mgmt->u.action.u.delba.params); 492 + params = le16_to_cpu(mgmt->u.action.delba.params); 494 493 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 495 494 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; 496 495 497 496 ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n", 498 497 mgmt->sa, initiator ? "initiator" : "recipient", 499 498 tid, 500 - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); 499 + le16_to_cpu(mgmt->u.action.delba.reason_code)); 501 500 502 501 if (initiator == WLAN_BACK_INITIATOR) 503 502 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, ··· 531 530 struct ieee80211_tx_info *info; 532 531 u8 status_link_id = link_id < 0 ? 0 : link_id; 533 532 534 - /* 27 = header + category + action + smps mode */ 535 - skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom); 533 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) + 534 + local->hw.extra_tx_headroom); 536 535 if (!skb) 537 536 return -ENOMEM; 538 537 539 538 skb_reserve(skb, local->hw.extra_tx_headroom); 540 - action_frame = skb_put(skb, 27); 539 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps)); 541 540 memcpy(action_frame->da, da, ETH_ALEN); 542 541 memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN); 543 542 memcpy(action_frame->bssid, bssid, ETH_ALEN); 544 543 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 545 544 IEEE80211_STYPE_ACTION); 546 545 action_frame->u.action.category = WLAN_CATEGORY_HT; 547 - action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; 546 + action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS; 548 547 switch (smps) { 549 548 case IEEE80211_SMPS_AUTOMATIC: 550 549 case IEEE80211_SMPS_NUM_MODES: ··· 552 551 smps = IEEE80211_SMPS_OFF; 553 552 fallthrough; 554 553 case IEEE80211_SMPS_OFF: 555 - action_frame->u.action.u.ht_smps.smps_control = 554 + action_frame->u.action.ht_smps.smps_control = 556 555 WLAN_HT_SMPS_CONTROL_DISABLED; 557 556 break; 558 557 case IEEE80211_SMPS_STATIC: 559 - action_frame->u.action.u.ht_smps.smps_control = 558 + action_frame->u.action.ht_smps.smps_control = 560 559 WLAN_HT_SMPS_CONTROL_STATIC; 561 560 break; 562 561 case IEEE80211_SMPS_DYNAMIC: 563 - action_frame->u.action.u.ht_smps.smps_control = 562 + action_frame->u.action.ht_smps.smps_control = 564 563 WLAN_HT_SMPS_CONTROL_DYNAMIC; 565 564 break; 566 565 }
+5 -13
net/mac80211/ibss.c
··· 9 9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> 10 10 * Copyright 2013-2014 Intel Mobile Communications GmbH 11 11 * Copyright(c) 2016 Intel Deutschland GmbH 12 - * Copyright(c) 2018-2025 Intel Corporation 12 + * Copyright(c) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/delay.h> ··· 888 888 struct ieee80211_rx_status *rx_status, 889 889 struct ieee802_11_elems *elems) 890 890 { 891 - int required_len; 892 - 893 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 891 + if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch)) 894 892 return; 895 893 896 894 /* CSA is the only action we handle for now */ 897 - if (mgmt->u.action.u.measurement.action_code != 898 - WLAN_ACTION_SPCT_CHL_SWITCH) 899 - return; 900 - 901 - required_len = IEEE80211_MIN_ACTION_SIZE + 902 - sizeof(mgmt->u.action.u.chan_switch); 903 - if (len < required_len) 895 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH) 904 896 return; 905 897 906 898 if (!sdata->vif.bss_conf.csa_active) ··· 1605 1613 case WLAN_CATEGORY_SPECTRUM_MGMT: 1606 1614 ies_len = skb->len - 1607 1615 offsetof(struct ieee80211_mgmt, 1608 - u.action.u.chan_switch.variable); 1616 + u.action.chan_switch.variable); 1609 1617 1610 1618 if (ies_len < 0) 1611 1619 break; 1612 1620 1613 - elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable, 1621 + elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable, 1614 1622 ies_len, 1615 1623 IEEE80211_FTYPE_MGMT | 1616 1624 IEEE80211_STYPE_ACTION,
+9 -9
net/mac80211/iface.c
··· 1579 1579 1580 1580 sta = sta_info_get_bss(sdata, mgmt->sa); 1581 1581 if (sta) { 1582 - switch (mgmt->u.action.u.addba_req.action_code) { 1582 + switch (mgmt->u.action.action_code) { 1583 1583 case WLAN_ACTION_ADDBA_REQ: 1584 1584 ieee80211_process_addba_request(local, sta, 1585 1585 mgmt, len); ··· 1599 1599 } 1600 1600 } else if (ieee80211_is_action(mgmt->frame_control) && 1601 1601 mgmt->u.action.category == WLAN_CATEGORY_HT) { 1602 - switch (mgmt->u.action.u.ht_smps.action) { 1602 + switch (mgmt->u.action.action_code) { 1603 1603 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 1604 - u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 1604 + u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth; 1605 1605 struct ieee80211_rx_status *status; 1606 1606 struct link_sta_info *link_sta; 1607 1607 struct sta_info *sta; ··· 1628 1628 } 1629 1629 } else if (ieee80211_is_action(mgmt->frame_control) && 1630 1630 mgmt->u.action.category == WLAN_CATEGORY_VHT) { 1631 - switch (mgmt->u.action.u.vht_group_notif.action_code) { 1631 + switch (mgmt->u.action.action_code) { 1632 1632 case WLAN_VHT_ACTION_OPMODE_NOTIF: { 1633 1633 struct ieee80211_rx_status *status; 1634 1634 enum nl80211_band band; ··· 1637 1637 1638 1638 status = IEEE80211_SKB_RXCB(skb); 1639 1639 band = status->band; 1640 - opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; 1640 + opmode = mgmt->u.action.vht_opmode_notif.operating_mode; 1641 1641 1642 1642 sta = sta_info_get_bss(sdata, mgmt->sa); 1643 1643 ··· 1658 1658 } 1659 1659 } else if (ieee80211_is_action(mgmt->frame_control) && 1660 1660 mgmt->u.action.category == WLAN_CATEGORY_S1G) { 1661 - switch (mgmt->u.action.u.s1g.action_code) { 1661 + switch (mgmt->u.action.action_code) { 1662 1662 case WLAN_S1G_TWT_TEARDOWN: 1663 1663 case WLAN_S1G_TWT_SETUP: 1664 1664 ieee80211_s1g_rx_twt_action(sdata, skb); ··· 1669 1669 } else if (ieee80211_is_action(mgmt->frame_control) && 1670 1670 mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_EHT) { 1671 1671 if (sdata->vif.type == NL80211_IFTYPE_AP) { 1672 - switch (mgmt->u.action.u.eml_omn.action_code) { 1672 + switch (mgmt->u.action.action_code) { 1673 1673 case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 1674 1674 ieee80211_rx_eml_op_mode_notif(sdata, skb); 1675 1675 break; ··· 1677 1677 break; 1678 1678 } 1679 1679 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 1680 - switch (mgmt->u.action.u.ttlm_req.action_code) { 1680 + switch (mgmt->u.action.action_code) { 1681 1681 case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ: 1682 1682 ieee80211_process_neg_ttlm_req(sdata, mgmt, 1683 1683 skb->len); ··· 1765 1765 1766 1766 if (ieee80211_is_action(mgmt->frame_control) && 1767 1767 mgmt->u.action.category == WLAN_CATEGORY_S1G) { 1768 - switch (mgmt->u.action.u.s1g.action_code) { 1768 + switch (mgmt->u.action.action_code) { 1769 1769 case WLAN_S1G_TWT_TEARDOWN: 1770 1770 case WLAN_S1G_TWT_SETUP: 1771 1771 ieee80211_s1g_status_twt_action(sdata, skb);
+6 -8
net/mac80211/mesh.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2018 - 2025 Intel Corporation 4 + * Copyright (C) 2018-2026 Intel Corporation 5 5 * Authors: Luis Carlos Cobo <luisca@cozybit.com> 6 6 * Javier Cardona <javier@cozybit.com> 7 7 */ ··· 19 19 20 20 bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) 21 21 { 22 - return (mgmt->u.action.u.mesh_action.action_code == 23 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION); 22 + return mgmt->u.action.action_code == WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 24 23 } 25 24 26 25 void ieee80211s_init(void) ··· 1617 1618 size_t baselen; 1618 1619 u8 *pos; 1619 1620 1620 - if (mgmt->u.action.u.measurement.action_code != 1621 - WLAN_ACTION_SPCT_CHL_SWITCH) 1621 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH) 1622 1622 return; 1623 1623 1624 - pos = mgmt->u.action.u.chan_switch.variable; 1624 + pos = mgmt->u.action.chan_switch.variable; 1625 1625 baselen = offsetof(struct ieee80211_mgmt, 1626 - u.action.u.chan_switch.variable); 1626 + u.action.chan_switch.variable); 1627 1627 elems = ieee802_11_parse_elems(pos, len - baselen, 1628 1628 IEEE80211_FTYPE_MGMT | 1629 1629 IEEE80211_STYPE_ACTION, ··· 1668 1670 { 1669 1671 switch (mgmt->u.action.category) { 1670 1672 case WLAN_CATEGORY_SELF_PROTECTED: 1671 - switch (mgmt->u.action.u.self_prot.action_code) { 1673 + switch (mgmt->u.action.action_code) { 1672 1674 case WLAN_SP_MESH_PEERING_OPEN: 1673 1675 case WLAN_SP_MESH_PEERING_CLOSE: 1674 1676 case WLAN_SP_MESH_PEERING_CONFIRM:
+8 -12
net/mac80211/mesh_hwmp.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2019, 2021-2023, 2025 Intel Corporation 4 + * Copyright (C) 2019, 2021-2023, 2025-2026 Intel Corporation 5 5 * Author: Luis Carlos Cobo <luisca@cozybit.com> 6 6 */ 7 7 ··· 105 105 u32 lifetime, u32 metric, u32 preq_id, 106 106 struct ieee80211_sub_if_data *sdata) 107 107 { 108 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action); 108 109 struct ieee80211_local *local = sdata->local; 109 110 struct sk_buff *skb; 110 111 struct ieee80211_mgmt *mgmt; 111 112 u8 *pos, ie_len; 112 - int hdr_len = offsetofend(struct ieee80211_mgmt, 113 - u.action.u.mesh_action); 114 113 115 114 skb = dev_alloc_skb(local->tx_headroom + 116 115 hdr_len + ··· 126 127 /* BSSID == SA */ 127 128 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 128 129 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 129 - mgmt->u.action.u.mesh_action.action_code = 130 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 130 + mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 131 131 132 132 switch (action) { 133 133 case MPATH_PREQ: ··· 235 237 u8 ttl, const u8 *target, u32 target_sn, 236 238 u16 target_rcode, const u8 *ra) 237 239 { 240 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action); 238 241 struct ieee80211_local *local = sdata->local; 239 242 struct sk_buff *skb; 240 243 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 241 244 struct ieee80211_mgmt *mgmt; 242 245 u8 *pos, ie_len; 243 - int hdr_len = offsetofend(struct ieee80211_mgmt, 244 - u.action.u.mesh_action); 245 246 246 247 if (time_before(jiffies, ifmsh->next_perr)) 247 248 return -EAGAIN; ··· 262 265 /* BSSID == SA */ 263 266 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 264 267 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 265 - mgmt->u.action.u.mesh_action.action_code = 266 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 268 + mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 267 269 ie_len = 15; 268 270 pos = skb_put(skb, 2 + ie_len); 269 271 *pos++ = WLAN_EID_PERR; ··· 934 938 struct sta_info *sta; 935 939 936 940 /* need action_code */ 937 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 941 + if (len < IEEE80211_MIN_ACTION_SIZE(mesh_action)) 938 942 return; 939 943 940 944 rcu_read_lock(); ··· 945 949 } 946 950 rcu_read_unlock(); 947 951 948 - baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; 949 - elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 952 + baselen = mgmt->u.action.mesh_action.variable - (u8 *)mgmt; 953 + elems = ieee802_11_parse_elems(mgmt->u.action.mesh_action.variable, 950 954 len - baselen, 951 955 IEEE80211_FTYPE_MGMT | 952 956 IEEE80211_STYPE_ACTION,
+10 -11
net/mac80211/mesh_plink.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2019, 2021-2025 Intel Corporation 4 + * Copyright (C) 2019, 2021-2026 Intel Corporation 5 5 * Author: Luis Carlos Cobo <luisca@cozybit.com> 6 6 */ 7 7 #include <linux/gfp.h> ··· 13 13 #include "rate.h" 14 14 #include "mesh.h" 15 15 16 - #define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2) 16 + #define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.self_prot.variable + 2) 17 17 #define PLINK_GET_LLID(p) (p + 2) 18 18 #define PLINK_GET_PLID(p) (p + 4) 19 19 ··· 215 215 enum ieee80211_self_protected_actioncode action, 216 216 u8 *da, u16 llid, u16 plid, u16 reason) 217 217 { 218 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(self_prot); 218 219 struct ieee80211_local *local = sdata->local; 219 220 struct sk_buff *skb; 220 221 struct ieee80211_tx_info *info; ··· 224 223 u16 peering_proto = 0; 225 224 u8 *pos, ie_len = 4; 226 225 u8 ie_len_he_cap, ie_len_eht_cap; 227 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot); 228 226 int err = -ENOMEM; 229 227 230 228 ie_len_he_cap = ieee80211_ie_len_he_cap(sdata); ··· 260 260 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 261 261 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 262 262 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED; 263 - mgmt->u.action.u.self_prot.action_code = action; 263 + mgmt->u.action.action_code = action; 264 264 265 265 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 266 266 struct ieee80211_supported_band *sband; ··· 1141 1141 return; 1142 1142 } 1143 1143 1144 - ftype = mgmt->u.action.u.self_prot.action_code; 1144 + ftype = mgmt->u.action.action_code; 1145 1145 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 1146 1146 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 1147 1147 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 ··· 1224 1224 size_t baselen; 1225 1225 u8 *baseaddr; 1226 1226 1227 - /* need action_code, aux */ 1228 - if (len < IEEE80211_MIN_ACTION_SIZE + 3) 1227 + /* need aux */ 1228 + if (len < IEEE80211_MIN_ACTION_SIZE(self_prot) + 1) 1229 1229 return; 1230 1230 1231 1231 if (sdata->u.mesh.user_mpm) ··· 1238 1238 return; 1239 1239 } 1240 1240 1241 - baseaddr = mgmt->u.action.u.self_prot.variable; 1242 - baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt; 1243 - if (mgmt->u.action.u.self_prot.action_code == 1244 - WLAN_SP_MESH_PEERING_CONFIRM) { 1241 + baseaddr = mgmt->u.action.self_prot.variable; 1242 + baselen = mgmt->u.action.self_prot.variable - (u8 *)mgmt; 1243 + if (mgmt->u.action.action_code == WLAN_SP_MESH_PEERING_CONFIRM) { 1245 1244 baseaddr += 4; 1246 1245 baselen += 4; 1247 1246
+36 -46
net/mac80211/mlme.c
··· 7957 7957 struct ieee80211_local *local = sdata->local; 7958 7958 struct ieee80211_mgmt *mgmt; 7959 7959 struct sk_buff *skb; 7960 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_req); 7960 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_req); 7961 7961 int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 + 7962 7962 2 * 2 * IEEE80211_TTLM_NUM_TIDS; 7963 7963 ··· 7974 7974 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 7975 7975 7976 7976 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 7977 - mgmt->u.action.u.ttlm_req.action_code = 7978 - WLAN_PROTECTED_EHT_ACTION_TTLM_REQ; 7979 - mgmt->u.action.u.ttlm_req.dialog_token = dialog_token; 7977 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_REQ; 7978 + mgmt->u.action.ttlm_req.dialog_token = dialog_token; 7980 7979 ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm); 7981 7980 ieee80211_tx_skb(sdata, skb); 7982 7981 } ··· 8025 8026 struct ieee80211_local *local = sdata->local; 8026 8027 struct ieee80211_mgmt *mgmt; 8027 8028 struct sk_buff *skb; 8028 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res); 8029 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_res); 8029 8030 int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 + 8030 8031 2 * 2 * IEEE80211_TTLM_NUM_TIDS; 8031 8032 u16 status_code; ··· 8043 8044 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 8044 8045 8045 8046 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 8046 - mgmt->u.action.u.ttlm_res.action_code = 8047 - WLAN_PROTECTED_EHT_ACTION_TTLM_RES; 8048 - mgmt->u.action.u.ttlm_res.dialog_token = dialog_token; 8047 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_RES; 8048 + mgmt->u.action.ttlm_res.dialog_token = dialog_token; 8049 8049 switch (ttlm_res) { 8050 8050 default: 8051 8051 WARN_ON(1); ··· 8061 8063 break; 8062 8064 } 8063 8065 8064 - mgmt->u.action.u.ttlm_res.status_code = cpu_to_le16(status_code); 8066 + mgmt->u.action.ttlm_res.status_code = cpu_to_le16(status_code); 8065 8067 ieee80211_tx_skb(sdata, skb); 8066 8068 } 8067 8069 ··· 8161 8163 if (!ieee80211_vif_is_mld(&sdata->vif)) 8162 8164 return; 8163 8165 8164 - dialog_token = mgmt->u.action.u.ttlm_req.dialog_token; 8165 - ies_len = len - offsetof(struct ieee80211_mgmt, 8166 - u.action.u.ttlm_req.variable); 8167 - elems = ieee802_11_parse_elems(mgmt->u.action.u.ttlm_req.variable, 8166 + dialog_token = mgmt->u.action.ttlm_req.dialog_token; 8167 + ies_len = len - IEEE80211_MIN_ACTION_SIZE(ttlm_req); 8168 + elems = ieee802_11_parse_elems(mgmt->u.action.ttlm_req.variable, 8168 8169 ies_len, 8169 8170 IEEE80211_FTYPE_MGMT | 8170 8171 IEEE80211_STYPE_ACTION, ··· 8214 8217 struct ieee80211_mgmt *mgmt, size_t len) 8215 8218 { 8216 8219 if (!ieee80211_vif_is_mld(&sdata->vif) || 8217 - mgmt->u.action.u.ttlm_req.dialog_token != 8218 - sdata->u.mgd.dialog_token_alloc) 8220 + mgmt->u.action.ttlm_res.dialog_token != sdata->u.mgd.dialog_token_alloc) 8219 8221 return; 8220 8222 8221 8223 wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ··· 8228 8232 * This can be better implemented in the future, to handle request 8229 8233 * rejections. 8230 8234 */ 8231 - if (le16_to_cpu(mgmt->u.action.u.ttlm_res.status_code) != WLAN_STATUS_SUCCESS) 8235 + if (le16_to_cpu(mgmt->u.action.ttlm_res.status_code) != WLAN_STATUS_SUCCESS) 8232 8236 __ieee80211_disconnect(sdata); 8233 8237 } 8234 8238 ··· 8261 8265 8262 8266 void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif) 8263 8267 { 8268 + int frame_len = IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down); 8264 8269 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 8265 8270 struct ieee80211_local *local = sdata->local; 8266 8271 struct ieee80211_mgmt *mgmt; 8267 8272 struct sk_buff *skb; 8268 - int frame_len = offsetofend(struct ieee80211_mgmt, 8269 - u.action.u.ttlm_tear_down); 8270 8273 struct ieee80211_tx_info *info; 8271 8274 8272 8275 skb = dev_alloc_skb(local->hw.extra_tx_headroom + frame_len); ··· 8281 8286 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 8282 8287 8283 8288 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 8284 - mgmt->u.action.u.ttlm_tear_down.action_code = 8285 - WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN; 8289 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN; 8286 8290 8287 8291 info = IEEE80211_SKB_CB(skb); 8288 8292 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; ··· 8364 8370 case WLAN_CATEGORY_SPECTRUM_MGMT: 8365 8371 ies_len = skb->len - 8366 8372 offsetof(struct ieee80211_mgmt, 8367 - u.action.u.chan_switch.variable); 8373 + u.action.chan_switch.variable); 8368 8374 8369 8375 if (ies_len < 0) 8370 8376 break; 8371 8377 8372 8378 /* CSA IE cannot be overridden, no need for BSSID */ 8373 - elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable, 8379 + elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable, 8374 8380 ies_len, 8375 8381 IEEE80211_FTYPE_MGMT | 8376 8382 IEEE80211_STYPE_ACTION, ··· 8392 8398 case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION: 8393 8399 ies_len = skb->len - 8394 8400 offsetof(struct ieee80211_mgmt, 8395 - u.action.u.ext_chan_switch.variable); 8401 + u.action.ext_chan_switch.variable); 8396 8402 8397 8403 if (ies_len < 0) 8398 8404 break; ··· 8401 8407 * extended CSA IE can't be overridden, no need for 8402 8408 * BSSID 8403 8409 */ 8404 - elems = ieee802_11_parse_elems(mgmt->u.action.u.ext_chan_switch.variable, 8410 + elems = ieee802_11_parse_elems(mgmt->u.action.ext_chan_switch.variable, 8405 8411 ies_len, 8406 8412 IEEE80211_FTYPE_MGMT | 8407 8413 IEEE80211_STYPE_ACTION, ··· 8418 8424 8419 8425 /* for the handling code pretend it was an IE */ 8420 8426 elems->ext_chansw_ie = 8421 - &mgmt->u.action.u.ext_chan_switch.data; 8427 + &mgmt->u.action.ext_chan_switch.data; 8422 8428 8423 8429 ieee80211_sta_process_chanswitch(link, 8424 8430 rx_status->mactime, ··· 10420 10426 u8 *pos; 10421 10427 10422 10428 if (!ieee80211_vif_is_mld(&sdata->vif) || 10423 - len < offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp) || 10424 - mgmt->u.action.u.ml_reconf_resp.dialog_token != 10425 - sdata->u.mgd.reconf.dialog_token || 10429 + len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) || 10430 + mgmt->u.action.ml_reconf_resp.dialog_token != 10431 + sdata->u.mgd.reconf.dialog_token || 10426 10432 !sta_changed_links) 10427 10433 return; 10428 10434 10429 - pos = mgmt->u.action.u.ml_reconf_resp.variable; 10430 - len -= offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp); 10435 + pos = mgmt->u.action.ml_reconf_resp.variable; 10436 + len -= offsetofend(typeof(*mgmt), u.action.ml_reconf_resp); 10431 10437 10432 10438 /* each status duple is 3 octets */ 10433 - if (len < mgmt->u.action.u.ml_reconf_resp.count * 3) { 10439 + if (len < mgmt->u.action.ml_reconf_resp.count * 3) { 10434 10440 sdata_info(sdata, 10435 10441 "mlo: reconf: unexpected len=%zu, count=%u\n", 10436 - len, mgmt->u.action.u.ml_reconf_resp.count); 10442 + len, mgmt->u.action.ml_reconf_resp.count); 10437 10443 goto disconnect; 10438 10444 } 10439 10445 10440 10446 link_mask = sta_changed_links; 10441 - for (i = 0; i < mgmt->u.action.u.ml_reconf_resp.count; i++) { 10447 + for (i = 0; i < mgmt->u.action.ml_reconf_resp.count; i++) { 10442 10448 u16 status = get_unaligned_le16(pos + 1); 10443 10449 10444 10450 link_id = *pos; ··· 10723 10729 return NULL; 10724 10730 10725 10731 skb_reserve(skb, local->hw.extra_tx_headroom); 10726 - mgmt = skb_put_zero(skb, offsetofend(struct ieee80211_mgmt, 10727 - u.action.u.ml_reconf_req)); 10732 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ml_reconf_req)); 10728 10733 10729 10734 /* Add the MAC header */ 10730 10735 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | ··· 10734 10741 10735 10742 /* Add the action frame fixed fields */ 10736 10743 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 10737 - mgmt->u.action.u.ml_reconf_req.action_code = 10738 - WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ; 10744 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ; 10739 10745 10740 10746 /* allocate a dialog token and store it */ 10741 10747 sdata->u.mgd.reconf.dialog_token = ++sdata->u.mgd.dialog_token_alloc; 10742 - mgmt->u.action.u.ml_reconf_req.dialog_token = 10748 + mgmt->u.action.ml_reconf_req.dialog_token = 10743 10749 sdata->u.mgd.reconf.dialog_token; 10744 10750 10745 10751 /* Add the ML reconfiguration element and the common information */ ··· 11108 11116 11109 11117 int ieee80211_mgd_set_epcs(struct ieee80211_sub_if_data *sdata, bool enable) 11110 11118 { 11119 + int frame_len = IEEE80211_MIN_ACTION_SIZE(epcs) + (enable ? 1 : 0); 11111 11120 struct ieee80211_local *local = sdata->local; 11112 11121 struct ieee80211_mgmt *mgmt; 11113 11122 struct sk_buff *skb; 11114 - int frame_len = offsetofend(struct ieee80211_mgmt, 11115 - u.action.u.epcs) + (enable ? 1 : 0); 11116 11123 11117 11124 if (!ieee80211_mgd_epcs_supp(sdata)) 11118 11125 return -EINVAL; ··· 11140 11149 11141 11150 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 11142 11151 if (enable) { 11143 - u8 *pos = mgmt->u.action.u.epcs.variable; 11152 + u8 *pos = mgmt->u.action.epcs.variable; 11144 11153 11145 - mgmt->u.action.u.epcs.action_code = 11154 + mgmt->u.action.action_code = 11146 11155 WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_REQ; 11147 11156 11148 11157 *pos = ++sdata->u.mgd.dialog_token_alloc; 11149 11158 sdata->u.mgd.epcs.dialog_token = *pos; 11150 11159 } else { 11151 - mgmt->u.action.u.epcs.action_code = 11160 + mgmt->u.action.action_code = 11152 11161 WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN; 11153 11162 11154 11163 ieee80211_epcs_teardown(sdata); ··· 11237 11246 return; 11238 11247 11239 11248 /* Handle dialog token and status code */ 11240 - pos = mgmt->u.action.u.epcs.variable; 11249 + pos = mgmt->u.action.epcs.variable; 11241 11250 dialog_token = *pos; 11242 11251 status_code = get_unaligned_le16(pos + 1); 11243 11252 ··· 11259 11268 return; 11260 11269 11261 11270 pos += IEEE80211_EPCS_ENA_RESP_BODY_LEN; 11262 - ies_len = len - offsetof(struct ieee80211_mgmt, 11263 - u.action.u.epcs.variable) - 11271 + ies_len = len - IEEE80211_MIN_ACTION_SIZE(epcs) - 11264 11272 IEEE80211_EPCS_ENA_RESP_BODY_LEN; 11265 11273 11266 11274 elems = ieee802_11_parse_elems(pos, ies_len,
+51 -72
net/mac80211/rx.c
··· 274 274 if (!sdata) 275 275 return; 276 276 277 - BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE + 1); 277 + BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE(action_code)); 278 278 279 279 if (skb->len < rtap_space + sizeof(action) + 280 280 VHT_MUMIMO_GROUPS_DATA_LEN) ··· 1162 1162 u8 category; 1163 1163 1164 1164 /* make sure category field is present */ 1165 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) 1165 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 1166 1166 return RX_DROP_U_RUNT_ACTION; 1167 1167 1168 1168 mgmt = (struct ieee80211_mgmt *)hdr; ··· 3422 3422 return; 3423 3423 } 3424 3424 3425 - if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) { 3425 + if (len < IEEE80211_MIN_ACTION_SIZE(sa_query)) { 3426 3426 /* Too short SA Query request frame */ 3427 3427 return; 3428 3428 } ··· 3432 3432 return; 3433 3433 3434 3434 skb_reserve(skb, local->hw.extra_tx_headroom); 3435 - resp = skb_put_zero(skb, 24); 3435 + resp = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(sa_query)); 3436 3436 memcpy(resp->da, sdata->vif.cfg.ap_addr, ETH_ALEN); 3437 3437 memcpy(resp->sa, sdata->vif.addr, ETH_ALEN); 3438 3438 memcpy(resp->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 3439 3439 resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 3440 3440 IEEE80211_STYPE_ACTION); 3441 - skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query)); 3442 3441 resp->u.action.category = WLAN_CATEGORY_SA_QUERY; 3443 - resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE; 3444 - memcpy(resp->u.action.u.sa_query.trans_id, 3445 - mgmt->u.action.u.sa_query.trans_id, 3442 + resp->u.action.action_code = WLAN_ACTION_SA_QUERY_RESPONSE; 3443 + memcpy(resp->u.action.sa_query.trans_id, 3444 + mgmt->u.action.sa_query.trans_id, 3446 3445 WLAN_SA_QUERY_TR_ID_LEN); 3447 3446 3448 3447 ieee80211_tx_skb(sdata, skb); ··· 3515 3516 3516 3517 /* drop too small action frames */ 3517 3518 if (ieee80211_is_action(mgmt->frame_control) && 3518 - rx->skb->len < IEEE80211_MIN_ACTION_SIZE) 3519 + rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 3519 3520 return RX_DROP_U_RUNT_ACTION; 3520 3521 3521 3522 /* Drop non-broadcast Beacon frames */ ··· 3564 3565 if (!rx->sta) 3565 3566 return false; 3566 3567 3567 - switch (mgmt->u.action.u.s1g.action_code) { 3568 + switch (mgmt->u.action.action_code) { 3568 3569 case WLAN_S1G_TWT_SETUP: { 3569 3570 struct ieee80211_twt_setup *twt; 3570 3571 3571 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 3572 - 1 + /* action code */ 3572 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 3573 3573 sizeof(struct ieee80211_twt_setup) + 3574 3574 2 /* TWT req_type agrt */) 3575 3575 break; 3576 3576 3577 - twt = (void *)mgmt->u.action.u.s1g.variable; 3577 + twt = (void *)mgmt->u.action.s1g.variable; 3578 3578 if (twt->element_id != WLAN_EID_S1G_TWT) 3579 3579 break; 3580 3580 3581 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 3582 - 4 + /* action code + token + tlv */ 3581 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 3582 + 3 + /* token + tlv */ 3583 3583 twt->length) 3584 3584 break; 3585 3585 3586 3586 return true; /* queue the frame */ 3587 3587 } 3588 3588 case WLAN_S1G_TWT_TEARDOWN: 3589 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2) 3589 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 1) 3590 3590 break; 3591 3591 3592 3592 return true; /* queue the frame */ ··· 3630 3632 break; 3631 3633 3632 3634 /* verify action & smps_control/chanwidth are present */ 3633 - if (len < IEEE80211_MIN_ACTION_SIZE + 2) 3635 + if (len < IEEE80211_MIN_ACTION_SIZE(ht_smps)) 3634 3636 goto invalid; 3635 3637 3636 - switch (mgmt->u.action.u.ht_smps.action) { 3638 + switch (mgmt->u.action.action_code) { 3637 3639 case WLAN_HT_ACTION_SMPS: { 3638 3640 struct ieee80211_supported_band *sband; 3639 3641 enum ieee80211_smps_mode smps_mode; ··· 3644 3646 goto handled; 3645 3647 3646 3648 /* convert to HT capability */ 3647 - switch (mgmt->u.action.u.ht_smps.smps_control) { 3649 + switch (mgmt->u.action.ht_smps.smps_control) { 3648 3650 case WLAN_HT_SMPS_CONTROL_DISABLED: 3649 3651 smps_mode = IEEE80211_SMPS_OFF; 3650 3652 break; ··· 3677 3679 goto handled; 3678 3680 } 3679 3681 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 3680 - u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 3682 + u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth; 3681 3683 3682 3684 if (chanwidth != IEEE80211_HT_CHANWIDTH_20MHZ && 3683 3685 chanwidth != IEEE80211_HT_CHANWIDTH_ANY) ··· 3697 3699 break; 3698 3700 case WLAN_CATEGORY_PUBLIC: 3699 3701 case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION: 3700 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3702 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3701 3703 goto invalid; 3702 3704 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3703 3705 break; ··· 3705 3707 break; 3706 3708 if (!ether_addr_equal(mgmt->bssid, sdata->deflink.u.mgd.bssid)) 3707 3709 break; 3708 - if (mgmt->u.action.u.ext_chan_switch.action_code != 3710 + if (mgmt->u.action.action_code != 3709 3711 WLAN_PUB_ACTION_EXT_CHANSW_ANN) 3710 3712 break; 3711 - if (len < offsetof(struct ieee80211_mgmt, 3712 - u.action.u.ext_chan_switch.variable)) 3713 + if (len < IEEE80211_MIN_ACTION_SIZE(ext_chan_switch)) 3713 3714 goto invalid; 3714 3715 goto queue; 3715 3716 case WLAN_CATEGORY_VHT: ··· 3720 3723 break; 3721 3724 3722 3725 /* verify action code is present */ 3723 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3726 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3724 3727 goto invalid; 3725 3728 3726 - switch (mgmt->u.action.u.vht_opmode_notif.action_code) { 3729 + switch (mgmt->u.action.action_code) { 3727 3730 case WLAN_VHT_ACTION_OPMODE_NOTIF: { 3728 3731 /* verify opmode is present */ 3729 - if (len < IEEE80211_MIN_ACTION_SIZE + 2) 3732 + if (len < IEEE80211_MIN_ACTION_SIZE(vht_opmode_notif)) 3730 3733 goto invalid; 3731 3734 goto queue; 3732 3735 } 3733 3736 case WLAN_VHT_ACTION_GROUPID_MGMT: { 3734 - if (len < IEEE80211_MIN_ACTION_SIZE + 25) 3737 + if (len < IEEE80211_MIN_ACTION_SIZE(vht_group_notif)) 3735 3738 goto invalid; 3736 3739 goto queue; 3737 3740 } ··· 3748 3751 break; 3749 3752 3750 3753 /* verify action_code is present */ 3751 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3754 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3752 3755 break; 3753 3756 3754 - switch (mgmt->u.action.u.addba_req.action_code) { 3757 + switch (mgmt->u.action.action_code) { 3755 3758 case WLAN_ACTION_ADDBA_REQ: 3756 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3757 - sizeof(mgmt->u.action.u.addba_req))) 3759 + if (len < IEEE80211_MIN_ACTION_SIZE(addba_req)) 3758 3760 goto invalid; 3759 3761 break; 3760 3762 case WLAN_ACTION_ADDBA_RESP: 3761 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3762 - sizeof(mgmt->u.action.u.addba_resp))) 3763 + if (len < IEEE80211_MIN_ACTION_SIZE(addba_resp)) 3763 3764 goto invalid; 3764 3765 break; 3765 3766 case WLAN_ACTION_DELBA: 3766 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3767 - sizeof(mgmt->u.action.u.delba))) 3767 + if (len < IEEE80211_MIN_ACTION_SIZE(delba)) 3768 3768 goto invalid; 3769 3769 break; 3770 3770 default: ··· 3771 3777 goto queue; 3772 3778 case WLAN_CATEGORY_SPECTRUM_MGMT: 3773 3779 /* verify action_code is present */ 3774 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3780 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3775 3781 break; 3776 3782 3777 - switch (mgmt->u.action.u.measurement.action_code) { 3783 + switch (mgmt->u.action.action_code) { 3778 3784 case WLAN_ACTION_SPCT_MSR_REQ: 3779 3785 if (status->band != NL80211_BAND_5GHZ) 3780 3786 break; 3781 3787 3782 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3783 - sizeof(mgmt->u.action.u.measurement))) 3788 + if (len < IEEE80211_MIN_ACTION_SIZE(measurement)) 3784 3789 break; 3785 3790 3786 3791 if (sdata->vif.type != NL80211_IFTYPE_STATION) ··· 3789 3796 goto handled; 3790 3797 case WLAN_ACTION_SPCT_CHL_SWITCH: { 3791 3798 u8 *bssid; 3792 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3793 - sizeof(mgmt->u.action.u.chan_switch))) 3799 + if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch)) 3794 3800 break; 3795 3801 3796 3802 if (sdata->vif.type != NL80211_IFTYPE_STATION && ··· 3814 3822 } 3815 3823 break; 3816 3824 case WLAN_CATEGORY_SELF_PROTECTED: 3817 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3818 - sizeof(mgmt->u.action.u.self_prot.action_code))) 3825 + if (len < IEEE80211_MIN_ACTION_SIZE(self_prot)) 3819 3826 break; 3820 3827 3821 - switch (mgmt->u.action.u.self_prot.action_code) { 3828 + switch (mgmt->u.action.action_code) { 3822 3829 case WLAN_SP_MESH_PEERING_OPEN: 3823 3830 case WLAN_SP_MESH_PEERING_CLOSE: 3824 3831 case WLAN_SP_MESH_PEERING_CONFIRM: ··· 3835 3844 } 3836 3845 break; 3837 3846 case WLAN_CATEGORY_MESH_ACTION: 3838 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3839 - sizeof(mgmt->u.action.u.mesh_action.action_code))) 3847 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3840 3848 break; 3841 3849 3842 3850 if (!ieee80211_vif_is_mesh(&sdata->vif)) ··· 3845 3855 break; 3846 3856 goto queue; 3847 3857 case WLAN_CATEGORY_S1G: 3848 - if (len < offsetofend(typeof(*mgmt), 3849 - u.action.u.s1g.action_code)) 3858 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3850 3859 break; 3851 3860 3852 - switch (mgmt->u.action.u.s1g.action_code) { 3861 + switch (mgmt->u.action.action_code) { 3853 3862 case WLAN_S1G_TWT_SETUP: 3854 3863 case WLAN_S1G_TWT_TEARDOWN: 3855 3864 if (ieee80211_process_rx_twt_action(rx)) ··· 3859 3870 } 3860 3871 break; 3861 3872 case WLAN_CATEGORY_PROTECTED_EHT: 3862 - if (len < offsetofend(typeof(*mgmt), 3863 - u.action.u.ttlm_req.action_code)) 3873 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3864 3874 break; 3865 3875 3866 - switch (mgmt->u.action.u.ttlm_req.action_code) { 3876 + switch (mgmt->u.action.action_code) { 3867 3877 case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ: 3868 3878 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3869 3879 break; 3870 3880 3871 - if (len < offsetofend(typeof(*mgmt), 3872 - u.action.u.ttlm_req)) 3881 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_req)) 3873 3882 goto invalid; 3874 3883 goto queue; 3875 3884 case WLAN_PROTECTED_EHT_ACTION_TTLM_RES: 3876 3885 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3877 3886 break; 3878 3887 3879 - if (len < offsetofend(typeof(*mgmt), 3880 - u.action.u.ttlm_res)) 3888 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_res)) 3881 3889 goto invalid; 3882 3890 goto queue; 3883 3891 case WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN: 3884 3892 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3885 3893 break; 3886 3894 3887 - if (len < offsetofend(typeof(*mgmt), 3888 - u.action.u.ttlm_tear_down)) 3895 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down)) 3889 3896 goto invalid; 3890 3897 goto queue; 3891 3898 case WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_RESP: ··· 3891 3906 /* The reconfiguration response action frame must 3892 3907 * least one 'Status Duple' entry (3 octets) 3893 3908 */ 3894 - if (len < 3895 - offsetofend(typeof(*mgmt), 3896 - u.action.u.ml_reconf_resp) + 3) 3909 + if (len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) + 3) 3897 3910 goto invalid; 3898 3911 goto queue; 3899 3912 case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_RESP: 3900 3913 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3901 3914 break; 3902 3915 3903 - if (len < offsetofend(typeof(*mgmt), 3904 - u.action.u.epcs) + 3905 - IEEE80211_EPCS_ENA_RESP_BODY_LEN) 3916 + if (len < IEEE80211_MIN_ACTION_SIZE(epcs) + 3917 + IEEE80211_EPCS_ENA_RESP_BODY_LEN) 3906 3918 goto invalid; 3907 3919 goto queue; 3908 3920 case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN: 3909 3921 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3910 3922 break; 3911 3923 3912 - if (len < offsetofend(typeof(*mgmt), 3913 - u.action.u.epcs)) 3924 + if (len < IEEE80211_MIN_ACTION_SIZE(epcs)) 3914 3925 goto invalid; 3915 3926 goto queue; 3916 3927 case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 3917 3928 if (sdata->vif.type != NL80211_IFTYPE_AP) 3918 3929 break; 3919 3930 3920 - if (len < offsetofend(typeof(*mgmt), 3921 - u.action.u.eml_omn)) 3931 + if (len < IEEE80211_MIN_ACTION_SIZE(eml_omn)) 3922 3932 goto invalid; 3923 3933 goto queue; 3924 3934 default: ··· 3995 4015 3996 4016 switch (mgmt->u.action.category) { 3997 4017 case WLAN_CATEGORY_SA_QUERY: 3998 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3999 - sizeof(mgmt->u.action.u.sa_query))) 4018 + if (len < IEEE80211_MIN_ACTION_SIZE(sa_query)) 4000 4019 break; 4001 4020 4002 - switch (mgmt->u.action.u.sa_query.action) { 4021 + switch (mgmt->u.action.action_code) { 4003 4022 case WLAN_ACTION_SA_QUERY_REQUEST: 4004 4023 if (sdata->vif.type != NL80211_IFTYPE_STATION) 4005 4024 break;
+14 -14
net/mac80211/s1g.c
··· 2 2 /* 3 3 * S1G handling 4 4 * Copyright(c) 2020 Adapt-IP 5 - * Copyright (C) 2023 Intel Corporation 5 + * Copyright (C) 2023, 2026 Intel Corporation 6 6 */ 7 7 #include <linux/ieee80211.h> 8 8 #include <net/mac80211.h> ··· 27 27 if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G)) 28 28 return false; 29 29 30 - return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP; 30 + return mgmt->u.action.action_code == WLAN_S1G_TWT_SETUP; 31 31 } 32 32 33 33 static void 34 34 ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da, 35 35 const u8 *bssid, struct ieee80211_twt_setup *twt) 36 36 { 37 - int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length; 37 + int len = IEEE80211_MIN_ACTION_SIZE(s1g) + 3 + twt->length; 38 38 struct ieee80211_local *local = sdata->local; 39 39 struct ieee80211_mgmt *mgmt; 40 40 struct sk_buff *skb; ··· 52 52 memcpy(mgmt->bssid, bssid, ETH_ALEN); 53 53 54 54 mgmt->u.action.category = WLAN_CATEGORY_S1G; 55 - mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP; 56 - memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length); 55 + mgmt->u.action.action_code = WLAN_S1G_TWT_SETUP; 56 + memcpy(mgmt->u.action.s1g.variable, twt, 3 + twt->length); 57 57 58 58 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | 59 59 IEEE80211_TX_INTFL_MLME_CONN_TX | ··· 71 71 u8 *id; 72 72 73 73 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 74 - IEEE80211_MIN_ACTION_SIZE + 2); 74 + IEEE80211_MIN_ACTION_SIZE(s1g) + 1); 75 75 if (!skb) 76 76 return; 77 77 78 78 skb_reserve(skb, local->hw.extra_tx_headroom); 79 - mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2); 79 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(s1g) + 1); 80 80 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 81 81 IEEE80211_STYPE_ACTION); 82 82 memcpy(mgmt->da, da, ETH_ALEN); ··· 84 84 memcpy(mgmt->bssid, bssid, ETH_ALEN); 85 85 86 86 mgmt->u.action.category = WLAN_CATEGORY_S1G; 87 - mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN; 88 - id = (u8 *)mgmt->u.action.u.s1g.variable; 87 + mgmt->u.action.action_code = WLAN_S1G_TWT_TEARDOWN; 88 + id = (u8 *)mgmt->u.action.s1g.variable; 89 89 *id = flowid; 90 90 91 91 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | ··· 98 98 struct sta_info *sta, struct sk_buff *skb) 99 99 { 100 100 struct ieee80211_mgmt *mgmt = (void *)skb->data; 101 - struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable; 101 + struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable; 102 102 struct ieee80211_twt_params *twt_agrt = (void *)twt->params; 103 103 104 104 twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST); ··· 128 128 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 129 129 130 130 drv_twt_teardown_request(sdata->local, sdata, &sta->sta, 131 - mgmt->u.action.u.s1g.variable[0]); 131 + mgmt->u.action.s1g.variable[0]); 132 132 } 133 133 134 134 static void ··· 136 136 struct sta_info *sta, struct sk_buff *skb) 137 137 { 138 138 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 139 - struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable; 139 + struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable; 140 140 struct ieee80211_twt_params *twt_agrt = (void *)twt->params; 141 141 u8 flowid = le16_get_bits(twt_agrt->req_type, 142 142 IEEE80211_TWT_REQTYPE_FLOWID); ··· 160 160 if (!sta) 161 161 return; 162 162 163 - switch (mgmt->u.action.u.s1g.action_code) { 163 + switch (mgmt->u.action.action_code) { 164 164 case WLAN_S1G_TWT_SETUP: 165 165 ieee80211_s1g_rx_twt_setup(sdata, sta, skb); 166 166 break; ··· 185 185 if (!sta) 186 186 return; 187 187 188 - switch (mgmt->u.action.u.s1g.action_code) { 188 + switch (mgmt->u.action.action_code) { 189 189 case WLAN_S1G_TWT_SETUP: 190 190 /* process failed twt setup frames */ 191 191 ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
+13 -18
net/mac80211/spectmgmt.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2008, Intel Corporation 11 11 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 12 - * Copyright (C) 2018, 2020, 2022-2024 Intel Corporation 12 + * Copyright (C) 2018, 2020, 2022-2024, 2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 409 409 struct sk_buff *skb; 410 410 struct ieee80211_mgmt *msr_report; 411 411 412 - skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + 413 - sizeof(struct ieee80211_msrment_ie)); 412 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(measurement) + 413 + local->hw.extra_tx_headroom); 414 414 if (!skb) 415 415 return; 416 416 417 417 skb_reserve(skb, local->hw.extra_tx_headroom); 418 - msr_report = skb_put_zero(skb, 24); 418 + msr_report = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(measurement)); 419 419 memcpy(msr_report->da, da, ETH_ALEN); 420 420 memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN); 421 421 memcpy(msr_report->bssid, bssid, ETH_ALEN); 422 422 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 423 423 IEEE80211_STYPE_ACTION); 424 424 425 - skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); 426 425 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; 427 - msr_report->u.action.u.measurement.action_code = 428 - WLAN_ACTION_SPCT_MSR_RPRT; 429 - msr_report->u.action.u.measurement.dialog_token = dialog_token; 426 + msr_report->u.action.action_code = WLAN_ACTION_SPCT_MSR_RPRT; 430 427 431 - msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; 432 - msr_report->u.action.u.measurement.length = 428 + msr_report->u.action.measurement.dialog_token = dialog_token; 429 + msr_report->u.action.measurement.element_id = WLAN_EID_MEASURE_REPORT; 430 + msr_report->u.action.measurement.length = 433 431 sizeof(struct ieee80211_msrment_ie); 434 - 435 - memset(&msr_report->u.action.u.measurement.msr_elem, 0, 436 - sizeof(struct ieee80211_msrment_ie)); 437 - msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; 438 - msr_report->u.action.u.measurement.msr_elem.mode |= 432 + msr_report->u.action.measurement.msr_elem.token = request_ie->token; 433 + msr_report->u.action.measurement.msr_elem.mode |= 439 434 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; 440 - msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; 435 + msr_report->u.action.measurement.msr_elem.type = request_ie->type; 441 436 442 437 ieee80211_tx_skb(sdata, skb); 443 438 } ··· 449 454 * TODO: Answer basic measurement as unmeasured 450 455 */ 451 456 ieee80211_send_refuse_measurement_request(sdata, 452 - &mgmt->u.action.u.measurement.msr_elem, 457 + &mgmt->u.action.measurement.msr_elem, 453 458 mgmt->sa, mgmt->bssid, 454 - mgmt->u.action.u.measurement.dialog_token); 459 + mgmt->u.action.measurement.dialog_token); 455 460 }
+12 -17
net/mac80211/tdls.c
··· 6 6 * Copyright 2014, Intel Corporation 7 7 * Copyright 2014 Intel Mobile Communications GmbH 8 8 * Copyright 2015 - 2016 Intel Deutschland GmbH 9 - * Copyright (C) 2019, 2021-2025 Intel Corporation 9 + * Copyright (C) 2019, 2021-2026 Intel Corporation 10 10 */ 11 11 12 12 #include <linux/ieee80211.h> ··· 879 879 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 880 880 struct ieee80211_mgmt *mgmt; 881 881 882 - mgmt = skb_put_zero(skb, 24); 882 + if (action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES) 883 + return -EINVAL; 884 + 885 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp)); 883 886 memcpy(mgmt->da, peer, ETH_ALEN); 884 887 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 885 888 memcpy(mgmt->bssid, link->u.mgd.bssid, ETH_ALEN); 886 889 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 887 890 IEEE80211_STYPE_ACTION); 888 891 889 - switch (action_code) { 890 - case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 891 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); 892 - mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 893 - mgmt->u.action.u.tdls_discover_resp.action_code = 894 - WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 895 - mgmt->u.action.u.tdls_discover_resp.dialog_token = 896 - dialog_token; 897 - mgmt->u.action.u.tdls_discover_resp.capability = 898 - cpu_to_le16(ieee80211_get_tdls_sta_capab(link, 899 - status_code)); 900 - break; 901 - default: 902 - return -EINVAL; 903 - } 892 + mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 893 + mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 894 + 895 + mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token; 896 + mgmt->u.action.tdls_discover_resp.capability = 897 + cpu_to_le16(ieee80211_get_tdls_sta_capab(link, 898 + status_code)); 904 899 905 900 return 0; 906 901 }
+2 -3
net/mac80211/util.c
··· 3766 3766 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, 3767 3767 struct cfg80211_csa_settings *csa_settings) 3768 3768 { 3769 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(chan_switch); 3769 3770 struct sk_buff *skb; 3770 3771 struct ieee80211_mgmt *mgmt; 3771 3772 struct ieee80211_local *local = sdata->local; 3772 3773 int freq; 3773 - int hdr_len = offsetofend(struct ieee80211_mgmt, 3774 - u.action.u.chan_switch); 3775 3774 u8 *pos; 3776 3775 3777 3776 if (sdata->vif.type != NL80211_IFTYPE_ADHOC && ··· 3799 3800 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 3800 3801 } 3801 3802 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; 3802 - mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; 3803 + mgmt->u.action.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; 3803 3804 pos = skb_put(skb, 5); 3804 3805 *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ 3805 3806 *pos++ = 3; /* IE length */
+5 -5
net/mac80211/vht.c
··· 4 4 * 5 5 * Portions of this file 6 6 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 7 - * Copyright (C) 2018 - 2024 Intel Corporation 7 + * Copyright (C) 2018-2026 Intel Corporation 8 8 */ 9 9 10 10 #include <linux/ieee80211.h> ··· 723 723 if (!link_conf->mu_mimo_owner) 724 724 return; 725 725 726 - if (!memcmp(mgmt->u.action.u.vht_group_notif.position, 726 + if (!memcmp(mgmt->u.action.vht_group_notif.position, 727 727 link_conf->mu_group.position, WLAN_USER_POSITION_LEN) && 728 - !memcmp(mgmt->u.action.u.vht_group_notif.membership, 728 + !memcmp(mgmt->u.action.vht_group_notif.membership, 729 729 link_conf->mu_group.membership, WLAN_MEMBERSHIP_LEN)) 730 730 return; 731 731 732 732 memcpy(link_conf->mu_group.membership, 733 - mgmt->u.action.u.vht_group_notif.membership, 733 + mgmt->u.action.vht_group_notif.membership, 734 734 WLAN_MEMBERSHIP_LEN); 735 735 memcpy(link_conf->mu_group.position, 736 - mgmt->u.action.u.vht_group_notif.position, 736 + mgmt->u.action.vht_group_notif.position, 737 737 WLAN_USER_POSITION_LEN); 738 738 739 739 ieee80211_link_info_change_notify(sdata, link,