diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-08-21 16:00:21 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-08-21 16:00:21 -0400 |
commit | 01e17dacd47101ad7d33152bbfbbd4394352d2e6 (patch) | |
tree | d94706b87fcad04d08a46a9b3555396d21ab41ec /net/mac80211/mesh_pathtbl.c | |
parent | 22c5649eef0fc37532e20c14d2656b28ca708a69 (diff) | |
parent | dcf33963c48e1959c83fda84e336dbb000eefa3f (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts:
drivers/net/wireless/mac80211_hwsim.c
Diffstat (limited to 'net/mac80211/mesh_pathtbl.c')
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 075bc535c60..aa749818860 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -203,23 +203,17 @@ 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) { + skb_queue_walk(&mpath->frame_queue, skb) { hdr = (struct ieee80211_hdr *) skb->data; memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN); - __skb_queue_tail(&tmpq, skb); } - skb_queue_splice(&tmpq, &mpath->frame_queue); spin_unlock_irqrestore(&mpath->frame_queue.lock, flags); } @@ -285,40 +279,42 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, struct mesh_path *from_mpath, bool copy) { - struct sk_buff *skb, *cp_skb = NULL; - struct sk_buff_head gateq, failq; + struct sk_buff *skb, *fskb, *tmp; + struct sk_buff_head failq; unsigned long flags; - int num_skbs; BUG_ON(gate_mpath == from_mpath); BUG_ON(!gate_mpath->next_hop); - __skb_queue_head_init(&gateq); __skb_queue_head_init(&failq); spin_lock_irqsave(&from_mpath->frame_queue.lock, flags); skb_queue_splice_init(&from_mpath->frame_queue, &failq); spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags); - num_skbs = skb_queue_len(&failq); - - while (num_skbs--) { - skb = __skb_dequeue(&failq); - if (copy) { - cp_skb = skb_copy(skb, GFP_ATOMIC); - if (cp_skb) - __skb_queue_tail(&failq, cp_skb); + skb_queue_walk_safe(&failq, fskb, tmp) { + if (skb_queue_len(&gate_mpath->frame_queue) >= + MESH_FRAME_QUEUE_LEN) { + mpath_dbg(gate_mpath->sdata, "mpath queue full!\n"); + break; } + skb = skb_copy(fskb, GFP_ATOMIC); + if (WARN_ON(!skb)) + break; + prepare_for_gate(skb, gate_mpath->dst, gate_mpath); - __skb_queue_tail(&gateq, skb); + skb_queue_tail(&gate_mpath->frame_queue, skb); + + if (copy) + continue; + + __skb_unlink(fskb, &failq); + kfree_skb(fskb); } - spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); - skb_queue_splice(&gateq, &gate_mpath->frame_queue); mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n", gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue)); - spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); if (!copy) return; @@ -531,7 +527,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) read_lock_bh(&pathtbl_resize_lock); memcpy(new_mpath->dst, dst, ETH_ALEN); - memset(new_mpath->rann_snd_addr, 0xff, ETH_ALEN); + eth_broadcast_addr(new_mpath->rann_snd_addr); new_mpath->is_root = false; new_mpath->sdata = sdata; new_mpath->flags = 0; |