summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>2012-06-15 10:20:02 +0800
committerJohannes Berg <johannes.berg@intel.com>2012-06-18 19:18:55 +0200
commit7ebfa46973aa239f79fbd4651ddeed5c92df45b2 (patch)
tree48869c5bb2d00d9aab2008eca8bb8021bd5f379b /net/mac80211/mesh_hwmp.c
parentd6a4ed6fe0a0d4790941e7f13e56630b8b9b053d (diff)
downloadlinux-7ebfa46973aa239f79fbd4651ddeed5c92df45b2.tar.gz
linux-7ebfa46973aa239f79fbd4651ddeed5c92df45b2.tar.bz2
linux-7ebfa46973aa239f79fbd4651ddeed5c92df45b2.zip
mac80211: fix and improve mesh RANN processing
This patch fixes the problem of dropping RANN element if the TTL is 1. If the received RANN element TTL is 1 or greater than 1, the RANN is processed. However, forwarding of received RANN element with TTL 1 or less is prohibited according to the standard. This is previously reported by Monthadar Al Jaberi. Besides, this patch also avoid the processing of unicast PREQ generation if the RANN element does not meet the acceptance criteria mentioned in Sec. 13.10.12.4.2 of IEEE Std. 802.11-2012. Reported-by: Monthadar Al Jaberi <monthadar@gmail.com> Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index bea52479e3aa..aed1821bd6f1 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -771,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
bool root_is_gate;
ttl = rann->rann_ttl;
- if (ttl <= 1) {
- ifmsh->mshstats.dropped_frames_ttl++;
- return;
- }
- ttl--;
flags = rann->rann_flags;
root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
orig_addr = rann->rann_addr;
@@ -812,37 +807,49 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
}
}
+ if (!(SN_LT(mpath->sn, orig_sn)) &&
+ !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
+ rcu_read_unlock();
+ return;
+ }
+
if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
(time_after(jiffies, mpath->last_preq_to_root +
root_path_confirmation_jiffies(sdata)) ||
time_before(jiffies, mpath->last_preq_to_root))) &&
- !(mpath->flags & MESH_PATH_FIXED)) {
+ !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) {
mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
orig_addr);
mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
mpath->last_preq_to_root = jiffies;
}
- if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
- metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
+ mpath->sn = orig_sn;
+ mpath->rann_metric = metric + metric_txsta;
+ mpath->is_root = true;
+ /* Recording RANNs sender address to send individually
+ * addressed PREQs destined for root mesh STA */
+ memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
+
+ if (root_is_gate)
+ mesh_path_add_gate(mpath);
+
+ if (ttl <= 1) {
+ ifmsh->mshstats.dropped_frames_ttl++;
+ rcu_read_unlock();
+ return;
+ }
+ ttl--;
+
+ if (ifmsh->mshcfg.dot11MeshForwarding) {
mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
cpu_to_le32(orig_sn),
0, NULL, 0, broadcast_addr,
hopcount, ttl, cpu_to_le32(interval),
cpu_to_le32(metric + metric_txsta),
0, sdata);
- mpath->sn = orig_sn;
- mpath->rann_metric = metric + metric_txsta;
- /* Recording RANNs sender address to send individually
- * addressed PREQs destined for root mesh STA */
- memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
}
- mpath->is_root = true;
-
- if (root_is_gate)
- mesh_path_add_gate(mpath);
-
rcu_read_unlock();
}