Commit 7ebfa469 authored by Chun-Yeow Yeoh's avatar Chun-Yeow Yeoh Committed by Johannes Berg

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: default avatarMonthadar Al Jaberi <monthadar@gmail.com>
Signed-off-by: default avatarChun-Yeow Yeoh <yeohchunyeow@gmail.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent d6a4ed6f
...@@ -771,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -771,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
bool root_is_gate; bool root_is_gate;
ttl = rann->rann_ttl; ttl = rann->rann_ttl;
if (ttl <= 1) {
ifmsh->mshstats.dropped_frames_ttl++;
return;
}
ttl--;
flags = rann->rann_flags; flags = rann->rann_flags;
root_is_gate = !!(flags & RANN_FLAG_IS_GATE); root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
orig_addr = rann->rann_addr; orig_addr = rann->rann_addr;
...@@ -812,37 +807,49 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -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)) || if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
(time_after(jiffies, mpath->last_preq_to_root + (time_after(jiffies, mpath->last_preq_to_root +
root_path_confirmation_jiffies(sdata)) || root_path_confirmation_jiffies(sdata)) ||
time_before(jiffies, mpath->last_preq_to_root))) && 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, mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
orig_addr); orig_addr);
mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
mpath->last_preq_to_root = jiffies; mpath->last_preq_to_root = jiffies;
} }
if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
metric < mpath->rann_metric)) && 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->sn = orig_sn;
mpath->rann_metric = metric + metric_txsta; mpath->rann_metric = metric + metric_txsta;
mpath->is_root = true;
/* Recording RANNs sender address to send individually /* Recording RANNs sender address to send individually
* addressed PREQs destined for root mesh STA */ * addressed PREQs destined for root mesh STA */
memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
}
mpath->is_root = true;
if (root_is_gate) if (root_is_gate)
mesh_path_add_gate(mpath); 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);
}
rcu_read_unlock(); rcu_read_unlock();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment