linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mac80211: fix rx data handling for non-data frames on multiple vifs
@ 2010-01-21 23:36 Felix Fietkau
  2010-01-22  9:27 ` Johannes Berg
  0 siblings, 1 reply; 2+ messages in thread
From: Felix Fietkau @ 2010-01-21 23:36 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville

The loop that passes non-data frames to all relevant vifs inside the
__ieee80211_rx_handle_packet keeps a pointer to the previous sdata to
avoid having to make unnecessary copies of the frame it's handling.
This led to a bug that caused it to apply the ieee80211_rx_data state
to the wrong interface, thereby either missing the rx.sta pointer or
having it assigned where it shouldn't be.
This breaks (among other things) aggregation on some vifs, as action
frame exchages are dropped to the cooked monitor interface due to
rx->sta being NULL.
Fix this by restructuring the loop so that it prepares the rx data just
before making the skb copy and calling the rx handlers.

Cc: stable@kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2348,22 +2348,6 @@ static void __ieee80211_rx_handle_packet
 			    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 				continue;
 
-			rx.sta = sta_info_get(sdata, hdr->addr2);
-
-			rx.flags |= IEEE80211_RX_RA_MATCH;
-			prepares = prepare_for_handlers(sdata, &rx, hdr);
-
-			if (!prepares)
-				continue;
-
-			if (status->flag & RX_FLAG_MMIC_ERROR) {
-				rx.sdata = sdata;
-				if (rx.flags & IEEE80211_RX_RA_MATCH)
-					ieee80211_rx_michael_mic_report(hdr,
-									&rx);
-				continue;
-			}
-
 			/*
 			 * frame is destined for this interface, but if it's
 			 * not also for the previous one we handle that after
@@ -2375,6 +2359,22 @@ static void __ieee80211_rx_handle_packet
 				continue;
 			}
 
+			rx.sta = sta_info_get(prev, hdr->addr2);
+
+			rx.flags |= IEEE80211_RX_RA_MATCH;
+			prepares = prepare_for_handlers(prev, &rx, hdr);
+
+			if (!prepares)
+				goto next;
+
+			if (status->flag & RX_FLAG_MMIC_ERROR) {
+				rx.sdata = prev;
+				if (rx.flags & IEEE80211_RX_RA_MATCH)
+					ieee80211_rx_michael_mic_report(hdr,
+									&rx);
+				goto next;
+			}
+
 			/*
 			 * frame was destined for the previous interface
 			 * so invoke RX handlers for it
@@ -2387,11 +2387,22 @@ static void __ieee80211_rx_handle_packet
 					       "multicast frame for %s\n",
 					       wiphy_name(local->hw.wiphy),
 					       prev->name);
-				continue;
+				goto next;
 			}
 			ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
+next:
 			prev = sdata;
 		}
+
+		if (prev) {
+			rx.sta = sta_info_get(prev, hdr->addr2);
+
+			rx.flags |= IEEE80211_RX_RA_MATCH;
+			prepares = prepare_for_handlers(prev, &rx, hdr);
+
+			if (!prepares)
+				prev = NULL;
+		}
 	}
 	if (prev)
 		ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] mac80211: fix rx data handling for non-data frames on multiple vifs
  2010-01-21 23:36 [PATCH] mac80211: fix rx data handling for non-data frames on multiple vifs Felix Fietkau
@ 2010-01-22  9:27 ` Johannes Berg
  0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2010-01-22  9:27 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, John W. Linville

[-- Attachment #1: Type: text/plain, Size: 2386 bytes --]

On Fri, 2010-01-22 at 00:36 +0100, Felix Fietkau wrote:

> Fix this by restructuring the loop so that it prepares the rx data just
> before making the skb copy and calling the rx handlers.
> 
> Cc: stable@kernel.org
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -2348,22 +2348,6 @@ static void __ieee80211_rx_handle_packet
>  			    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
>  				continue;
>  
> -			rx.sta = sta_info_get(sdata, hdr->addr2);
> -
> -			rx.flags |= IEEE80211_RX_RA_MATCH;
> -			prepares = prepare_for_handlers(sdata, &rx, hdr);
> -
> -			if (!prepares)
> -				continue;
> -
> -			if (status->flag & RX_FLAG_MMIC_ERROR) {
> -				rx.sdata = sdata;
> -				if (rx.flags & IEEE80211_RX_RA_MATCH)
> -					ieee80211_rx_michael_mic_report(hdr,
> -									&rx);
> -				continue;
> -			}
> -
>  			/*
>  			 * frame is destined for this interface, but if it's
>  			 * not also for the previous one we handle that after
> @@ -2375,6 +2359,22 @@ static void __ieee80211_rx_handle_packet
>  				continue;
>  			}
>  
> +			rx.sta = sta_info_get(prev, hdr->addr2);
> +
> +			rx.flags |= IEEE80211_RX_RA_MATCH;
> +			prepares = prepare_for_handlers(prev, &rx, hdr);
> +
> +			if (!prepares)
> +				goto next;
> +
> +			if (status->flag & RX_FLAG_MMIC_ERROR) {
> +				rx.sdata = prev;
> +				if (rx.flags & IEEE80211_RX_RA_MATCH)
> +					ieee80211_rx_michael_mic_report(hdr,
> +									&rx);
> +				goto next;
> +			}
> +
>  			/*
>  			 * frame was destined for the previous interface
>  			 * so invoke RX handlers for it
> @@ -2387,11 +2387,22 @@ static void __ieee80211_rx_handle_packet
>  					       "multicast frame for %s\n",
>  					       wiphy_name(local->hw.wiphy),
>  					       prev->name);
> -				continue;
> +				goto next;
>  			}
>  			ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
> +next:
>  			prev = sdata;
>  		}
> +
> +		if (prev) {
> +			rx.sta = sta_info_get(prev, hdr->addr2);
> +
> +			rx.flags |= IEEE80211_RX_RA_MATCH;
> +			prepares = prepare_for_handlers(prev, &rx, hdr);
> +
> +			if (!prepares)
> +				prev = NULL;
> +		}
>  	}
>  	if (prev)
>  		ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);

That's kinda subtle, but looks correct at first and second glance,
thanks.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-01-22  9:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-21 23:36 [PATCH] mac80211: fix rx data handling for non-data frames on multiple vifs Felix Fietkau
2010-01-22  9:27 ` Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).