wifi: cfg80211: allocate memory for link_station info structure

Currently, station_info structure is passed to fill station statistics
from mac80211/drivers. After NL message send to user space for requested
station statistics, memory for station statistics is freed in cfg80211.
Therefore, memory allocation/free for link station statistics should
also happen in cfg80211 only.

Hence, allocate the memory for link_station structure for all
possible links and free in cfg80211_sinfo_release_content().

Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
Link: https://patch.msgid.link/20250528054420.3050133-6-quic_sarishar@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Sarika Sharma 2025-05-28 11:14:15 +05:30 committed by Johannes Berg
parent 2d226d41db
commit 49e47223ec
2 changed files with 31 additions and 3 deletions

View file

@ -8577,6 +8577,13 @@ int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp);
static inline void cfg80211_sinfo_release_content(struct station_info *sinfo)
{
kfree(sinfo->pertid);
for (int link_id = 0; link_id < ARRAY_SIZE(sinfo->links); link_id++) {
if (sinfo->links[link_id]) {
kfree(sinfo->links[link_id]->pertid);
kfree(sinfo->links[link_id]);
}
}
}
/**

View file

@ -7366,7 +7366,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
struct wireless_dev *wdev;
u8 mac_addr[ETH_ALEN];
int sta_idx = cb->args[2];
int err;
int err, i;
err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
if (err)
@ -7386,6 +7386,16 @@ static int nl80211_dump_station(struct sk_buff *skb,
while (1) {
memset(&sinfo, 0, sizeof(sinfo));
for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
sinfo.links[i] =
kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL);
if (!sinfo.links[i]) {
err = -ENOMEM;
goto out_err;
}
}
err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
mac_addr, &sinfo);
if (err == -ENOENT)
@ -7410,6 +7420,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
cb->args[2] = sta_idx;
err = skb->len;
out_err:
cfg80211_sinfo_release_content(&sinfo);
wiphy_unlock(&rdev->wiphy);
return err;
@ -7422,7 +7433,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
struct station_info sinfo;
struct sk_buff *msg;
u8 *mac_addr = NULL;
int err;
int err, i;
memset(&sinfo, 0, sizeof(sinfo));
@ -7434,9 +7445,19 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->get_station)
return -EOPNOTSUPP;
for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
sinfo.links[i] = kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL);
if (!sinfo.links[i]) {
cfg80211_sinfo_release_content(&sinfo);
return -ENOMEM;
}
}
err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
if (err)
if (err) {
cfg80211_sinfo_release_content(&sinfo);
return err;
}
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {