diff options
author | Javier Cardona <javier@cozybit.com> | 2009-07-07 13:55:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-24 15:05:31 -0400 |
commit | 249b405cf8145da8a74b70544ae1079d244bdb00 (patch) | |
tree | be2d79554f8a00ec74038e8526ceb1ce7a8daf3e | |
parent | 3d34deb6737b1ae1f8b7817b57d603807f5d88ea (diff) |
mac80211: Fix regression in mesh forwarding path.
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>
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 8 | ||||
-rw-r--r-- | net/mac80211/rx.c | 17 | ||||
-rw-r--r-- | net/mac80211/tx.c | 3 |
4 files changed, 20 insertions, 11 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 8e86e910edfc..e93c37ef6a48 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -784,7 +784,6 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
784 | mesh_path_add(dst_addr, sdata); | 784 | mesh_path_add(dst_addr, sdata); |
785 | mpath = mesh_path_lookup(dst_addr, sdata); | 785 | mpath = mesh_path_lookup(dst_addr, sdata); |
786 | if (!mpath) { | 786 | if (!mpath) { |
787 | dev_kfree_skb(skb); | ||
788 | sdata->u.mesh.mshstats.dropped_frames_no_route++; | 787 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
789 | err = -ENOSPC; | 788 | err = -ENOSPC; |
790 | goto endlookup; | 789 | goto endlookup; |
@@ -804,6 +803,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
804 | memcpy(hdr->addr1, mpath->next_hop->sta.addr, | 803 | memcpy(hdr->addr1, mpath->next_hop->sta.addr, |
805 | ETH_ALEN); | 804 | ETH_ALEN); |
806 | } else { | 805 | } else { |
806 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
807 | if (!(mpath->flags & MESH_PATH_RESOLVING)) { | 807 | if (!(mpath->flags & MESH_PATH_RESOLVING)) { |
808 | /* Start discovery only if it is not running yet */ | 808 | /* Start discovery only if it is not running yet */ |
809 | mesh_queue_preq(mpath, PREQ_Q_F_START); | 809 | mesh_queue_preq(mpath, PREQ_Q_F_START); |
@@ -815,6 +815,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
815 | skb_unlink(skb_to_free, &mpath->frame_queue); | 815 | skb_unlink(skb_to_free, &mpath->frame_queue); |
816 | } | 816 | } |
817 | 817 | ||
818 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | ||
818 | skb_queue_tail(&mpath->frame_queue, skb); | 819 | skb_queue_tail(&mpath->frame_queue, skb); |
819 | if (skb_to_free) | 820 | if (skb_to_free) |
820 | mesh_path_discard_frame(skb_to_free, sdata); | 821 | mesh_path_discard_frame(skb_to_free, sdata); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index f0304bfdcdff..04b9e4d61b8e 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -499,11 +499,9 @@ enddel: | |||
499 | */ | 499 | */ |
500 | void mesh_path_tx_pending(struct mesh_path *mpath) | 500 | void mesh_path_tx_pending(struct mesh_path *mpath) |
501 | { | 501 | { |
502 | struct sk_buff *skb; | 502 | if (mpath->flags & MESH_PATH_ACTIVE) |
503 | 503 | ieee80211_add_pending_skbs(mpath->sdata->local, | |
504 | while ((skb = skb_dequeue(&mpath->frame_queue)) && | 504 | &mpath->frame_queue); |
505 | (mpath->flags & MESH_PATH_ACTIVE)) | ||
506 | dev_queue_xmit(skb); | ||
507 | } | 505 | } |
508 | 506 | ||
509 | /** | 507 | /** |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7f33f775c5df..66c797cc85ce 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1479,10 +1479,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1479 | unsigned int hdrlen; | 1479 | unsigned int hdrlen; |
1480 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1480 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1481 | struct ieee80211_local *local = rx->local; | 1481 | struct ieee80211_local *local = rx->local; |
1482 | struct ieee80211_sub_if_data *sdata; | ||
1482 | 1483 | ||
1483 | hdr = (struct ieee80211_hdr *) skb->data; | 1484 | hdr = (struct ieee80211_hdr *) skb->data; |
1484 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1485 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1485 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 1486 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
1487 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | ||
1486 | 1488 | ||
1487 | if (!ieee80211_is_data(hdr->frame_control)) | 1489 | if (!ieee80211_is_data(hdr->frame_control)) |
1488 | return RX_CONTINUE; | 1490 | return RX_CONTINUE; |
@@ -1492,10 +1494,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1492 | return RX_DROP_MONITOR; | 1494 | return RX_DROP_MONITOR; |
1493 | 1495 | ||
1494 | if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){ | 1496 | if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){ |
1495 | struct ieee80211_sub_if_data *sdata; | ||
1496 | struct mesh_path *mppath; | 1497 | struct mesh_path *mppath; |
1497 | 1498 | ||
1498 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | ||
1499 | rcu_read_lock(); | 1499 | rcu_read_lock(); |
1500 | mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata); | 1500 | mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata); |
1501 | if (!mppath) { | 1501 | if (!mppath) { |
@@ -1541,6 +1541,19 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1541 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1541 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1542 | fwd_skb->iif = rx->dev->ifindex; | 1542 | fwd_skb->iif = rx->dev->ifindex; |
1543 | ieee80211_select_queue(local, fwd_skb); | 1543 | ieee80211_select_queue(local, fwd_skb); |
1544 | if (is_multicast_ether_addr(fwd_hdr->addr3)) | ||
1545 | memcpy(fwd_hdr->addr1, fwd_hdr->addr3, | ||
1546 | ETH_ALEN); | ||
1547 | else { | ||
1548 | int err = mesh_nexthop_lookup(fwd_skb, sdata); | ||
1549 | /* Failed to immediately resolve next hop: | ||
1550 | * fwded frame was dropped or will be added | ||
1551 | * later to the pending skb queue. */ | ||
1552 | if (err) | ||
1553 | return RX_DROP_MONITOR; | ||
1554 | } | ||
1555 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | ||
1556 | fwded_frames); | ||
1544 | ieee80211_add_pending_skb(local, fwd_skb); | 1557 | ieee80211_add_pending_skb(local, fwd_skb); |
1545 | } | 1558 | } |
1546 | } | 1559 | } |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a204092e8356..2572509d5568 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1419,9 +1419,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1419 | dev_put(sdata->dev); | 1419 | dev_put(sdata->dev); |
1420 | return; | 1420 | return; |
1421 | } | 1421 | } |
1422 | if (memcmp(sdata->dev->dev_addr, hdr->addr4, ETH_ALEN) != 0) | ||
1423 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | ||
1424 | fwded_frames); | ||
1425 | } else if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { | 1422 | } else if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { |
1426 | int hdrlen; | 1423 | int hdrlen; |
1427 | u16 len_rthdr; | 1424 | u16 len_rthdr; |