Thread (10 messages) flat view 10 messages, 2 authors, 13h ago
HOTtoday

[PATCH wireless-next 6/7] wifi: mac80211: set flags/ctrl_flags before ieee80211_build_hdr()

From: Johannes Berg <johannes@sipsolutions.net>
Date: 2026-08-03 14:13:23
Subsystem: mac80211, the rest · Maintainers: Johannes Berg, Linus Torvalds

From: Johannes Berg <redacted>

ieee80211_build_hdr() takes the info and control flags to use as
arguments, but that leads to some messy code and missed cleanup.
Fill them in the SKB before calling ieee80211_build_hdr().

Signed-off-by: Johannes Berg <redacted>
---
 net/mac80211/tx.c | 60 +++++++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cc0c6b46d19c..96261429a78d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2639,9 +2639,7 @@ static void ieee80211_remove_ack_skb(struct ieee80211_local *local, u16 info_id)
  * ieee80211_build_hdr - build 802.11 header in the given frame
  * @sdata: virtual interface to build the header for
  * @skb: the skb to build the header in
- * @info_flags: skb flags to set
  * @sta: the station pointer
- * @ctrl_flags: info control flags to set
  * @cookie: cookie pointer to fill (if not %NULL)
  *
  * This function takes the skb with 802.3 header and reformats the header to
@@ -2649,19 +2647,20 @@ static void ieee80211_remove_ack_skb(struct ieee80211_local *local, u16 info_id)
  * being transmitted on.
  *
  * Note that this function also takes care of the TX status request. The skb
- * must not be shared.
+ * must not be shared, and its TX info must already be initialised - this
+ * function only fills in what it determines itself.
  *
  * The function requires the read-side RCU lock held
  *
  * Returns: the (possibly reallocated) skb or an ERR_PTR() code
  */
 static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
-					   struct sk_buff *skb, u32 info_flags,
-					   struct sta_info *sta, u32 ctrl_flags,
+					   struct sk_buff *skb,
+					   struct sta_info *sta,
 					   u64 cookie)
 {
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_tx_info *info;
 	int head_need;
 	u16 ethertype, hdrlen,  meshhdrlen = 0;
 	__le16 fc;
@@ -2677,14 +2676,15 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_chanctx_conf *chanctx_conf = NULL;
 	enum nl80211_band band;
 	int ret;
-	u8 link_id = u32_get_bits(ctrl_flags, IEEE80211_TX_CTRL_MLO_LINK);
+	u8 link_id = u32_get_bits(info->control.flags,
+				  IEEE80211_TX_CTRL_MLO_LINK);
 
 	if (IS_ERR(sta))
 		sta = NULL;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
 	if (local->force_tx_status)
-		info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
+		info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 #endif
 
 	/* convert Ethernet header to proper 802.11 header (based on
@@ -2825,7 +2825,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 		/* For injected frames, fill RA right away as nexthop lookup
 		 * will be skipped.
 		 */
-		if ((ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) &&
+		if ((info->control.flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) &&
 		    is_zero_ether_addr(hdr.addr1))
 			memcpy(hdr.addr1, skb->data, ETH_ALEN);
 		break;
@@ -2956,7 +2956,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 
 	if (unlikely(!multicast &&
 		     (sk_requests_wifi_status(skb->sk) || cookie)))
-		info_id = ieee80211_store_ack_skb(local, skb, &info_flags,
+		info_id = ieee80211_store_ack_skb(local, skb, &info->flags,
 						  cookie);
 
 	hdr.frame_control = fc;
@@ -3027,10 +3027,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 
 	skb_reset_mac_header(skb);
 
-	info = IEEE80211_SKB_CB(skb);
-	memset(info, 0, sizeof(*info));
-
-	info->flags = info_flags;
 	if (info_id) {
 		info->status_data = info_id;
 		info->status_data_idr = 1;
@@ -3038,18 +3034,18 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 	info->band = band;
 
 	if (likely(!cookie)) {
-		ctrl_flags |= u32_encode_bits(link_id,
-					      IEEE80211_TX_CTRL_MLO_LINK);
+		info->control.flags |=
+			u32_encode_bits(link_id, IEEE80211_TX_CTRL_MLO_LINK);
 	} else {
 		unsigned int pre_conf_link_id;
 
 		/*
-		 * ctrl_flags already have been set by
+		 * The link ID already has been set by
 		 * ieee80211_tx_control_port(), here
 		 * we just sanity check that
 		 */
 
-		pre_conf_link_id = u32_get_bits(ctrl_flags,
+		pre_conf_link_id = u32_get_bits(info->control.flags,
 						IEEE80211_TX_CTRL_MLO_LINK);
 
 		if (pre_conf_link_id != link_id &&
@@ -3064,8 +3060,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
-	info->control.flags = ctrl_flags;
-
 	return skb;
  free:
 	if (info_id)
@@ -4372,6 +4366,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_tx_info *info;
 	struct sta_info *sta;
 	struct sk_buff *next;
 	int len = skb->len;
@@ -4431,8 +4426,12 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 			goto out;
 		}
 
-		skb = ieee80211_build_hdr(sdata, skb, info_flags,
-					  sta, ctrl_flags, 0);
+		info = IEEE80211_SKB_CB(skb);
+		memset(info, 0, sizeof(*info));
+		info->flags = info_flags;
+		info->control.flags = ctrl_flags;
+
+		skb = ieee80211_build_hdr(sdata, skb, sta, 0);
 		if (IS_ERR(skb)) {
 			kfree_skb_list(next);
 			goto out;
@@ -4901,6 +4900,7 @@ ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
 		.local = sdata->local,
 		.sdata = sdata,
 	};
+	struct ieee80211_tx_info *info;
 	struct sta_info *sta;
 
 	rcu_read_lock();
@@ -4911,8 +4911,12 @@ ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
 		goto out;
 	}
 
-	skb = ieee80211_build_hdr(sdata, skb, info_flags, sta,
-				  IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, 0);
+	info = IEEE80211_SKB_CB(skb);
+	memset(info, 0, sizeof(*info));
+	info->flags = info_flags;
+	info->control.flags = IEEE80211_TX_CTRL_MLO_LINK_UNSPEC;
+
+	skb = ieee80211_build_hdr(sdata, skb, sta, 0);
 	if (IS_ERR(skb))
 		goto out;
 
@@ -6532,6 +6536,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_tx_info *info;
 	struct sta_info *sta;
 	struct sk_buff *skb;
 	struct ethhdr *ehdr;
@@ -6623,7 +6628,12 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
 	if (sta && sta->sta.mlo)
 		memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
 
-	skb = ieee80211_build_hdr(sdata, skb, flags, sta, ctrl_flags, cookie);
+	info = IEEE80211_SKB_CB(skb);
+	memset(info, 0, sizeof(*info));
+	info->flags = flags;
+	info->control.flags = ctrl_flags;
+
+	skb = ieee80211_build_hdr(sdata, skb, sta, cookie);
 	if (IS_ERR(skb)) {
 		rcu_read_unlock();
 		return PTR_ERR(skb);
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help