summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2009-07-09 21:42:16 (GMT)
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 19:05:07 (GMT)
commit10c836d7896e9d7b683a76f3cac3c289d8da72ef (patch)
treee68ed929565d3960f6d431d353fc41932f410fdf /net
parent4bde0f7d1dca0a7d886997eb8dee3fb47a6484e4 (diff)
downloadlinux-10c836d7896e9d7b683a76f3cac3c289d8da72ef.tar.xz
mac80211: Assign next hop address to pending mesh frames
Assign next hop address to pending mesh frames once the path is resolved. Regression. Frames transmitted when a mesh path was wating to be resolved were being transmitted with an invalid Receiver Address. [Changes since v1] Suggested by Johannes: - Improved frame_queue traversal - Narower RCU scope Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: Andrey Yurovsky <andrey@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mesh_pathtbl.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 479597e..f0304bf 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -55,7 +55,25 @@ static DEFINE_RWLOCK(pathtbl_resize_lock);
*/
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
{
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
+ struct sk_buff_head tmpq;
+ unsigned long flags;
+
rcu_assign_pointer(mpath->next_hop, sta);
+
+ __skb_queue_head_init(&tmpq);
+
+ spin_lock_irqsave(&mpath->frame_queue.lock, flags);
+
+ while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
+ hdr = (struct ieee80211_hdr *) skb->data;
+ memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
+ __skb_queue_tail(&tmpq, skb);
+ }
+
+ skb_queue_splice(&tmpq, &mpath->frame_queue);
+ spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
}