summaryrefslogtreecommitdiff
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-05-13 14:15:49 +0200
committerJohn W. Linville <linville@tuxdriver.com>2011-05-16 14:10:41 -0400
commit40b275b69ee660274b77fb612b0db31fd282fc3f (patch)
tree29a4f82a44a12edcf9db5de6a3c6df9615a5799e /net/mac80211/mesh_hwmp.c
parentec034b208dc8aa5dc73ec46c3f27e34c5efbf113 (diff)
mac80211: sparse RCU annotations
This adds sparse RCU annotations to most of mac80211, only the mesh code remains to be done. Due the the previous patches, the annotations are pretty simple. The only thing that this actually changes is removing the RCU usage of key->sta in debugfs since this pointer isn't actually an RCU-managed pointer (it only has a single assignment done before the key even goes live). As that is otherwise harmless, I decided to make it part of this patch. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 2aec7c4f357b..2b18053070c1 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -560,6 +560,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
}
+static inline struct sta_info *
+next_hop_deref_protected(struct mesh_path *mpath)
+{
+ return rcu_dereference_protected(mpath->next_hop,
+ lockdep_is_held(&mpath->state_lock));
+}
+
+
static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
u8 *prep_elem, u32 metric)
@@ -599,7 +607,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
spin_unlock_bh(&mpath->state_lock);
goto fail;
}
- memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
+ memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN);
spin_unlock_bh(&mpath->state_lock);
--ttl;
flags = PREP_IE_FLAGS(prep_elem);
@@ -651,7 +659,8 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
if (mpath) {
spin_lock_bh(&mpath->state_lock);
if (mpath->flags & MESH_PATH_ACTIVE &&
- memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 &&
+ memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
+ ETH_ALEN) == 0 &&
(!(mpath->flags & MESH_PATH_SN_VALID) ||
SN_GT(target_sn, mpath->sn))) {
mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -913,6 +922,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
{
struct sk_buff *skb_to_free = NULL;
struct mesh_path *mpath;
+ struct sta_info *next_hop;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u8 *target_addr = hdr->addr3;
int err = 0;
@@ -940,7 +950,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
mesh_queue_preq(mpath,
PREQ_Q_F_START | PREQ_Q_F_REFRESH);
}
- memcpy(hdr->addr1, mpath->next_hop->sta.addr, ETH_ALEN);
+ next_hop = rcu_dereference(mpath->next_hop);
+ if (next_hop)
+ memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
+ else
+ err = -ENOENT;
} else {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!(mpath->flags & MESH_PATH_RESOLVING)) {