summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMasashi Honma <masashi.honma@gmail.com>2026-05-30 08:09:48 +0900
committerJohannes Berg <johannes.berg@intel.com>2026-06-03 14:07:07 +0200
commit4ec9ea8a58859c260ae32e097aa643975572e58b (patch)
tree10205373ac9cf2a93a578b3447bc0de644e38ad8 /include/linux
parentd158e54476ea9667c33dfa2c8d87c7cc32b40f1b (diff)
wifi: mac80211: Fix PERR frame processing
There are no issues with the PERR processing itself; however, to maintain consistency with the previous PREQ/PREP code modifications, I will create a new mesh_path_parse_error_frame() function to separately implement the frame format validation and the "not supported" check. Signed-off-by: Masashi Honma <masashi.honma@gmail.com> Link: https://patch.msgid.link/20260529230952.124754-6-masashi.honma@gmail.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ieee80211-mesh.h36
1 files changed, 36 insertions, 0 deletions
diff --git a/include/linux/ieee80211-mesh.h b/include/linux/ieee80211-mesh.h
index 482ac0c6d759..7eb15834531c 100644
--- a/include/linux/ieee80211-mesh.h
+++ b/include/linux/ieee80211-mesh.h
@@ -403,4 +403,40 @@ static inline bool ieee80211_mesh_prep_size_ok(const u8 *pos, u8 elen)
return elen == needed;
}
+/* IEEE Std 802.11-2016 9.4.2.115 PERR element */
+static inline bool ieee80211_mesh_perr_size_ok(const u8 *pos, u8 elen)
+{
+ struct ieee80211_mesh_hwmp_perr *perr_elem = (void *)pos;
+ const u8 *start = pos;
+ u8 number_of_dst;
+ int needed;
+ int i;
+
+ needed = sizeof(struct ieee80211_mesh_hwmp_perr);
+
+ /* Check if the element contains number of dst */
+ if (elen < needed)
+ return false;
+
+ pos += sizeof(struct ieee80211_mesh_hwmp_perr);
+ number_of_dst = perr_elem->number_of_dst;
+
+ for (i = 0; i < number_of_dst; i++) {
+ struct ieee80211_mesh_hwmp_perr_dst *dst = (void *)pos;
+ u8 dst_len = sizeof(struct ieee80211_mesh_hwmp_perr_dst);
+
+ /* Check if the element contains flags */
+ if (elen < pos - start + dst_len)
+ return false;
+
+ dst_len += ((dst->flags & AE_F) ? ETH_ALEN : 0)
+ /* Destination External Address */ +
+ 2 /* Reason Code */;
+ needed += dst_len;
+ pos += dst_len;
+ }
+
+ return elen == needed;
+}
+
#endif /* LINUX_IEEE80211_MESH_H */