wifi: mac80211: balance mesh path quota accounting
Subsystems (2)
cover wifi: mac80211: balance mesh path quota accounting
The interface mesh path counter does not track the number of installed paths. Failed mesh additions can exhaust the quota while the table stays below the limit, and proxy-path churn can drive the counter negative and let later mesh additions exceed MESH_MAX_MPATHS.
mesh_path_add() reserves quota before allocation, but its allocation, insertion, and duplicate returns never roll it back. mpp_path_add() does not reserve quota at all, even though the common free path decrements the same counter for entries from both tables.
Make every successfully installed mesh or proxy path hold exactly one shared reservation, and release it whenever an addition fails. The two defects have different origins, so they are fixed in separate patches.
Validation used GCC W=1, Sparse C=2, and a controlled production-helper accounting matrix. Allocation and insertion errors used test-only fault injection; the concurrent duplicate path did not. A separate two-point hwsim 802.11s run reached mesh_path_add() from HWMP PREQ/PREP processing and mpp_path_add() from received mesh data with address extension. It observed the proxy-accounting difference with identical table walks. No physical-radio or layer-3 success is claimed.
Zhao Li (2):
wifi: mac80211: release mesh path quota on failed additions
wifi: mac80211: account proxy paths against the mesh path limit
net/mac80211/mesh_pathtbl.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
base-commit: 50d3d79dc0743b616afb00d01a626c76758721f7
Signature · 1 line
2.55.0
PATCH 1/2 wifi: mac80211: release mesh path quota on failed additions
Repeated failed or duplicate mesh path additions can exhaust MESH_MAX_MPATHS while the path table holds fewer paths, which stops new paths to reachable destinations from being created.
mesh_path_add() reserves a slot before allocating and inserting a path. If allocation fails, the function returns without releasing the slot. If the rhashtable insertion reports an error or an existing destination, the function discards its candidate but retains the reservation. No new path is installed in any of these cases.
Release the reservation whenever the candidate is not installed.
---
Validation:
- GCC W=1 and Sparse C=2 produced no diagnostics.
- A controlled production-helper matrix reproduced the allocation, insertion, and duplicate reservation leaks. Allocation and insertion errors used test-only fault injection; 24/24 concurrent same-destination trials leaked a reservation before the fix and 0/24 after. That case used no forced-failure hook.
- A two-point hwsim 802.11s run reached production mesh_path_add() from mesh_nexthop_resolve() and hwmp_route_info_get() during PREQ/PREP processing. No physical-radio or layer-3 success is claimed.
net/mac80211/mesh_pathtbl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/mac80211/mesh_pathtbl.c +4 -1
@@ -694,8 +694,10 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,return ERR_PTR (-ENOSPC ); new_mpath =mesh_path_new (sdata, dst,GFP_ATOMIC ); -if (!new_mpath) +if (!new_mpath) { +atomic_dec (&sdata->u.mesh.mpaths);return ERR_PTR (-ENOMEM ); + } tbl = &sdata->u.mesh.mesh_paths;spin_lock_bh (&tbl->walk_lock);
@@ -708,6 +710,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,if (mpath) {kfree (new_mpath); +atomic_dec (&sdata->u.mesh.mpaths);if (IS_ERR (mpath))return mpath;
Signature · 1 line
2.55.0
PATCH 2/2 wifi: mac80211: account proxy paths against the mesh path limit
In reply to Zhao LiProxy-path churn can drive the interface path counter negative and let later mesh path additions exceed MESH_MAX_MPATHS.
mesh_path_free_rcu() decrements the interface mpaths counter for entries from both the mesh and proxy path tables, but mpp_path_add() never reserves a slot in that counter. Removing or expiring a proxy path therefore returns a slot that was never charged.
mesh_path_add() uses the same counter to enforce MESH_MAX_MPATHS, so once it falls below the number of installed paths the limit no longer holds.
Reserve the shared quota before allocating a proxy path and release it on every unsuccessful addition. Mesh and proxy paths now share one 1024-entry budget, so mpp_path_add() can return -ENOSPC at that limit.
---
Validation:
- GCC W=1 and Sparse C=2 produced no diagnostics.
- A controlled production-helper matrix drove the counter to -10 through proxy-path churn before the fix and kept it at zero after it. With 1023 mesh paths and one proxy path installed, one further mesh addition exceeded the combined cap before the fix and returned -ENOSPC afterward.
- A two-point hwsim 802.11s run reached production mpp_path_add() from received address-extension mesh data. After one proxy install, the pre-patch counter was 2 and the fixed counter was 3 for the same three walk-list entries. No physical-radio or layer-3 success is claimed.
net/mac80211/mesh_pathtbl.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
net/mac80211/mesh_pathtbl.c +10 -3
@@ -736,10 +736,15 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,if (is_multicast_ether_addr (dst))return -EOPNOTSUPP ; +if (!atomic_add_unless (&sdata->u.mesh.mpaths,1 ,MESH_MAX_MPATHS )) +return -ENOSPC ; + new_mpath =mesh_path_new (sdata, dst,GFP_ATOMIC ); -if (!new_mpath) +if (!new_mpath) { +atomic_dec (&sdata->u.mesh.mpaths);return -ENOMEM ; + }memcpy (new_mpath->mpp, mpp,ETH_ALEN ); tbl = &sdata->u.mesh.mpp_paths;
@@ -752,10 +757,12 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,hlist_add_head_rcu (&new_mpath->walk_list, &tbl->walk_head);spin_unlock_bh (&tbl->walk_lock); -if (ret) +if (ret) {kfree (new_mpath); -else +atomic_dec (&sdata->u.mesh.mpaths); + }else {mesh_fast_tx_flush_addr (sdata, dst); + } sdata->u.mesh.mpp_paths_generation++;return ret;
Signature · 1 line
2.55.0