summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c33
-rw-r--r--include/net/mac80211.h12
-rw-r--r--net/mac80211/rx.c71
3 files changed, 103 insertions, 13 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index ce522aa93af7..c242f5a9b8bc 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -751,7 +751,11 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
751 continue; 751 continue;
752 } 752 }
753 753
754 nskb = skb_copy(skb, GFP_ATOMIC); 754 /*
755 * reserve some space for our vendor and the normal
756 * radiotap header, since we're copying anyway
757 */
758 nskb = skb_copy_expand(skb, 64, 0, GFP_ATOMIC);
755 if (nskb == NULL) 759 if (nskb == NULL)
756 continue; 760 continue;
757 761
@@ -769,6 +773,33 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
769 (data->tsf_offset - data2->tsf_offset) + 773 (data->tsf_offset - data2->tsf_offset) +
770 24 * 8 * 10 / txrate->bitrate); 774 24 * 8 * 10 / txrate->bitrate);
771 775
776#if 0
777 /*
778 * Don't enable this code by default as the OUI 00:00:00
779 * is registered to Xerox so we shouldn't use it here, it
780 * might find its way into pcap files.
781 * Note that this code requires the headroom in the SKB
782 * that was allocated earlier.
783 */
784 rx_status.vendor_radiotap_oui[0] = 0x00;
785 rx_status.vendor_radiotap_oui[1] = 0x00;
786 rx_status.vendor_radiotap_oui[2] = 0x00;
787 rx_status.vendor_radiotap_subns = 127;
788 /*
789 * Radiotap vendor namespaces can (and should) also be
790 * split into fields by using the standard radiotap
791 * presence bitmap mechanism. Use just BIT(0) here for
792 * the presence bitmap.
793 */
794 rx_status.vendor_radiotap_bitmap = BIT(0);
795 /* We have 8 bytes of (dummy) data */
796 rx_status.vendor_radiotap_len = 8;
797 /* For testing, also require it to be aligned */
798 rx_status.vendor_radiotap_align = 8;
799 /* push the data */
800 memcpy(skb_push(nskb, 8), "ABCDEFGH", 8);
801#endif
802
772 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 803 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
773 ieee80211_rx_irqsafe(data2->hw, nskb); 804 ieee80211_rx_irqsafe(data2->hw, nskb);
774 } 805 }
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b484a6569eac..dd08fbb3cf28 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -789,12 +789,21 @@ enum mac80211_rx_flags {
789 * @ampdu_reference: A-MPDU reference number, must be a different value for 789 * @ampdu_reference: A-MPDU reference number, must be a different value for
790 * each A-MPDU but the same for each subframe within one A-MPDU 790 * each A-MPDU but the same for each subframe within one A-MPDU
791 * @ampdu_delimiter_crc: A-MPDU delimiter CRC 791 * @ampdu_delimiter_crc: A-MPDU delimiter CRC
792 * @vendor_radiotap_bitmap: radiotap vendor namespace presence bitmap
793 * @vendor_radiotap_len: radiotap vendor namespace length
794 * @vendor_radiotap_align: radiotap vendor namespace alignment. Note
795 * that the actual data must be at the start of the SKB data
796 * already.
797 * @vendor_radiotap_oui: radiotap vendor namespace OUI
798 * @vendor_radiotap_subns: radiotap vendor sub namespace
792 */ 799 */
793struct ieee80211_rx_status { 800struct ieee80211_rx_status {
794 u64 mactime; 801 u64 mactime;
795 u32 device_timestamp; 802 u32 device_timestamp;
796 u32 ampdu_reference; 803 u32 ampdu_reference;
797 u32 flag; 804 u32 flag;
805 u32 vendor_radiotap_bitmap;
806 u16 vendor_radiotap_len;
798 u16 freq; 807 u16 freq;
799 u8 rate_idx; 808 u8 rate_idx;
800 u8 rx_flags; 809 u8 rx_flags;
@@ -802,6 +811,9 @@ struct ieee80211_rx_status {
802 u8 antenna; 811 u8 antenna;
803 s8 signal; 812 s8 signal;
804 u8 ampdu_delimiter_crc; 813 u8 ampdu_delimiter_crc;
814 u8 vendor_radiotap_align;
815 u8 vendor_radiotap_oui[3];
816 u8 vendor_radiotap_subns;
805}; 817};
806 818
807/** 819/**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8480bbf1a707..ec15a4929f7a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -40,6 +40,8 @@
40static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, 40static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
41 struct sk_buff *skb) 41 struct sk_buff *skb)
42{ 42{
43 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
44
43 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 45 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
44 if (likely(skb->len > FCS_LEN)) 46 if (likely(skb->len > FCS_LEN))
45 __pskb_trim(skb, skb->len - FCS_LEN); 47 __pskb_trim(skb, skb->len - FCS_LEN);
@@ -51,6 +53,9 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
51 } 53 }
52 } 54 }
53 55
56 if (status->vendor_radiotap_len)
57 __pskb_pull(skb, status->vendor_radiotap_len);
58
54 return skb; 59 return skb;
55} 60}
56 61
@@ -73,32 +78,48 @@ static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
73} 78}
74 79
75static int 80static int
76ieee80211_rx_radiotap_len(struct ieee80211_local *local, 81ieee80211_rx_radiotap_space(struct ieee80211_local *local,
77 struct ieee80211_rx_status *status) 82 struct ieee80211_rx_status *status)
78{ 83{
79 int len; 84 int len;
80 85
81 /* always present fields */ 86 /* always present fields */
82 len = sizeof(struct ieee80211_radiotap_header) + 9; 87 len = sizeof(struct ieee80211_radiotap_header) + 9;
83 88
84 if (ieee80211_have_rx_timestamp(status)) 89 /* allocate extra bitmap */
90 if (status->vendor_radiotap_len)
91 len += 4;
92
93 if (ieee80211_have_rx_timestamp(status)) {
94 len = ALIGN(len, 8);
85 len += 8; 95 len += 8;
96 }
86 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 97 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
87 len += 1; 98 len += 1;
88 99
89 if (len & 1) /* padding for RX_FLAGS if necessary */ 100 /* padding for RX_FLAGS if necessary */
90 len++; 101 len = ALIGN(len, 2);
91 102
92 if (status->flag & RX_FLAG_HT) /* HT info */ 103 if (status->flag & RX_FLAG_HT) /* HT info */
93 len += 3; 104 len += 3;
94 105
95 if (status->flag & RX_FLAG_AMPDU_DETAILS) { 106 if (status->flag & RX_FLAG_AMPDU_DETAILS) {
96 /* padding */ 107 len = ALIGN(len, 4);
97 while (len & 3)
98 len++;
99 len += 8; 108 len += 8;
100 } 109 }
101 110
111 if (status->vendor_radiotap_len) {
112 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
113 status->vendor_radiotap_align = 1;
114 /* align standard part of vendor namespace */
115 len = ALIGN(len, 2);
116 /* allocate standard part of vendor namespace */
117 len += 6;
118 /* align vendor-defined part */
119 len = ALIGN(len, status->vendor_radiotap_align);
120 /* vendor-defined part is already in skb */
121 }
122
102 return len; 123 return len;
103} 124}
104 125
@@ -132,14 +153,25 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
132 (1 << IEEE80211_RADIOTAP_CHANNEL) | 153 (1 << IEEE80211_RADIOTAP_CHANNEL) |
133 (1 << IEEE80211_RADIOTAP_ANTENNA) | 154 (1 << IEEE80211_RADIOTAP_ANTENNA) |
134 (1 << IEEE80211_RADIOTAP_RX_FLAGS)); 155 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
135 rthdr->it_len = cpu_to_le16(rtap_len); 156 rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
136 157
137 pos = (unsigned char *)(rthdr + 1); 158 pos = (unsigned char *)(rthdr + 1);
138 159
160 if (status->vendor_radiotap_len) {
161 rthdr->it_present |=
162 cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
163 cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
164 put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
165 pos += 4;
166 }
167
139 /* the order of the following fields is important */ 168 /* the order of the following fields is important */
140 169
141 /* IEEE80211_RADIOTAP_TSFT */ 170 /* IEEE80211_RADIOTAP_TSFT */
142 if (ieee80211_have_rx_timestamp(status)) { 171 if (ieee80211_have_rx_timestamp(status)) {
172 /* padding */
173 while ((pos - (u8 *)rthdr) & 7)
174 *pos++ = 0;
143 put_unaligned_le64( 175 put_unaligned_le64(
144 ieee80211_calculate_rx_timestamp(local, status, 176 ieee80211_calculate_rx_timestamp(local, status,
145 mpdulen, 0), 177 mpdulen, 0),
@@ -211,7 +243,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
211 /* IEEE80211_RADIOTAP_RX_FLAGS */ 243 /* IEEE80211_RADIOTAP_RX_FLAGS */
212 /* ensure 2 byte alignment for the 2 byte field as required */ 244 /* ensure 2 byte alignment for the 2 byte field as required */
213 if ((pos - (u8 *)rthdr) & 1) 245 if ((pos - (u8 *)rthdr) & 1)
214 pos++; 246 *pos++ = 0;
215 if (status->flag & RX_FLAG_FAILED_PLCP_CRC) 247 if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
216 rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP; 248 rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
217 put_unaligned_le16(rx_flags, pos); 249 put_unaligned_le16(rx_flags, pos);
@@ -261,6 +293,21 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
261 *pos++ = 0; 293 *pos++ = 0;
262 *pos++ = 0; 294 *pos++ = 0;
263 } 295 }
296
297 if (status->vendor_radiotap_len) {
298 /* ensure 2 byte alignment for the vendor field as required */
299 if ((pos - (u8 *)rthdr) & 1)
300 *pos++ = 0;
301 *pos++ = status->vendor_radiotap_oui[0];
302 *pos++ = status->vendor_radiotap_oui[1];
303 *pos++ = status->vendor_radiotap_oui[2];
304 *pos++ = status->vendor_radiotap_subns;
305 put_unaligned_le16(status->vendor_radiotap_len, pos);
306 pos += 2;
307 /* align the actual payload as requested */
308 while ((pos - (u8 *)rthdr) & (status->vendor_radiotap_align - 1))
309 *pos++ = 0;
310 }
264} 311}
265 312
266/* 313/*
@@ -289,7 +336,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
289 */ 336 */
290 337
291 /* room for the radiotap header based on driver features */ 338 /* room for the radiotap header based on driver features */
292 needed_headroom = ieee80211_rx_radiotap_len(local, status); 339 needed_headroom = ieee80211_rx_radiotap_space(local, status);
293 340
294 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 341 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
295 present_fcs_len = FCS_LEN; 342 present_fcs_len = FCS_LEN;
@@ -2593,7 +2640,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2593 goto out_free_skb; 2640 goto out_free_skb;
2594 2641
2595 /* room for the radiotap header based on driver features */ 2642 /* room for the radiotap header based on driver features */
2596 needed_headroom = ieee80211_rx_radiotap_len(local, status); 2643 needed_headroom = ieee80211_rx_radiotap_space(local, status);
2597 2644
2598 if (skb_headroom(skb) < needed_headroom && 2645 if (skb_headroom(skb) < needed_headroom &&
2599 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) 2646 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))