Some drivers (ath9k for example) are using skb->protocol to treat EAPOL
frames somehow special (disallow aggregation for example).
When running in AP mode hostapd injects the EAPOL frames through a
monitor interface and thus skb->protocol isn't set at all. Hence, if the
injected frame is a data frame and carries a rfc1042 headaer update the
skb->protocol field accordingly.
Signed-off-by: Helmut Schaa <[email protected]>
---
Changes since v1:
Use cpu_to_be16 instead of ntohs as done everywhere in mac80211.
net/mac80211/tx.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index b83de4e..0499707 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1631,7 +1631,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
struct ieee80211_radiotap_header *prthdr =
(struct ieee80211_radiotap_header *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr;
u16 len_rthdr;
+ u8 *payload;
/*
* Frame injection is not allowed if beaconing is not allowed
@@ -1682,6 +1684,24 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
skb_set_network_header(skb, len_rthdr);
skb_set_transport_header(skb, len_rthdr);
+ /*
+ * Initialize skb->protocol if the injected frame is a data frame
+ * carrying a rfc1042 header
+ */
+ if (skb->len > len_rthdr + 2) {
+ hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
+ if (ieee80211_is_data(hdr->frame_control) &&
+ skb->len >= len_rthdr +
+ ieee80211_hdrlen(hdr->frame_control) +
+ sizeof(rfc1042_header) + 2) {
+ payload = (u8 *)hdr +
+ ieee80211_hdrlen(hdr->frame_control);
+ if (compare_ether_addr(payload, rfc1042_header) == 0)
+ skb->protocol = cpu_to_be16((payload[6] << 8) |
+ payload[7]);
+ }
+ }
+
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
--
1.7.3.4
On Mon, Aug 1, 2011 at 11:38 AM, Felix Fietkau <[email protected]> wrote:
> On 2011-08-01 11:32 AM, Helmut Schaa wrote:
>>
>> Signed-off-by: Helmut Schaa<[email protected]>
>> ---
>>
>> Haven't done much testing yet but this looks safe to me.
>> Helmut
>>
>> ?net/mac80211/rc80211_minstrel_ht.c | ? ?8 +++++++-
>> ?1 files changed, 7 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/mac80211/rc80211_minstrel_ht.c
>> b/net/mac80211/rc80211_minstrel_ht.c
>> index 66a1eeb..2158838 100644
>> --- a/net/mac80211/rc80211_minstrel_ht.c
>> +++ b/net/mac80211/rc80211_minstrel_ht.c
>> @@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta
>> *sta, void *priv_sta,
>> ? ? ? ? ? ? ? ?return mac80211_minstrel.get_rate(priv, sta,&msp->legacy,
>> txrc);
>>
>> ? ? ? ?info->flags |= mi->tx_flags;
>> - ? ? ? sample_idx = minstrel_get_sample_rate(mp, mi);
>> +
>> + ? ? ? /* Don't use EAPOL frames for sampling on non-mrr hw */
>> + ? ? ? if (mp->hw->max_rates == 1&&
>> + ? ? ? ? ? txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
>
> I think checking for mp->hw->max_rates < 3 would be better here, because
> then it also covers the primary rate + fallback rate case (as being used by
> b43), which also doesn't include the max_prob_rate in the mrr series.
The mp->hw->max_rates == 2 case is sample_rate -> max_prob_rate and
max_tp_rate -> max_prob_rate at the moment. So, these devices should be fine
already.
Helmut
On 2011-08-01 11:43 AM, Helmut Schaa wrote:
> On Mon, Aug 1, 2011 at 11:38 AM, Felix Fietkau<[email protected]> wrote:
>> On 2011-08-01 11:32 AM, Helmut Schaa wrote:
>>>
>>> Signed-off-by: Helmut Schaa<[email protected]>
>>> ---
>>>
>>> Haven't done much testing yet but this looks safe to me.
>>> Helmut
>>>
>>> net/mac80211/rc80211_minstrel_ht.c | 8 +++++++-
>>> 1 files changed, 7 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/net/mac80211/rc80211_minstrel_ht.c
>>> b/net/mac80211/rc80211_minstrel_ht.c
>>> index 66a1eeb..2158838 100644
>>> --- a/net/mac80211/rc80211_minstrel_ht.c
>>> +++ b/net/mac80211/rc80211_minstrel_ht.c
>>> @@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta
>>> *sta, void *priv_sta,
>>> return mac80211_minstrel.get_rate(priv, sta,&msp->legacy,
>>> txrc);
>>>
>>> info->flags |= mi->tx_flags;
>>> - sample_idx = minstrel_get_sample_rate(mp, mi);
>>> +
>>> + /* Don't use EAPOL frames for sampling on non-mrr hw */
>>> + if (mp->hw->max_rates == 1&&
>>> + txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
>>
>> I think checking for mp->hw->max_rates< 3 would be better here, because
>> then it also covers the primary rate + fallback rate case (as being used by
>> b43), which also doesn't include the max_prob_rate in the mrr series.
>
> The mp->hw->max_rates == 2 case is sample_rate -> max_prob_rate and
> max_tp_rate -> max_prob_rate at the moment. So, these devices should be fine
> already.
Yeah, you're right.
Acked-by: Felix Fietkau <[email protected]>
On 2011-08-01 11:32 AM, Helmut Schaa wrote:
> Signed-off-by: Helmut Schaa<[email protected]>
> ---
>
> Haven't done much testing yet but this looks safe to me.
> Helmut
>
> net/mac80211/rc80211_minstrel_ht.c | 8 +++++++-
> 1 files changed, 7 insertions(+), 1 deletions(-)
>
> diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
> index 66a1eeb..2158838 100644
> --- a/net/mac80211/rc80211_minstrel_ht.c
> +++ b/net/mac80211/rc80211_minstrel_ht.c
> @@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
> return mac80211_minstrel.get_rate(priv, sta,&msp->legacy, txrc);
>
> info->flags |= mi->tx_flags;
> - sample_idx = minstrel_get_sample_rate(mp, mi);
> +
> + /* Don't use EAPOL frames for sampling on non-mrr hw */
> + if (mp->hw->max_rates == 1&&
> + txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
I think checking for mp->hw->max_rates < 3 would be better here, because
then it also covers the primary rate + fallback rate case (as being used
by b43), which also doesn't include the max_prob_rate in the mrr series.
- Felix
Signed-off-by: Helmut Schaa <[email protected]>
---
Haven't done much testing yet but this looks safe to me.
Helmut
net/mac80211/rc80211_minstrel_ht.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 66a1eeb..2158838 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
info->flags |= mi->tx_flags;
- sample_idx = minstrel_get_sample_rate(mp, mi);
+
+ /* Don't use EAPOL frames for sampling on non-mrr hw */
+ if (mp->hw->max_rates == 1 &&
+ txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
+ sample_idx = -1;
+ else
+ sample_idx = minstrel_get_sample_rate(mp, mi);
#ifdef CONFIG_MAC80211_DEBUGFS
/* use fixed index if set */
--
1.7.3.4