Linux wireless drivers development
 help / color / mirror / Atom feed
From: Masashi Honma <masashi.honma@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: johannes@sipsolutions.net, Masashi Honma <masashi.honma@gmail.com>
Subject: [PATCH v9 3/9] wifi: mac80211: Use struct instead of macro for PERR frame
Date: Sat, 30 May 2026 08:09:45 +0900	[thread overview]
Message-ID: <20260529230952.124754-3-masashi.honma@gmail.com> (raw)
In-Reply-To: <20260529230952.124754-1-masashi.honma@gmail.com>

The existing PERR_IE_* macros access HWMP PERR frame fields via hardcoded
byte offsets. Each PERR destination entry contains an optional 6-byte AE
(Address Extension) address followed by a reason code, making offset-based
access error-prone.

Introduce typed packed C structs to represent the PERR frame layout:
  - ieee80211_mesh_hwmp_perr: top-level frame containing TTL and
    destination count
  - ieee80211_mesh_hwmp_perr_dst: per-destination entry with optional AE
    address and variable-position reason code

Add ieee80211_mesh_hwmp_perr_get_rcode() to locate the reason code in
each destination entry depending on whether the AE flag is set.

This refactoring makes the PERR processing code consistent with the
struct-based approach adopted for PREQ and PREP in preceding patches.

Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
---
 include/linux/ieee80211-mesh.h | 62 ++++++++++++++++++++++++++++++++++
 net/mac80211/mesh_hwmp.c       | 31 +++--------------
 2 files changed, 67 insertions(+), 26 deletions(-)

diff --git a/include/linux/ieee80211-mesh.h b/include/linux/ieee80211-mesh.h
index 4ce4e47d6d01..f709263c310b 100644
--- a/include/linux/ieee80211-mesh.h
+++ b/include/linux/ieee80211-mesh.h
@@ -71,6 +71,21 @@ struct ieee80211_mesh_hwmp_prep_bottom {
 	__le32 orig_sn;
 } __packed;
 
+struct ieee80211_mesh_hwmp_perr_dst {
+	u8 flags;
+	u8 addr[ETH_ALEN];
+	__le32 sn;
+	/* optional Destination External Address */
+	u8 variable[];
+} __packed;
+
+struct ieee80211_mesh_hwmp_perr {
+	u8 ttl;
+	u8 number_of_dst;
+	/* Destinations */
+	u8 variable[];
+} __packed;
+
 /* Mesh flags */
 #define MESH_FLAGS_AE_A4 	0x1
 #define MESH_FLAGS_AE_A5_A6	0x2
@@ -296,4 +311,51 @@ ieee80211_mesh_hwmp_prep_get_bottom(const u8 *ie)
 		ieee80211_mesh_preq_prep_ae_enabled(ie) ? ETH_ALEN : 0];
 }
 
+static inline struct ieee80211_mesh_hwmp_perr_dst *
+ieee80211_mesh_hwmp_perr_get_dst(const u8 *ie, u8 dst_idx)
+{
+	struct ieee80211_mesh_hwmp_perr *perr_ie = (void *)ie;
+	struct ieee80211_mesh_hwmp_perr_dst *dst;
+	u8 *pos = perr_ie->variable;
+	int i;
+
+	for (i = 0; i < dst_idx + 1; i++) {
+		dst = (void *)pos;
+		pos += sizeof(struct ieee80211_mesh_hwmp_perr_dst) +
+			  ((dst->flags & AE_F) ? ETH_ALEN : 0)
+			  /* Destination External Address */ +
+			  2 /* Reason Code */;
+	}
+
+	return dst;
+}
+
+static inline u8 *
+ieee80211_mesh_hwmp_perr_get_addr(const u8 *ie, u8 dst_idx)
+{
+	struct ieee80211_mesh_hwmp_perr_dst *dst =
+		ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx);
+
+	return dst->addr;
+}
+
+static inline u32
+ieee80211_mesh_hwmp_perr_get_sn(const u8 *ie, u8 dst_idx)
+{
+	struct ieee80211_mesh_hwmp_perr_dst *dst =
+		ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx);
+
+	return le32_to_cpu(dst->sn);
+}
+
+static inline u16
+ieee80211_mesh_hwmp_perr_get_rcode(const u8 *ie, u8 dst_idx)
+{
+	struct ieee80211_mesh_hwmp_perr_dst *dst =
+		ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx);
+
+	return get_unaligned_le16(&dst->variable[
+		(dst->flags & AE_F) ? ETH_ALEN : 0]);
+}
+
 #endif /* LINUX_IEEE80211_MESH_H */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 39b782370df0..378338778a23 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -20,29 +20,7 @@
 
 static void mesh_queue_preq(struct mesh_path *, u8);
 
