2011-12-15 16:30:31

by Helmut Schaa

[permalink] [raw]
Subject: QoS frames in AP mode?

Hi,

just noticed a problem with QoS frames in AP mode when mac80211
relays for example a VOIP frame from STA1 to STA2 the frame will be
sent out on AC_BE and not on AC_VO.

When the frame is processed in the rx path we will send it to the wireless media
with the code path below (from rx.c):

if (xmit_skb) {
/* send to wireless media */
xmit_skb->protocol = htons(ETH_P_802_3);
skb_reset_network_header(xmit_skb);
skb_reset_mac_header(xmit_skb);
dev_queue_xmit(xmit_skb);
}

So, skb->priority is the same as the received frame but will be overwritten
because the the netstack will call ieee80211_select_queue to select the
appropriate queue which in turn will use cfg80211_classify8021d to select
the skb->priority and the according queue (from net/wireless/util.c):

unsigned int cfg80211_classify8021d(struct sk_buff *skb)
{
unsigned int dscp;

/* skb->priority values from 256->263 are magic values to
* directly indicate a specific 802.1d priority. This is used
* to allow 802.1d priority to be passed directly in from VLAN
* tags, etc.
*/
if (skb->priority >= 256 && skb->priority <= 263)
return skb->priority - 256;

switch (skb->protocol) {
case htons(ETH_P_IP):
dscp = ip_hdr(skb)->tos & 0xfc;
break;
default:
return 0;
}

return dscp >> 5;
}

Unfortunately we don't have an skb priority between 256 and 263 and
we don't have skb->protocol set to ETH_P_IP here since we've just set
it to ETH_P_802_3.

I tried using eth_type_trans on the frame but that will "pull" the ethernet
header and adding an skb_push afterwards seems a little bit ugly to me.

Is it possible to just shortcut the classification if the priority is
already set?
Or should we just add 256 to the priority before sending the frame to
dev_queue_xmit?

What would be an appropriate fix for this?

Thanks,
Helmut


2011-12-16 08:14:22

by Helmut Schaa

[permalink] [raw]
Subject: Re: QoS frames in AP mode?

On Thu, Dec 15, 2011 at 6:00 PM, Johannes Berg
<[email protected]> wrote:

>> ? ? ? ? /* skb->priority values from 256->263 are magic values to
>> ? ? ? ? ?* directly indicate a specific 802.1d priority. ?This is used
>> ? ? ? ? ?* to allow 802.1d priority to be passed directly in from VLAN
>> ? ? ? ? ?* tags, etc.
>> ? ? ? ? ?*/
>> ? ? ? ? if (skb->priority >= 256 && skb->priority <= 263)
>> ? ? ? ? ? ? ? ? return skb->priority - 256;

Is this code still valid? I haven't found a reference in the 802.1q code :(

Helmut

2011-12-15 17:00:10

by Johannes Berg

[permalink] [raw]
Subject: Re: QoS frames in AP mode?

On Thu, 2011-12-15 at 17:30 +0100, Helmut Schaa wrote:

> just noticed a problem with QoS frames in AP mode when mac80211
> relays for example a VOIP frame from STA1 to STA2 the frame will be
> sent out on AC_BE and not on AC_VO.

Hm. You want (T)DLS ;-)

> When the frame is processed in the rx path we will send it to the wireless media
> with the code path below (from rx.c):
>
> if (xmit_skb) {
> /* send to wireless media */
> xmit_skb->protocol = htons(ETH_P_802_3);
> skb_reset_network_header(xmit_skb);
> skb_reset_mac_header(xmit_skb);
> dev_queue_xmit(xmit_skb);
> }
>
> So, skb->priority is the same as the received frame but will be overwritten
> because the the netstack will call ieee80211_select_queue to select the
> appropriate queue which in turn will use cfg80211_classify8021d to select
> the skb->priority and the according queue (from net/wireless/util.c):
>
> unsigned int cfg80211_classify8021d(struct sk_buff *skb)
> {
> unsigned int dscp;
>
> /* skb->priority values from 256->263 are magic values to
> * directly indicate a specific 802.1d priority. This is used
> * to allow 802.1d priority to be passed directly in from VLAN
> * tags, etc.
> */
> if (skb->priority >= 256 && skb->priority <= 263)
> return skb->priority - 256;
>
> switch (skb->protocol) {
> case htons(ETH_P_IP):
> dscp = ip_hdr(skb)->tos & 0xfc;
> break;
> default:
> return 0;
> }
>
> return dscp >> 5;
> }
>
> Unfortunately we don't have an skb priority between 256 and 263 and
> we don't have skb->protocol set to ETH_P_IP here since we've just set
> it to ETH_P_802_3.
>
> I tried using eth_type_trans on the frame but that will "pull" the ethernet
> header and adding an skb_push afterwards seems a little bit ugly to me.
>
> Is it possible to just shortcut the classification if the priority is
> already set?
> Or should we just add 256 to the priority before sending the frame to
> dev_queue_xmit?
>
> What would be an appropriate fix for this?

