]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: cfg80211: Fix "no buffer space available" error in nl80211_get_station() for MLO
authorNithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com>
Fri, 5 Sep 2025 12:48:00 +0000 (18:18 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 10 Sep 2025 07:11:35 +0000 (09:11 +0200)
Currently, nl80211_get_station() allocates a fixed buffer size using
NLMSG_DEFAULT_SIZE. In multi-link scenarios - particularly when the
number of links exceeds two - this buffer size is often insufficient
to accommodate complete station statistics, resulting in "no buffer
space available" errors.

To address this, modify nl80211_get_station() to return only
accumulated station statistics and exclude per link stats.

Pass a new flag (link_stats) to nl80211_send_station() to control
the inclusion of per link statistics. This allows retaining
detailed output with per link data in dump commands, while
excluding it from other commands where it is not needed.

This change modifies the handling of per link stats introduced in
commit 82d7f841d9bd ("wifi: cfg80211: extend to embed link level
statistics in NL message") to enable them only for
nl80211_dump_station().

Apply the same fix to cfg80211_del_sta_sinfo() by skipping per link
stats to avoid buffer issues. cfg80211_new_sta() doesn't include
stats and is therefore not impacted.

Fixes: 82d7f841d9bd ("wifi: cfg80211: extend to embed link level statistics in NL message")
Signed-off-by: Nithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com>
Link: https://patch.msgid.link/20250905124800.1448493-1-nithyanantham.paramasivam@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index 89519aa52893e6c7738d4e24352b0a77bc4e89c8..f2f7424e930cc134f504c69d8b17544c31955687 100644 (file)
@@ -7062,7 +7062,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
                                u32 seq, int flags,
                                struct cfg80211_registered_device *rdev,
                                struct net_device *dev,
-                               const u8 *mac_addr, struct station_info *sinfo)
+                               const u8 *mac_addr, struct station_info *sinfo,
+                               bool link_stats)
 {
        void *hdr;
        struct nlattr *sinfoattr, *bss_param;
@@ -7283,7 +7284,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
                        goto nla_put_failure;
        }
 
-       if (sinfo->valid_links) {
+       if (link_stats && sinfo->valid_links) {
                links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
                if (!links)
                        goto nla_put_failure;
@@ -7574,7 +7575,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
                                NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                rdev, wdev->netdev, mac_addr,
-                               &sinfo) < 0)
+                               &sinfo, true) < 0)
                        goto out;
 
                sta_idx++;
@@ -7635,7 +7636,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 
        if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
                                 info->snd_portid, info->snd_seq, 0,
-                                rdev, dev, mac_addr, &sinfo) < 0) {
+                                rdev, dev, mac_addr, &sinfo, false) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
@@ -19680,7 +19681,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
                return;
 
        if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
-                                rdev, dev, mac_addr, sinfo) < 0) {
+                                rdev, dev, mac_addr, sinfo, false) < 0) {
                nlmsg_free(msg);
                return;
        }
@@ -19710,7 +19711,7 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
        }
 
        if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
-                                rdev, dev, mac_addr, sinfo) < 0) {
+                                rdev, dev, mac_addr, sinfo, false) < 0) {
                nlmsg_free(msg);
                return;
        }