Search Linux Wireless

Re: [RFC] mac80211: radiotap vendor data

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, May 1, 2010 at 10:13 AM, Johannes Berg
<johannes@xxxxxxxxxxxxxxxx> wrote:
> This allows drivers to add radiotap vendor data
> to any received frame, which will be simply
> passed into userspace and ignored by the kernel.
> Can be used by drivers to convey hw-specific
> information.

Thanks a lot for all your work on this area, on the standardization
part, mac80211 and even for providing a simple example, its really
appreciated! Some comments below.

> Note: 11n shouldn't be done there, in case somebody
> got ideas!!

Well you mean 802.11n standard stuff, I take it, because there are
vendor 802.11n specific stuff.

> Note: didn't test this after the paged RX changes
> ---
>  drivers/net/wireless/mac80211_hwsim.c |   17 ++++++++++
>  include/net/mac80211.h                |   12 +++++++
>  net/mac80211/rx.c                     |   53 ++++++++++++++++++++++++++++++----
>  3 files changed, 77 insertions(+), 5 deletions(-)
>
> --- wireless-testing.orig/include/net/mac80211.h        2010-05-01 08:46:26.000000000 +0200
> +++ wireless-testing/include/net/mac80211.h     2010-05-01 08:47:54.000000000 +0200
> @@ -565,6 +565,13 @@ enum mac80211_rx_flags {
>  * @rate_idx: index of data rate into band's supported rates or MCS index if
>  *     HT rates are use (RX_FLAG_HT)
>  * @flag: %RX_FLAG_*
> + * @vendor_radiotap_bitmap: radiotap vendor namespace presence bitmap
> + * @vendor_radiotap_len: radiotap vendor namespace length
> + * @vendor_radiotap_align: radiotap vendor namespace alignment. Note
> + *     that the actual data must be at the start of the SKB data
> + *     already.

I see your WARN_ON() on the alignment being set to 0 and set it to 1
then. Can you clarify a little more on this here. If there is no
strict alignment requirements why not just treat 0 as 1 then?

> + * @vendor_radiotap_oui: radiotap vendor namespace OUI
> + * @vendor_radiotap_subns: radiotap vendor sub namespace
>  */
>  struct ieee80211_rx_status {
>        u64 mactime;
> @@ -575,6 +582,11 @@ struct ieee80211_rx_status {
>        int antenna;
>        int rate_idx;
>        int flag;
> +       u32 vendor_radiotap_bitmap;
> +       u16 vendor_radiotap_len;
> +       u8 vendor_radiotap_align;
> +       u8 vendor_radiotap_oui[3];
> +       u8 vendor_radiotap_subns;
>  };
>
>  /**
> --- wireless-testing.orig/net/mac80211/rx.c     2010-05-01 08:46:26.000000000 +0200
> +++ wireless-testing/net/mac80211/rx.c  2010-05-01 08:47:54.000000000 +0200
> @@ -37,6 +37,8 @@
>  static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
>                                           struct sk_buff *skb)
>  {
> +       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
> +
>        if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
>                if (likely(skb->len > FCS_LEN))
>                        __pskb_trim(skb, skb->len - FCS_LEN);
> @@ -48,6 +50,9 @@ static struct sk_buff *remove_monitor_in
>                }
>        }
>
> +       if (status->vendor_radiotap_len)
> +               __pskb_pull(skb, status->vendor_radiotap_len);
> +
>        return skb;
>  }
>
> @@ -69,8 +74,8 @@ static inline int should_drop_frame(stru
>  }
>
>  static int
> -ieee80211_rx_radiotap_len(struct ieee80211_local *local,
> -                         struct ieee80211_rx_status *status)
> +ieee80211_rx_radiotap_space(struct ieee80211_local *local,
> +                           struct ieee80211_rx_status *status)
>  {
>        int len;
>
> @@ -87,6 +92,21 @@ ieee80211_rx_radiotap_len(struct ieee802
>        if (len & 1) /* padding for RX_FLAGS if necessary */
>                len++;
>
> +       if (status->vendor_radiotap_len) {
> +               /* allocate extra bitmap */
> +               len += 4;
> +
> +               if (WARN_ON(status->vendor_radiotap_align == 0))
> +                       status->vendor_radiotap_align = 1;
> +               /* align standard part of vendor namespace */
> +               len = ALIGN(len, 2);
> +               /* allocate standard part of vendor namespace */
> +               len += 6;
> +               /* align vendor-defined part */
> +               len = ALIGN(len, status->vendor_radiotap_align);
> +               /* vendor-defined part is already in skb */
> +       }
> +
>        return len;
>  }
>
> @@ -115,10 +135,18 @@ ieee80211_add_rx_radiotap_header(struct
>                            (1 << IEEE80211_RADIOTAP_CHANNEL) |
>                            (1 << IEEE80211_RADIOTAP_ANTENNA) |
>                            (1 << IEEE80211_RADIOTAP_RX_FLAGS));
> -       rthdr->it_len = cpu_to_le16(rtap_len);
> +       rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
>
>        pos = (unsigned char *)(rthdr+1);
>
> +       if (status->vendor_radiotap_len) {
> +               rthdr->it_present |=
> +                       cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
> +                       cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
> +               put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
> +               pos += 4;
> +       }
> +
>        /* the order of the following fields is important */
>
>        /* IEEE80211_RADIOTAP_TSFT */
> @@ -190,11 +218,26 @@ ieee80211_add_rx_radiotap_header(struct
>        /* IEEE80211_RADIOTAP_RX_FLAGS */
>        /* ensure 2 byte alignment for the 2 byte field as required */
>        if ((pos - (u8 *)rthdr) & 1)
> -               pos++;
> +               *pos++ = 0;

Why is this needed though? We already memset(rthdr, 0, rtap_len); above.

>        if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
>                rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
>        put_unaligned_le16(rx_flags, pos);
>        pos += 2;
> +
> +       if (status->vendor_radiotap_len) {
> +               /* ensure 2 byte alignment for the vendor field as required */
> +               if ((pos - (u8 *)rthdr) & 1)
> +                       *pos++ = 0;
> +               *pos++ = status->vendor_radiotap_oui[0];
> +               *pos++ = status->vendor_radiotap_oui[1];
> +               *pos++ = status->vendor_radiotap_oui[2];
> +               *pos++ = status->vendor_radiotap_subns;
> +               put_unaligned_le16(status->vendor_radiotap_len, pos);
> +               pos += 2;
> +               /* align the actual payload as requested */
> +               while ((pos - (u8 *)rthdr) & (status->vendor_radiotap_align - 1))
> +                       *pos++ = 0;
> +       }
>  }
>
>  /*
> @@ -223,7 +266,7 @@ ieee80211_rx_monitor(struct ieee80211_lo
>         */
>
>        /* room for the radiotap header based on driver features */
> -       needed_headroom = ieee80211_rx_radiotap_len(local, status);
> +       needed_headroom = ieee80211_rx_radiotap_space(local, status);
>
>        if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
>                present_fcs_len = FCS_LEN;
> --- wireless-testing.orig/drivers/net/wireless/mac80211_hwsim.c 2010-05-01 08:46:27.000000000 +0200
> +++ wireless-testing/drivers/net/wireless/mac80211_hwsim.c      2010-05-01 19:04:57.000000000 +0200
> @@ -484,6 +484,7 @@ static bool mac80211_hwsim_tx_frame(stru
>        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
>        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>        struct ieee80211_rx_status rx_status;
> +       u8 *vendor_data;
>
>        if (data->idle) {
>                printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n",
> @@ -509,6 +510,20 @@ static bool mac80211_hwsim_tx_frame(stru
>        secpath_reset(skb);
>        nf_reset(skb);
>
> +       vendor_data = skb_push(skb, 4);
> +       rx_status.vendor_radiotap_len = 4;
> +       rx_status.vendor_radiotap_align = 4;
> +       rx_status.vendor_radiotap_oui[0] = 0xff;
> +       rx_status.vendor_radiotap_oui[1] = 0xff;
> +       rx_status.vendor_radiotap_oui[2] = 0xff;
> +       rx_status.vendor_radiotap_subns = 129;
> +       rx_status.vendor_radiotap_bitmap = 0x1;
> +
> +       *vendor_data++ = 1;
> +       *vendor_data++ = 2;
> +       *vendor_data++ = 3;
> +       *vendor_data++ = 4;
> +

Heh nice, now we just need a sample radiotap vendor extension parser example.

Thanks!!!

  Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux