Subject: [ipwave] QoS Data vs. Data for IPv6 over 802.11-OCB

From: Sandra Céspedes U. <[email-masked]>
Date: Thu, 10 Oct 2019 11:41:56 -0300

Dear all,

Here at Niclabs, Universidad de Chile, we have been playing with some 
commercial RSU and OBUs we use for research purposes. I asked my 
students to capture traffic from basic IP exchanges to confirm the type 
of encapsulation at the link layer. If you check the report below (I 
have also included the pcap files), they confirm that all the IP packets 
are encapsulated as QoS Data.

I'm providing the files to have more evidence of what the commercial 
vendors are doing in their implementations.

Hope you find them useful.

Best,
Sandra Céspedes

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

---

From: Alexandre Petrescu <[email-masked]>
Date: Fri, 11 Oct 2019 11:15:39 +0200

Dear Sandra,

Thank you very much for this reporting.

I skimmed quickly through the pcap, and I noticed indeed the presence of 
QoS Data headers in all IPv6 over OCB packets.  That is very good 
confirmation for the Internet Draft.

There are other things worth mentioning.

- the Priority is set to 'Best-Effort', whereas the Internet Draft 
IPv6-over-OCB says it SHOULD be 'Background'.  (in pcap, see header 
'IEEE 802.11 QoS Data', field 'Qos Control', field 'Priority:'; in I-D 
draft-ietf-ipwave-ipv6-over-80211ocb-52 see section 4.2 Frame Format).

- others.

Alex

Le 10/10/2019 à 16:41, Sandra Céspedes U. a écrit :
> _______________________________________________
> its mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/its
>

---

From: Alexandre Petrescu <[email-masked]>
Date: Thu, 17 Oct 2019 11:39:53 +0200

Hi IPWAVErs,

I take advantage of the email from Sandra reporting about the use of QoS 
Data headers for IP in Arada Systems.

We would like to make QoS Data headers for IP on OCB work on open 
source, because that is what the Internet Draft IPv6-over-OCB requires 
("The mapping to the 802.11 data service SHOULD use a 'priority' value 
of 1 (QoS with a 'Background' user priority)").  It is a long term goal. 
  We did some progress.  The most promissing result is maybe that ath10k 
_might_ work with QoS Data headers with IPv6 on OCB.

At this time we stopped trying to make QoS Data headers with IP on OCB 
work on open source.

Is somebody else working in the same aspects and who is more advanced 
than us in this study?

Do you know if it is possible to implement QoS data header on ATH9K? If 
yes is it possible to give us some technical details? If not is it 
possible to know what are the technical limits? How about ATH10K, is 
there any work in progress in this direction?

Here's what we tried:

0. we have a partner in Greece who specializes in making OCB cards with 
MArvell.  They worked with us from this WG, and with someone from 
Marvell, and from IEEE, to put a Marvell 88W8997 card, on a LAIRD 
module, a Manufacturer's Firmware, (MFW), at 5.9 GHz.  But that is still 
in a sort of simulator or 'sandbox' state in linux, that, even if it 
works, it does not really put packets in the air.  This result is of 
January 2019.

1. we tried to set the flow label on IPv6 base header, by using a python 
code from https://github.com/nasa/ipv6_python.  We hoped that setting 
the flow label it would automagically set the QoS Data headers.  But the 
result of this script is that the flow label changes at each packet and, 
worse, there is no QoS Data header added at all.  It is still the Data 
header that is set.

2. we tried to find options in the linux kernel (make menuconfig) that 
have the 'qos' name in some WiFi section.  In kernel 4.4.0 and 5.2.2 we 
found Symbols 'IPW2200_QOS' (Intel PRO/Wireless 2200BG...) and 
'DWMAC_DWC_QOS_ETH' (ST, Qualcomm, Intel) respectively.  But these are 
specific to these manufacturers, and supposedly would not work with 
manufacturer Atheros (ath9k) nor with the generic MAC80211.  And it is 
this ath9k driver that has open source OCB support (ST/Qualcomm/Intel 
dont do OCB).  Because of that, we were reluctant to set these QoS 
options on them.  We tried, half-heartedly, only to notice that the 
packets still dont get QoS Data headers.  It is understandable, because 
our cards are ath9k in OCB mode and not Intel/ST/Qualcomm.

3. we searched for 'qos', 'qos-data' and 'qos_data' throughout the 
entire kernel source code, and tried to reduce the results to only what 
is pertinent to WiFi (eliminate Ethernet, ATM and others).  For some 
Atheros drivers, we could guess that QoS is partly implemented. At this 
time we do not know how this works because we don't have right drivers 
to test (need ath10k like 802.11ac).  Worse - we don't really understand 
how QoS implementation works.

We can guess that it is possible to implement QoS Data header with a 
ATH10K driver, but we are not 100% sur about that.

I suppose that if we get an OCB mode with ath10k driver then not only we 
get QoS Data headers, but we get also higher bandwidth of IPv6 on OCB. 
This might be very helpful for many V2V communications involving video 
(needs high bandwidth low latency).

This is the raw output of the search results for QoS related to wifi in 
Atheros in kernel:

Ath5K :

ath/ath5k/base.c: if (ieee80211_is_data_qos(frame_control))

Ath6kl (for debugging?):

th/ath6kl/wmi.c:       hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
ath/ath6kl/wmi.c: * for delete qos stream from AP
ath/ath6kl/debug.c:static ssize_t ath6kl_create_qos_write(struct file *file,
ath/ath6kl/debug.c:static const struct file_operations fops_create_qos = {
ath/ath6kl/debug.c:    .write = ath6kl_create_qos_write,
ath/ath6kl/debug.c:static ssize_t ath6kl_delete_qos_write(struct file *file,
ath/ath6kl/debug.c:static const struct file_operations fops_delete_qos = {
ath/ath6kl/debug.c:    .write = ath6kl_delete_qos_write,
ath/ath6kl/debug.c:    debugfs_create_file("create_qos", S_IWUSR, 
ar->debugfs_phy, ar,
ath/ath6kl/debug.c:                   &fops_create_qos);
ath/ath6kl/debug.c:    debugfs_create_file("delete_qos", S_IWUSR, 
ar->debugfs_phy, ar,
ath/ath6kl/debug.c:                  &fops_delete_qos);

Ath9k (need to deepen and to understand what is done):

ath/ath9k/recv.c:     !ieee80211_is_qos_nullfunc(hdr->frame_control))
ath/ath9k/htc_drv_txrx.c:   if (ieee80211_is_data_qos(hdr->frame_control)) {
ath/ath9k/htc_drv_txrx.c:         qc = ieee80211_get_qos_ctl(hdr);
ath/ath9k/htc_drv_txrx.c:         if (ieee80211_is_data_qos(fc)) {
ath/ath9k/htc_drv_txrx.c:              qc = ieee80211_get_qos_ctl(hdr);
ath/ath9k/hw.c:static void ath9k_hw_init_qos(struct ath_hw *ah)
ath/ath9k/hw.c:  ath9k_hw_init_qos(ah);

Ath10k (the implementation seems to be more quantitative than for ath9k 
and it is done on mac layer, which is what we need)

ath/ath10k/htt.c:      36 + /* 802.11 + qos + ht */
ath/ath10k/wmi.c: .pmf_qos = WMI_PDEV_PARAM_PMF_QOS,
ath/ath10k/wmi.c: .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
ath/ath10k/wmi.c: .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
ath/ath10k/wmi.c: .pmf_qos = WMI_10_4_PDEV_PARAM_PMF_QOS,
ath/ath10k/mac.c:static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
ath/ath10k/mac.c:static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
ath/ath10k/mac.c:      if (vif->bss_conf.qos)
ath/ath10k/mac.c: ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
ath/ath10k/mac.c: ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
ath/ath10k/mac.c:      ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
ath/ath10k/mac.c:           ath10k_warn(ar, "failed to set qos params 
for STA %pM for vdev %i: %d\n",
ath/ath10k/mac.c: if (!ieee80211_is_data_qos(hdr->frame_control))
ath/ath10k/mac.c: return ieee80211_get_qos_ctl(hdr)[0] & 
IEEE80211_QOS_CTL_TID_MASK;
ath/ath10k/mac.c:     (ieee80211_is_nullfunc(fc) || 
ieee80211_is_qos_nullfunc(fc)) &&
ath/ath10k/mac.c: u8 *qos_ctl;
ath/ath10k/mac.c: if (!ieee80211_is_data_qos(hdr->frame_control))
ath/ath10k/mac.c: qos_ctl = ieee80211_get_qos_ctl(hdr);
ath/ath10k/mac.c:      skb->data, (void *)qos_ctl - (void *)skb->data);
ath/ath10k/mac.c: if (ieee80211_is_qos_nullfunc(hdr->frame_control))
ath/ath10k/mac.c: ret = ath10k_wmi_pdev_set_param(ar, 
ar->wmi.pdev_param->pmf_qos, 1);
ath/ath10k/rx_desc.h: * non_qos
ath/ath10k/wmi-tlv.h:  __le32 peer_qos;
ath/ath10k/htt.h: *       ext_tid: for qos-data frames (0-15), see 
%HTT_DATA_TX_EXT_TID_
ath/ath10k/htt.h: __le32 deliver_non_qos;
ath/ath10k/wmi.h: u32 pmf_qos;
ath/ath10k/wmi-tlv.c:static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 
uapsd_queues, u8 sp)
ath/ath10k/wmi-tlv.c:  u32 peer_qos = 0;
ath/ath10k/wmi-tlv.c:       peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
ath/ath10k/wmi-tlv.c:       peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
ath/ath10k/wmi-tlv.c:       peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
ath/ath10k/wmi-tlv.c:       peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
ath/ath10k/wmi-tlv.c:  peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
ath/ath10k/wmi-tlv.c:  return peer_qos;
ath/ath10k/wmi-tlv.c:  u32 peer_qos;
ath/ath10k/wmi-tlv.c:  peer_qos = 
ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
ath/ath10k/wmi-tlv.c:  peer_cap->peer_qos = __cpu_to_le32(peer_qos);
ath/ath10k/wmi-tlv.c:  .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
ath/ath10k/htt_rx.c:   if (!ieee80211_is_data_qos(hdr->frame_control))
ath/ath10k/htt_rx.c:   qc = ieee80211_get_qos_ctl(hdr);
ath/ath10k/htt_rx.c:   u8 *qos;
ath/ath10k/htt_rx.c:   qos = ieee80211_get_qos_ctl(hdr);
ath/ath10k/htt_rx.c:   qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;

Carl9170

ath/carl9170/rx.c:     if (ieee80211_is_data_qos(hdr->frame_control)) {
ath/carl9170/rx.c:          u8 *qc = ieee80211_get_qos_ctl(hdr);
ath/carl9170/rx.c:     if (ieee80211_is_data_qos(fc) && 
ieee80211_is_data_present(fc))
ath/carl9170/mac.c:int carl9170_set_qos(struct ar9170 *ar)
ath/carl9170/debug.c:static char *carl9170_debugfs_qos_stat_read(struct 
ar9170 *ar, char *buf,
ath/carl9170/debug.c:DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
ath/carl9170/debug.c:  DEBUGFS_ADD(qos_stat);
ath/carl9170/carl9170.h:    /* qos queue settings */
ath/carl9170/carl9170.h:int carl9170_set_qos(struct ar9170 *ar);
ath/carl9170/carl9170.h:    return (ieee80211_get_qos_ctl(hdr))[0] & 
IEEE80211_QOS_CTL_TID_MASK;
ath/carl9170/wlan.h:              u8 qos_queue:2;
ath/carl9170/main.c:   err = carl9170_set_qos(ar);
ath/carl9170/main.c:        ret = carl9170_set_qos(ar);

Wnc36xx

ath/wcn36xx/txrx.c:     if 
(WARN_ON(!ieee80211_is_data_qos(hdr->frame_control)))
ath/wcn36xx/txrx.c:    qc = ieee80211_get_qos_ctl(hdr);
ath/wcn36xx/txrx.c:    bool is_data_qos;
ath/wcn36xx/txrx.c:    is_data_qos = 
ieee80211_is_data_qos(hdr->frame_control);
ath/wcn36xx/txrx.c:                  is_data_qos ?
ath/wcn36xx/txrx.c:                  sizeof(struct ieee80211_qos_hdr) :
ath/wcn36xx/txrx.c:    if (sta_priv && is_data_qos)
ath/wcn36xx/txrx.c: 
ieee80211_is_data_qos(hdr->frame_control) ?
ath/wcn36xx/txrx.c:                  sizeof(struct ieee80211_qos_hdr) :

---

From: Alexandre Petrescu <[email-masked]>
Date: Fri, 25 Oct 2019 14:44:21 +0200

Sandra,

After further analysis of the reported work at Niclabs, and analysis of 
packet dumps from elsewhere, I am tempted to say that this was probably 
the first public report of running IPv6 over 802.11-OCB with 'QoS Data' 
headers - thanks!

Alex