Skip to content

Commit

Permalink
mac80211: fix radiotap header generation
Browse files Browse the repository at this point in the history
In

  commit 601ae7f
  Author: Bruno Randolf <br1@einfach.org>
  Date:   Thu May 8 19:22:43 2008 +0200

      mac80211: make rx radiotap header more flexible

code was added that tried to align the radiotap header
position in memory based on the radiotap header length.
Quite obviously, that is completely useless.

Instead of trying to do that, use unaligned accesses
to generate the radiotap header. To properly do that,
we also need to mark struct ieee80211_radiotap_header
packed, but that is fine since it's already packed
(and it should be marked packed anyway since its a
wire format).

Cc: Bruno Randolf <br1@einfach.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Oct 30, 2009
1 parent 4d36ec5 commit 6a86b9c
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 15 deletions.
2 changes: 1 addition & 1 deletion include/net/ieee80211_radiotap.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct ieee80211_radiotap_header {
* Additional extensions are made
* by setting bit 31.
*/
};
} __packed;

/* Name Data type Units
* ---- --------- -----
Expand Down
26 changes: 12 additions & 14 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
if (len & 1) /* padding for RX_FLAGS if necessary */
len++;

/* make sure radiotap starts at a naturally aligned address */
if (len % 8)
len = roundup(len, 8);

return len;
}

Expand All @@ -116,6 +112,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_radiotap_header *rthdr;
unsigned char *pos;
u16 rx_flags = 0;

rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
memset(rthdr, 0, rtap_len);
Expand All @@ -134,7 +131,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,

/* IEEE80211_RADIOTAP_TSFT */
if (status->flag & RX_FLAG_TSFT) {
*(__le64 *)pos = cpu_to_le64(status->mactime);
put_unaligned_le64(status->mactime, pos);
rthdr->it_present |=
cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
pos += 8;
Expand Down Expand Up @@ -166,17 +163,17 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos++;

/* IEEE80211_RADIOTAP_CHANNEL */
*(__le16 *)pos = cpu_to_le16(status->freq);
put_unaligned_le16(status->freq, pos);
pos += 2;
if (status->band == IEEE80211_BAND_5GHZ)
*(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
IEEE80211_CHAN_5GHZ);
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
pos);
else if (rate->flags & IEEE80211_RATE_ERP_G)
*(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
IEEE80211_CHAN_2GHZ);
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
pos);
else
*(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_CCK |
IEEE80211_CHAN_2GHZ);
put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
pos);
pos += 2;

/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
Expand Down Expand Up @@ -205,10 +202,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,

/* IEEE80211_RADIOTAP_RX_FLAGS */
/* ensure 2 byte alignment for the 2 byte field as required */
if ((pos - (unsigned char *)rthdr) & 1)
if ((pos - (u8 *)rthdr) & 1)
pos++;
if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
*(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADPLCP);
rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
put_unaligned_le16(rx_flags, pos);
pos += 2;
}

Expand Down

0 comments on commit 6a86b9c

Please sign in to comment.