diff options
author | Thomas Pedersen <thomas@cozybit.com> | 2011-11-24 20:15:23 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-28 14:44:05 -0500 |
commit | d3c1597b8d1ba0447ce858c7c385eabcf69f2c8f (patch) | |
tree | 8cb77c385088aadf240d270f1c854d72d4193c52 /net/mac80211/rx.c | |
parent | 3c26f1f68e24d087cd3481aeb68a6274e6e0b30b (diff) |
mac80211: fix forwarded mesh frame queue mapping
We can't rely on ieee80211_select_queue() to do its job at this point
since the skb->protocol is not yet known. Instead, factor out and reuse
the queue mapping logic for injected frames.
Also, to mitigate congestion, forwarded frames should be dropped if the
outgoing queue was stopped. This was not correctly implemented as we
were not checking the right queue. Furthermore, we were dropping frames
that had arrived to their destination if that queue was stopped.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 60798d6d53cf..92fa95741761 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1899,6 +1899,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1899 | struct ieee80211_local *local = rx->local; | 1899 | struct ieee80211_local *local = rx->local; |
1900 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1900 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1901 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 1901 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
1902 | u16 q; | ||
1902 | 1903 | ||
1903 | hdr = (struct ieee80211_hdr *) skb->data; | 1904 | hdr = (struct ieee80211_hdr *) skb->data; |
1904 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1905 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1917,12 +1918,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1917 | /* illegal frame */ | 1918 | /* illegal frame */ |
1918 | return RX_DROP_MONITOR; | 1919 | return RX_DROP_MONITOR; |
1919 | 1920 | ||
1920 | if (ieee80211_queue_stopped(&local->hw, skb_get_queue_mapping(skb))) { | ||
1921 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | ||
1922 | dropped_frames_congestion); | ||
1923 | return RX_DROP_MONITOR; | ||
1924 | } | ||
1925 | |||
1926 | if (mesh_hdr->flags & MESH_FLAGS_AE) { | 1921 | if (mesh_hdr->flags & MESH_FLAGS_AE) { |
1927 | struct mesh_path *mppath; | 1922 | struct mesh_path *mppath; |
1928 | char *proxied_addr; | 1923 | char *proxied_addr; |
@@ -1954,7 +1949,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1954 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) | 1949 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) |
1955 | return RX_CONTINUE; | 1950 | return RX_CONTINUE; |
1956 | 1951 | ||
1957 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); | 1952 | q = ieee80211_select_queue_80211(local, skb, hdr); |
1953 | if (ieee80211_queue_stopped(&local->hw, q)) { | ||
1954 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | ||
1955 | dropped_frames_congestion); | ||
1956 | return RX_DROP_MONITOR; | ||
1957 | } | ||
1958 | skb_set_queue_mapping(skb, q); | ||
1958 | mesh_hdr->ttl--; | 1959 | mesh_hdr->ttl--; |
1959 | 1960 | ||
1960 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { | 1961 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |