diff options
author | Chun-Yeow Yeoh <yeohchunyeow@gmail.com> | 2012-03-23 06:48:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-09 16:37:10 -0400 |
commit | d2a079fd48c05235b86016a33a79cb86a86e15a8 (patch) | |
tree | 060be7f455d64165eb5f5ca7187aac73bf5d79e2 /net | |
parent | 30899cc6ab4d4b63d43f6d652d1ecf9107eadb8d (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.h | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 24 |
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 */ |