Return-path: Received: from mail-pz0-f52.google.com ([209.85.210.52]:32937 "EHLO mail-pz0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752221Ab2FMJxW (ORCPT ); Wed, 13 Jun 2012 05:53:22 -0400 Received: by dano14 with SMTP id o14so831719dan.11 for ; Wed, 13 Jun 2012 02:53:22 -0700 (PDT) From: Chun-Yeow Yeoh To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, linville@tuxdriver.com, devel@lists.open80211s.org, Chun-Yeow Yeoh Subject: [PATCH v4 3/4] mac80211: implement the proactive PREP generation Date: Wed, 13 Jun 2012 17:52:23 +0800 Message-Id: <1339581144-9343-2-git-send-email-yeohchunyeow@gmail.com> (sfid-20120613_115325_971086_623FACB6) In-Reply-To: <1339581144-9343-1-git-send-email-yeohchunyeow@gmail.com> References: <1339581144-9343-1-git-send-email-yeohchunyeow@gmail.com> Sender: linux-wireless-owner@vger.kernel.org List-ID: Generate the proactive PREP element in Proactive PREQ mode as defined in Sec. 13.10.10.3 (Case D) of IEEE Std. 802.11-2012. Signed-off-by: Chun-Yeow Yeoh --- v2: adhere to Linux kernel coding style (Johannes) v3: eliminate 4 spaces indentation (Johannes) v4: make changes due to renaming enum variable (Johannes) net/mac80211/mesh_hwmp.c | 35 ++++++++++++++++++++++++++++++++--- 1 files changed, 32 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 82031bb..249b98b 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -519,10 +519,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, struct mesh_path *mpath = NULL; u8 *target_addr, *orig_addr; const u8 *da; - u8 target_flags, ttl; - u32 orig_sn, target_sn, lifetime; + u8 target_flags, ttl, flags; + u32 orig_sn, target_sn, lifetime, orig_metric; bool reply = false; bool forward = true; + bool root_is_gate; /* Update target SN, if present */ target_addr = PREQ_IE_TARGET_ADDR(preq_elem); @@ -530,6 +531,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = PREQ_IE_TARGET_SN(preq_elem); orig_sn = PREQ_IE_ORIG_SN(preq_elem); target_flags = PREQ_IE_TARGET_F(preq_elem); + orig_metric = metric; + /* Proactive PREQ gate announcements */ + flags = PREQ_IE_FLAGS(preq_elem); + root_is_gate = !!(flags & RANN_FLAG_IS_GATE); mhwmp_dbg("received PREQ from %pM", orig_addr); @@ -544,6 +549,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = ++ifmsh->sn; ifmsh->last_sn_update = jiffies; } + } else if (is_broadcast_ether_addr(target_addr) && + (target_flags & IEEE80211_PREQ_TO_FLAG)) { + rcu_read_lock(); + mpath = mesh_path_lookup(orig_addr, sdata); + if (mpath) { + if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { + reply = true; + target_addr = sdata->vif.addr; + target_sn = ++ifmsh->sn; + metric = 0; + ifmsh->last_sn_update = jiffies; + } + if (root_is_gate) + mesh_path_add_gate(mpath); + } + rcu_read_unlock(); } else { rcu_read_lock(); mpath = mesh_path_lookup(target_addr, sdata); @@ -576,8 +597,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, cpu_to_le32(target_sn), mgmt->sa, 0, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 0, sdata); - } else + } else { ifmsh->mshstats.dropped_frames_ttl++; + } } if (forward && ifmsh->mshcfg.dot11MeshForwarding) { @@ -597,6 +619,13 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; da = (mpath && mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; + + if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { + target_addr = PREQ_IE_TARGET_ADDR(preq_elem); + target_sn = PREQ_IE_TARGET_SN(preq_elem); + metric = orig_metric; + } + mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, cpu_to_le32(orig_sn), target_flags, target_addr, cpu_to_le32(target_sn), da, -- 1.7.0.4