Skip to content

Commit

Permalink
mac80211: Fix regression in mesh forwarding path.
Browse files Browse the repository at this point in the history
The removal of the master netdev broke the mesh forwarding path.  This patch
fixes it by using the new internal 'pending' queue.

As a result of this change, mesh forwarding no longer does the inefficient
802.11 -> 802.3 -> 802.11 conversion that was done before.

[Changes since v1]
Suggested by Johannes:
 - Select queue before adding to mpath queue
 - ieee80211_add_pending_skb -> ieee80211_add_pending_skbs
 - Remove unnecessary header wme.h

Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Andrey Yurovsky <andrey@cozybit.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Javier Cardona authored and John W. Linville committed Jul 24, 2009
1 parent 3d34deb commit 249b405
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 11 deletions.
3 changes: 2 additions & 1 deletion net/mac80211/mesh_hwmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,6 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
mesh_path_add(dst_addr, sdata);
mpath = mesh_path_lookup(dst_addr, sdata);
if (!mpath) {
dev_kfree_skb(skb);
sdata->u.mesh.mshstats.dropped_frames_no_route++;
err = -ENOSPC;
goto endlookup;
Expand All @@ -804,6 +803,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
memcpy(hdr->addr1, mpath->next_hop->sta.addr,
ETH_ALEN);
} else {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!(mpath->flags & MESH_PATH_RESOLVING)) {
/* Start discovery only if it is not running yet */
mesh_queue_preq(mpath, PREQ_Q_F_START);
Expand All @@ -815,6 +815,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
skb_unlink(skb_to_free, &mpath->frame_queue);
}

info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
skb_queue_tail(&mpath->frame_queue, skb);
if (skb_to_free)
mesh_path_discard_frame(skb_to_free, sdata);
Expand Down
8 changes: 3 additions & 5 deletions net/mac80211/mesh_pathtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,9 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
*/
void mesh_path_tx_pending(struct mesh_path *mpath)
{
struct sk_buff *skb;

while ((skb = skb_dequeue(&mpath->frame_queue)) &&
(mpath->flags & MESH_PATH_ACTIVE))
dev_queue_xmit(skb);
if (mpath->flags & MESH_PATH_ACTIVE)
ieee80211_add_pending_skbs(mpath->sdata->local,
&mpath->frame_queue);
}

/**
Expand Down
17 changes: 15 additions & 2 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,10 +1479,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
unsigned int hdrlen;
struct sk_buff *skb = rx->skb, *fwd_skb;
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata;

hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);

if (!ieee80211_is_data(hdr->frame_control))
return RX_CONTINUE;
Expand All @@ -1492,10 +1494,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
return RX_DROP_MONITOR;

if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
struct ieee80211_sub_if_data *sdata;
struct mesh_path *mppath;

sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
rcu_read_lock();
mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
if (!mppath) {
Expand Down Expand Up @@ -1541,6 +1541,19 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
fwd_skb->iif = rx->dev->ifindex;
ieee80211_select_queue(local, fwd_skb);
if (is_multicast_ether_addr(fwd_hdr->addr3))
memcpy(fwd_hdr->addr1, fwd_hdr->addr3,
ETH_ALEN);
else {
int err = mesh_nexthop_lookup(fwd_skb, sdata);
/* Failed to immediately resolve next hop:
* fwded frame was dropped or will be added
* later to the pending skb queue. */
if (err)
return RX_DROP_MONITOR;
}
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_frames);
ieee80211_add_pending_skb(local, fwd_skb);
}
}
Expand Down
3 changes: 0 additions & 3 deletions net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,9 +1419,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
dev_put(sdata->dev);
return;
}
if (memcmp(sdata->dev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_frames);
} else if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
int hdrlen;
u16 len_rthdr;
Expand Down

0 comments on commit 249b405

Please sign in to comment.