The >= 256 is already a shortcut, so just adding 256 seems reasonable?

johannes


2011-12-27 20:54:44

by Jouni Malinen

[permalink] [raw]
Subject: Re: QoS frames in AP mode?

On Fri, Dec 16, 2011 at 09:27:48AM +0100, Johannes Berg wrote:
> On Fri, 2011-12-16 at 09:14 +0100, Helmut Schaa wrote:
> > On Thu, Dec 15, 2011 at 6:00 PM, Johannes Berg
> > <[email protected]> wrote:
> >
> > >> /* skb->priority values from 256->263 are magic values to
> > >> * directly indicate a specific 802.1d priority. This is used
> > >> * to allow 802.1d priority to be passed directly in from VLAN
> > >> * tags, etc.
> > >> */
> > >> if (skb->priority >= 256 && skb->priority <= 263)
> > >> return skb->priority - 256;
> >
> > Is this code still valid? I haven't found a reference in the 802.1q code :(
>
> I always thought you'd use like iptables to set it to the right value,
> but I have no idea.

Yes, if my memory serves me right, this was indeed the original reason
for this code (from almost ten years ago... ;-). It was used in some
interesting combination of iptables and tc rules.

--
Jouni Malinen PGP id EFC895FA

2011-12-15 21:08:30

by Helmut Schaa

[permalink] [raw]
Subject: Re: QoS frames in AP mode?

On Thu, Dec 15, 2011 at 6:00 PM, Johannes Berg
<[email protected]> wrote:
> On Thu, 2011-12-15 at 17:30 +0100, Helmut Schaa wrote:
>> just noticed a problem with QoS frames in AP mode when mac80211
>> relays for example a VOIP frame from STA1 to STA2 the frame will be
>> sent out on AC_BE and not on AC_VO.
>
> Hm. You want (T)DLS ;-)

Would be nice but if the clients don't support it we're out of luck :)

>> Unfortunately we don't have an skb priority between 256 and 263 and
>> we don't have skb->protocol set to ETH_P_IP here since we've just set
>> it to ETH_P_802_3.
>>
>> I tried using eth_type_trans on the frame but that will "pull" the ethernet
>> header and adding an skb_push afterwards seems a little bit ugly to me.
>>
>> Is it possible to just shortcut the classification if the priority is
>> already set?
>> Or should we just add 256 to the priority before sending the frame to
>> dev_queue_xmit?
>>
>> What would be an appropriate fix for this?
>
> The >= 256 is already a shortcut, so just adding 256 seems reasonable?

Haven't tried that yet but I guess this works. However, if a client is
misbehaving and sending low priority frames with a high priority TID
we might want to re-classify the frame before sending to its
destination? Not sure though.

Helmut

2011-12-16 08:27:51

by Johannes Berg

[permalink] [raw]
Subject: Re: QoS frames in AP mode?

On Fri, 2011-12-16 at 09:14 +0100, Helmut Schaa wrote:
> On Thu, Dec 15, 2011 at 6:00 PM, Johannes Berg
> <[email protected]> wrote:
>
> >> /* skb->priority values from 256->263 are magic values to
> >> * directly indicate a specific 802.1d priority. This is used
> >> * to allow 802.1d priority to be passed directly in from VLAN
> >> * tags, etc.
> >> */
> >> if (skb->priority >= 256 && skb->priority <= 263)
> >> return skb->priority - 256;
>
> Is this code still valid? I haven't found a reference in the 802.1q code :(

I always thought you'd use like iptables to set it to the right value,
but I have no idea.

johannes