diff options
author | Felix Fietkau <nbd@nbd.name> | 2023-03-14 10:59:51 +0100 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2023-03-22 13:31:18 +0100 |
commit | e626dad92383ca16d1d71e66124a272a0cbfe7bd (patch) | |
tree | aaff82328031e5dbaad29ea3719b9484080f716c /net/mac80211 | |
parent | wifi: mac80211: add support for letting drivers register tc offload support (diff) | |
download | linux-e626dad92383ca16d1d71e66124a272a0cbfe7bd.tar.xz linux-e626dad92383ca16d1d71e66124a272a0cbfe7bd.zip |
wifi: mac80211: fix race in mesh sequence number assignment
Since the sequence number is shared across different tx queues, it needs
to be atomic in order to avoid accidental duplicate assignment
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20230314095956.62085-2-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 6 |
2 files changed, 3 insertions, 5 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b2535614483e..04017d5c435a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -696,7 +696,7 @@ struct ieee80211_if_mesh { struct mesh_stats mshstats; struct mesh_config mshcfg; atomic_t estab_plinks; - u32 mesh_seqnum; + atomic_t mesh_seqnum; bool accepting_plinks; int num_gates; struct beacon_data __rcu *beacon; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 5a99b8f6e465..0608ed415831 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata, meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; - /* FIXME: racy -- TX on multiple queues can be concurrent */ - put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); - sdata->u.mesh.mesh_seqnum++; - + put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), + &meshhdr->seqnum); if (addr4or5 && !addr6) { meshhdr->flags |= MESH_FLAGS_AE_A4; memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); |