Commit 3d045a54 authored by Chun-Yeow Yeoh's avatar Chun-Yeow Yeoh Committed by John W. Linville

mac80211: Fix the generation of PREQs in proactive RANN mechanism of HWMP

According to Section Y.7.4 Actions on receipt of proactive RANN, an individually
addressed PREQ should be generated towards the neighbor peer mesh STA indicated
in the RANN Sender Address field in the forwarding information.
Signed-off-by: default avatarChun-Yeow Yeoh <yeohchunyeow@gmail.com>
Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarThomas Pedersen <thomas@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent be0b281e
...@@ -85,6 +85,8 @@ enum mesh_deferred_task_flags { ...@@ -85,6 +85,8 @@ enum mesh_deferred_task_flags {
* @state_lock: mesh path state lock used to protect changes to the * @state_lock: mesh path state lock used to protect changes to the
* mpath itself. No need to take this lock when adding or removing * mpath itself. No need to take this lock when adding or removing
* an mpath to a hash bucket on a path table. * an mpath to a hash bucket on a path table.
* @rann_snd_addr: the RANN sender address
* @is_root: the destination station of this path is a root node
* @is_gate: the destination station of this path is a mesh gate * @is_gate: the destination station of this path is a mesh gate
* *
* *
...@@ -109,6 +111,8 @@ struct mesh_path { ...@@ -109,6 +111,8 @@ struct mesh_path {
u8 discovery_retries; u8 discovery_retries;
enum mesh_path_flags flags; enum mesh_path_flags flags;
spinlock_t state_lock; spinlock_t state_lock;
u8 rann_snd_addr[ETH_ALEN];
bool is_root;
bool is_gate; bool is_gate;
}; };
......
...@@ -513,8 +513,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -513,8 +513,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
u8 *preq_elem, u32 metric) u8 *preq_elem, u32 metric)
{ {
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct mesh_path *mpath; struct mesh_path *mpath = NULL;
u8 *target_addr, *orig_addr; u8 *target_addr, *orig_addr;
const u8 *da;
u8 target_flags, ttl; u8 target_flags, ttl;
u32 orig_sn, target_sn, lifetime; u32 orig_sn, target_sn, lifetime;
bool reply = false; bool reply = false;
...@@ -591,9 +592,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -591,9 +592,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
flags = PREQ_IE_FLAGS(preq_elem); flags = PREQ_IE_FLAGS(preq_elem);
preq_id = PREQ_IE_PREQ_ID(preq_elem); preq_id = PREQ_IE_PREQ_ID(preq_elem);
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
da = (mpath && mpath->is_root) ?
mpath->rann_snd_addr : broadcast_addr;
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
cpu_to_le32(orig_sn), target_flags, target_addr, cpu_to_le32(orig_sn), target_flags, target_addr,
cpu_to_le32(target_sn), broadcast_addr, cpu_to_le32(target_sn), da,
hopcount, ttl, cpu_to_le32(lifetime), hopcount, ttl, cpu_to_le32(lifetime),
cpu_to_le32(metric), cpu_to_le32(preq_id), cpu_to_le32(metric), cpu_to_le32(preq_id),
sdata); sdata);
...@@ -742,8 +745,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -742,8 +745,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
return; return;
mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr, mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)",
root_is_gate); orig_addr, mgmt->sa, root_is_gate);
rcu_read_lock(); rcu_read_lock();
mpath = mesh_path_lookup(orig_addr, sdata); mpath = mesh_path_lookup(orig_addr, sdata);
...@@ -774,6 +777,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -774,6 +777,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
0, sdata); 0, sdata);
mpath->sn = orig_sn; mpath->sn = orig_sn;
} }
/* Using individually addressed PREQ for root node */
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);
...@@ -909,6 +917,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) ...@@ -909,6 +917,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
struct mesh_preq_queue *preq_node; struct mesh_preq_queue *preq_node;
struct mesh_path *mpath; struct mesh_path *mpath;
u8 ttl, target_flags; u8 ttl, target_flags;
const u8 *da;
u32 lifetime; u32 lifetime;
spin_lock_bh(&ifmsh->mesh_preq_queue_lock); spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
...@@ -971,9 +980,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) ...@@ -971,9 +980,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
target_flags = MP_F_RF; target_flags = MP_F_RF;
spin_unlock_bh(&mpath->state_lock); spin_unlock_bh(&mpath->state_lock);
da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
cpu_to_le32(mpath->sn), broadcast_addr, 0, cpu_to_le32(mpath->sn), da, 0,
ttl, cpu_to_le32(lifetime), 0, ttl, cpu_to_le32(lifetime), 0,
cpu_to_le32(ifmsh->preq_id++), sdata); cpu_to_le32(ifmsh->preq_id++), sdata);
mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
......
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