aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>2012-03-23 06:48:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-09 16:37:10 -0400
commitd2a079fd48c05235b86016a33a79cb86a86e15a8 (patch)
tree060be7f455d64165eb5f5ca7187aac73bf5d79e2 /net
parent30899cc6ab4d4b63d43f6d652d1ecf9107eadb8d (diff)
mac80211: fix the RANN propagation issues
This patch is intended to solve the follwing issues in RANN propagation: [1] The interval in propagated RANN should be based on the interval of received RANN. [2] The aggregated path metric for propagated RANN is as received plus own link metric towards the transmitting mesh STA (not root mesh STA). [3] The comparison of path metric for RANN with same sequence number should be done before deciding whether to propagate or not. Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c24
2 files changed, 20 insertions, 6 deletions
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 2bd5d8b864f6..3e52439ed112 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -86,6 +86,7 @@ enum mesh_deferred_task_flags {
86 * mpath itself. No need to take this lock when adding or removing 86 * mpath itself. No need to take this lock when adding or removing
87 * an mpath to a hash bucket on a path table. 87 * an mpath to a hash bucket on a path table.
88 * @rann_snd_addr: the RANN sender address 88 * @rann_snd_addr: the RANN sender address
89 * @rann_metric: the aggregated path metric towards the root node
89 * @is_root: the destination station of this path is a root node 90 * @is_root: the destination station of this path is a root node
90 * @is_gate: the destination station of this path is a mesh gate 91 * @is_gate: the destination station of this path is a mesh gate
91 * 92 *
@@ -112,6 +113,7 @@ struct mesh_path {
112 enum mesh_path_flags flags; 113 enum mesh_path_flags flags;
113 spinlock_t state_lock; 114 spinlock_t state_lock;
114 u8 rann_snd_addr[ETH_ALEN]; 115 u8 rann_snd_addr[ETH_ALEN];
116 u32 rann_metric;
115 bool is_root; 117 bool is_root;
116 bool is_gate; 118 bool is_gate;
117}; 119};
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index f80a9e3da359..a80da3784a25 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -86,8 +86,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
86#define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0) 86#define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0)
87 87
88#define MSEC_TO_TU(x) (x*1000/1024) 88#define MSEC_TO_TU(x) (x*1000/1024)
89#define SN_GT(x, y) ((long) (y) - (long) (x) < 0) 89#define SN_GT(x, y) ((s32)(y - x) < 0)
90#define SN_LT(x, y) ((long) (x) - (long) (y) < 0) 90#define SN_LT(x, y) ((s32)(x - y) < 0)
91 91
92#define net_traversal_jiffies(s) \ 92#define net_traversal_jiffies(s) \
93 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) 93 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
@@ -732,11 +732,12 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
732 struct ieee80211_rann_ie *rann) 732 struct ieee80211_rann_ie *rann)
733{ 733{
734 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 734 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
735 struct ieee80211_local *local = sdata->local;
736 struct sta_info *sta;
735 struct mesh_path *mpath; 737 struct mesh_path *mpath;
736 u8 ttl, flags, hopcount; 738 u8 ttl, flags, hopcount;
737 u8 *orig_addr; 739 u8 *orig_addr;
738 u32 orig_sn, metric; 740 u32 orig_sn, metric, metric_txsta, interval;
739 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
740 bool root_is_gate; 741 bool root_is_gate;
741 742
742 ttl = rann->rann_ttl; 743 ttl = rann->rann_ttl;
@@ -749,6 +750,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
749 root_is_gate = !!(flags & RANN_FLAG_IS_GATE); 750 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
750 orig_addr = rann->rann_addr; 751 orig_addr = rann->rann_addr;
751 orig_sn = le32_to_cpu(rann->rann_seq); 752 orig_sn = le32_to_cpu(rann->rann_seq);
753 interval = le32_to_cpu(rann->rann_interval);
752 hopcount = rann->rann_hopcount; 754 hopcount = rann->rann_hopcount;
753 hopcount++; 755 hopcount++;
754 metric = le32_to_cpu(rann->rann_metric); 756 metric = le32_to_cpu(rann->rann_metric);
@@ -761,6 +763,14 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
761 orig_addr, mgmt->sa, root_is_gate); 763 orig_addr, mgmt->sa, root_is_gate);
762 764
763 rcu_read_lock(); 765 rcu_read_lock();
766 sta = sta_info_get(sdata, mgmt->sa);
767 if (!sta) {
768 rcu_read_unlock();
769 return;
770 }
771
772 metric_txsta = airtime_link_metric_get(local, sta);
773
764 mpath = mesh_path_lookup(orig_addr, sdata); 774 mpath = mesh_path_lookup(orig_addr, sdata);
765 if (!mpath) { 775 if (!mpath) {
766 mesh_path_add(orig_addr, sdata); 776 mesh_path_add(orig_addr, sdata);
@@ -780,14 +790,16 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
780 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); 790 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
781 } 791 }
782 792
783 if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) { 793 if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
794 metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
784 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 795 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
785 cpu_to_le32(orig_sn), 796 cpu_to_le32(orig_sn),
786 0, NULL, 0, broadcast_addr, 797 0, NULL, 0, broadcast_addr,
787 hopcount, ttl, cpu_to_le32(interval), 798 hopcount, ttl, cpu_to_le32(interval),
788 cpu_to_le32(metric + mpath->metric), 799 cpu_to_le32(metric + metric_txsta),
789 0, sdata); 800 0, sdata);
790 mpath->sn = orig_sn; 801 mpath->sn = orig_sn;
802 mpath->rann_metric = metric + metric_txsta;
791 } 803 }
792 804
793 /* Using individually addressed PREQ for root node */ 805 /* Using individually addressed PREQ for root node */