-static inline u32 u32_field_get(const u8 *preq_elem, int offset, bool ae)
-{
-	if (ae)
-		offset += 6;
-	return get_unaligned_le32(preq_elem + offset);
-}
-
-static inline u16 u16_field_get(const u8 *preq_elem, int offset, bool ae)
-{
-	if (ae)
-		offset += 6;
-	return get_unaligned_le16(preq_elem + offset);
-}
-
 /* HWMP IE processing macros */
-#define AE_F_SET(x)		(*x & AE_F)
-
-#define PERR_IE_TTL(x)		(*(x))
-#define PERR_IE_TARGET_FLAGS(x)	(*(x + 2))
-#define PERR_IE_TARGET_ADDR(x)	(x + 3)
-#define PERR_IE_TARGET_SN(x)	u32_field_get(x, 9, 0)
-#define PERR_IE_TARGET_RCODE(x)	u16_field_get(x, 13, 0)
-
 #define MSEC_TO_TU(x) (x*1000/1024)
 #define SN_GT(x, y) ((s32)(y - x) < 0)
 #define SN_LT(x, y) ((s32)(x - y) < 0)
@@ -774,6 +752,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
 				    const u8 *perr_elem)
 {
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	struct ieee80211_mesh_hwmp_perr *perr_elem_s = (void *)perr_elem;
 	struct mesh_path *mpath;
 	u8 ttl;
 	const u8 *ta, *target_addr;
@@ -781,15 +760,15 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
 	u16 target_rcode;
 
 	ta = mgmt->sa;
-	ttl = PERR_IE_TTL(perr_elem);
+	ttl = perr_elem_s->ttl;
 	if (ttl <= 1) {
 		ifmsh->mshstats.dropped_frames_ttl++;
 		return;
 	}
 	ttl--;
-	target_addr = PERR_IE_TARGET_ADDR(perr_elem);
-	target_sn = PERR_IE_TARGET_SN(perr_elem);
-	target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
+	target_addr = ieee80211_mesh_hwmp_perr_get_addr(perr_elem, 0);
+	target_sn = ieee80211_mesh_hwmp_perr_get_sn(perr_elem, 0);
+	target_rcode = ieee80211_mesh_hwmp_perr_get_rcode(perr_elem, 0);
 
 	rcu_read_lock();
 	mpath = mesh_path_lookup(sdata, target_addr);
-- 
2.43.0


  parent reply	other threads:[~2026-05-29 23:10 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-29 23:09 [PATCH v9 1/9] wifi: mac80211: Use struct instead of macro for PREQ frame Masashi Honma
2026-05-29 23:09 ` [PATCH v9 2/9] wifi: mac80211: Use struct instead of macro for PREP frame Masashi Honma
2026-05-29 23:09 ` Masashi Honma [this message]
2026-05-29 23:09 ` [PATCH v9 4/9] wifi: mac80211: Fix overread in PREQ frame processing Masashi Honma
2026-05-29 23:09 ` [PATCH v9 5/9] wifi: mac80211: Fix overread in PREP " Masashi Honma
2026-05-29 23:09 ` [PATCH v9 6/9] wifi: mac80211: Fix PERR " Masashi Honma
2026-05-29 23:09 ` [PATCH v9 7/9] Add KUnit test for ieee80211_mesh_preq_size_ok Masashi Honma
2026-05-29 23:09 ` [PATCH v9 8/9] Add KUnit test for ieee80211_mesh_prep_size_ok Masashi Honma
2026-05-29 23:09 ` [PATCH v9 9/9] Add KUnit test for ieee80211_mesh_perr_size_ok Masashi Honma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260529230952.124754-3-masashi.honma@gmail.com \
    --to=masashi.honma@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox