rx.c (4c532321bf90288dae6b07a3f52279bfde842a80) rx.c (9179dff82598ab8b4e88dcc93c9e26a2594efd1a)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2002-2005, Instant802 Networks, Inc.
4 * Copyright 2005-2006, Devicescape Software, Inc.
5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH

--- 41 unchanged lines hidden (view full) ---

50
51 if (present_fcs_len)
52 __pskb_trim(skb, skb->len - present_fcs_len);
53 pskb_pull(skb, rtap_space);
54
55 /* After pulling radiotap header, clear all flags that indicate
56 * info in skb->data.
57 */
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2002-2005, Instant802 Networks, Inc.
4 * Copyright 2005-2006, Devicescape Software, Inc.
5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH

--- 41 unchanged lines hidden (view full) ---

50
51 if (present_fcs_len)
52 __pskb_trim(skb, skb->len - present_fcs_len);
53 pskb_pull(skb, rtap_space);
54
55 /* After pulling radiotap header, clear all flags that indicate
56 * info in skb->data.
57 */
58 status->flag &= ~(RX_FLAG_RADIOTAP_VENDOR_DATA |
58 status->flag &= ~(RX_FLAG_RADIOTAP_TLV_AT_END |
59 RX_FLAG_RADIOTAP_LSIG |
60 RX_FLAG_RADIOTAP_HE_MU |
61 RX_FLAG_RADIOTAP_HE);
62
63 hdr = (void *)skb->data;
64 fc = hdr->frame_control;
65
66 /*

--- 54 unchanged lines hidden (view full) ---

121 int len;
122
123 /* always present fields */
124 len = sizeof(struct ieee80211_radiotap_header) + 8;
125
126 /* allocate extra bitmaps */
127 if (status->chains)
128 len += 4 * hweight8(status->chains);
59 RX_FLAG_RADIOTAP_LSIG |
60 RX_FLAG_RADIOTAP_HE_MU |
61 RX_FLAG_RADIOTAP_HE);
62
63 hdr = (void *)skb->data;
64 fc = hdr->frame_control;
65
66 /*

--- 54 unchanged lines hidden (view full) ---

121 int len;
122
123 /* always present fields */
124 len = sizeof(struct ieee80211_radiotap_header) + 8;
125
126 /* allocate extra bitmaps */
127 if (status->chains)
128 len += 4 * hweight8(status->chains);
129 /* vendor presence bitmap */
130 if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)
131 len += 4;
132
133 if (ieee80211_have_rx_timestamp(status)) {
134 len = ALIGN(len, 8);
135 len += 8;
136 }
137 if (ieee80211_hw_check(&local->hw, SIGNAL_DBM))
138 len += 1;
139

--- 45 unchanged lines hidden (view full) ---

185 BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) != 4);
186 }
187
188 if (status->chains) {
189 /* antenna and antenna signal fields */
190 len += 2 * hweight8(status->chains);
191 }
192
129
130 if (ieee80211_have_rx_timestamp(status)) {
131 len = ALIGN(len, 8);
132 len += 8;
133 }
134 if (ieee80211_hw_check(&local->hw, SIGNAL_DBM))
135 len += 1;
136

--- 45 unchanged lines hidden (view full) ---

182 BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) != 4);
183 }
184
185 if (status->chains) {
186 /* antenna and antenna signal fields */
187 len += 2 * hweight8(status->chains);
188 }
189
193 if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
194 struct ieee80211_vendor_radiotap *rtap;
195 int vendor_data_offset = 0;
190 if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) {
191 int tlv_offset = 0;
196
197 /*
198 * The position to look at depends on the existence (or non-
199 * existence) of other elements, so take that into account...
200 */
201 if (status->flag & RX_FLAG_RADIOTAP_HE)
192
193 /*
194 * The position to look at depends on the existence (or non-
195 * existence) of other elements, so take that into account...
196 */
197 if (status->flag & RX_FLAG_RADIOTAP_HE)
202 vendor_data_offset +=
198 tlv_offset +=
203 sizeof(struct ieee80211_radiotap_he);
204 if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
199 sizeof(struct ieee80211_radiotap_he);
200 if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
205 vendor_data_offset +=
201 tlv_offset +=
206 sizeof(struct ieee80211_radiotap_he_mu);
207 if (status->flag & RX_FLAG_RADIOTAP_LSIG)
202 sizeof(struct ieee80211_radiotap_he_mu);
203 if (status->flag & RX_FLAG_RADIOTAP_LSIG)
208 vendor_data_offset +=
204 tlv_offset +=
209 sizeof(struct ieee80211_radiotap_lsig);
210
205 sizeof(struct ieee80211_radiotap_lsig);
206
211 rtap = (void *)&skb->data[vendor_data_offset];
207 /* ensure 4 byte alignment for TLV */
208 len = ALIGN(len, 4);
212
209
213 /* alignment for fixed 6-byte vendor data header */
214 len = ALIGN(len, 2);
215 /* vendor data header */
216 len += 6;
217 if (WARN_ON(rtap->align == 0))
218 rtap->align = 1;
219 len = ALIGN(len, rtap->align);
220 len += rtap->len + rtap->pad;
210 /* TLVs until the mac header */
211 len += skb_mac_header(skb) - &skb->data[tlv_offset];
221 }
222
223 return len;
224}
225
226static void __ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
227 int link_id,
228 struct sta_info *sta,

--- 79 unchanged lines hidden (view full) ---

308{
309 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
310 struct ieee80211_radiotap_header *rthdr;
311 unsigned char *pos;
312 __le32 *it_present;
313 u32 it_present_val;
314 u16 rx_flags = 0;
315 u16 channel_flags = 0;
212 }
213
214 return len;
215}
216
217static void __ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
218 int link_id,
219 struct sta_info *sta,

--- 79 unchanged lines hidden (view full) ---

299{
300 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
301 struct ieee80211_radiotap_header *rthdr;
302 unsigned char *pos;
303 __le32 *it_present;
304 u32 it_present_val;
305 u16 rx_flags = 0;
306 u16 channel_flags = 0;
307 u32 tlvs_len = 0;
316 int mpdulen, chain;
317 unsigned long chains = status->chains;
308 int mpdulen, chain;
309 unsigned long chains = status->chains;
318 struct ieee80211_vendor_radiotap rtap = {};
319 struct ieee80211_radiotap_he he = {};
320 struct ieee80211_radiotap_he_mu he_mu = {};
321 struct ieee80211_radiotap_lsig lsig = {};
322
323 if (status->flag & RX_FLAG_RADIOTAP_HE) {
324 he = *(struct ieee80211_radiotap_he *)skb->data;
325 skb_pull(skb, sizeof(he));
326 WARN_ON_ONCE(status->encoding != RX_ENC_HE);

--- 4 unchanged lines hidden (view full) ---

331 skb_pull(skb, sizeof(he_mu));
332 }
333
334 if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
335 lsig = *(struct ieee80211_radiotap_lsig *)skb->data;
336 skb_pull(skb, sizeof(lsig));
337 }
338
310 struct ieee80211_radiotap_he he = {};
311 struct ieee80211_radiotap_he_mu he_mu = {};
312 struct ieee80211_radiotap_lsig lsig = {};
313
314 if (status->flag & RX_FLAG_RADIOTAP_HE) {
315 he = *(struct ieee80211_radiotap_he *)skb->data;
316 skb_pull(skb, sizeof(he));
317 WARN_ON_ONCE(status->encoding != RX_ENC_HE);

--- 4 unchanged lines hidden (view full) ---

322 skb_pull(skb, sizeof(he_mu));
323 }
324
325 if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
326 lsig = *(struct ieee80211_radiotap_lsig *)skb->data;
327 skb_pull(skb, sizeof(lsig));
328 }
329
339 if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
340 rtap = *(struct ieee80211_vendor_radiotap *)skb->data;
341 /* rtap.len and rtap.pad are undone immediately */
342 skb_pull(skb, sizeof(rtap) + rtap.len + rtap.pad);
330 if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) {
331 /* data is pointer at tlv all other info was pulled off */
332 tlvs_len = skb_mac_header(skb) - skb->data;
343 }
344
345 mpdulen = skb->len;
346 if (!(has_fcs && ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)))
347 mpdulen += FCS_LEN;
348
333 }
334
335 mpdulen = skb->len;
336 if (!(has_fcs && ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)))
337 mpdulen += FCS_LEN;
338
349 rthdr = skb_push(skb, rtap_len);
350 memset(rthdr, 0, rtap_len - rtap.len - rtap.pad);
339 rthdr = skb_push(skb, rtap_len - tlvs_len);
340 memset(rthdr, 0, rtap_len - tlvs_len);
351 it_present = &rthdr->it_present;
352
353 /* radiotap header, set always present flags */
354 rthdr->it_len = cpu_to_le16(rtap_len);
355 it_present_val = BIT(IEEE80211_RADIOTAP_FLAGS) |
356 BIT(IEEE80211_RADIOTAP_CHANNEL) |
357 BIT(IEEE80211_RADIOTAP_RX_FLAGS);
358

--- 5 unchanged lines hidden (view full) ---

364 BIT(IEEE80211_RADIOTAP_EXT) |
365 BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
366 put_unaligned_le32(it_present_val, it_present);
367 it_present++;
368 it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) |
369 BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
370 }
371
341 it_present = &rthdr->it_present;
342
343 /* radiotap header, set always present flags */
344 rthdr->it_len = cpu_to_le16(rtap_len);
345 it_present_val = BIT(IEEE80211_RADIOTAP_FLAGS) |
346 BIT(IEEE80211_RADIOTAP_CHANNEL) |
347 BIT(IEEE80211_RADIOTAP_RX_FLAGS);
348

--- 5 unchanged lines hidden (view full) ---

354 BIT(IEEE80211_RADIOTAP_EXT) |
355 BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
356 put_unaligned_le32(it_present_val, it_present);
357 it_present++;
358 it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) |
359 BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
360 }
361
372 if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
373 it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |
374 BIT(IEEE80211_RADIOTAP_EXT);
375 put_unaligned_le32(it_present_val, it_present);
376 it_present++;
377 it_present_val = rtap.present;
378 }
362 if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END)
363 it_present_val |= BIT(IEEE80211_RADIOTAP_TLV);
379
380 put_unaligned_le32(it_present_val, it_present);
381
382 /* This references through an offset into it_optional[] rather
383 * than via it_present otherwise later uses of pos will cause
384 * the compiler to think we have walked past the end of the
385 * struct member.
386 */

--- 314 unchanged lines hidden (view full) ---

701 memcpy(pos, &lsig, sizeof(lsig));
702 pos += sizeof(lsig);
703 }
704
705 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
706 *pos++ = status->chain_signal[chain];
707 *pos++ = chain;
708 }
364
365 put_unaligned_le32(it_present_val, it_present);
366
367 /* This references through an offset into it_optional[] rather
368 * than via it_present otherwise later uses of pos will cause
369 * the compiler to think we have walked past the end of the
370 * struct member.
371 */

--- 314 unchanged lines hidden (view full) ---

686 memcpy(pos, &lsig, sizeof(lsig));
687 pos += sizeof(lsig);
688 }
689
690 for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
691 *pos++ = status->chain_signal[chain];
692 *pos++ = chain;
693 }
709
710 if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
711 /* ensure 2 byte alignment for the vendor field as required */
712 if ((pos - (u8 *)rthdr) & 1)
713 *pos++ = 0;
714 *pos++ = rtap.oui[0];
715 *pos++ = rtap.oui[1];
716 *pos++ = rtap.oui[2];
717 *pos++ = rtap.subns;
718 put_unaligned_le16(rtap.len, pos);
719 pos += 2;
720 /* align the actual payload as requested */
721 while ((pos - (u8 *)rthdr) & (rtap.align - 1))
722 *pos++ = 0;
723 /* data (and possible padding) already follows */
724 }
725}
726
727static struct sk_buff *
728ieee80211_make_monitor_skb(struct ieee80211_local *local,
729 struct sk_buff **origskb,
730 struct ieee80211_rate *rate,
731 int rtap_space, bool use_origskb)
732{

--- 59 unchanged lines hidden (view full) ---

792 struct sk_buff *monskb = NULL;
793 int present_fcs_len = 0;
794 unsigned int rtap_space = 0;
795 struct ieee80211_sub_if_data *monitor_sdata =
796 rcu_dereference(local->monitor_sdata);
797 bool only_monitor = false;
798 unsigned int min_head_len;
799
694}
695
696static struct sk_buff *
697ieee80211_make_monitor_skb(struct ieee80211_local *local,
698 struct sk_buff **origskb,
699 struct ieee80211_rate *rate,
700 int rtap_space, bool use_origskb)
701{

--- 59 unchanged lines hidden (view full) ---

761 struct sk_buff *monskb = NULL;
762 int present_fcs_len = 0;
763 unsigned int rtap_space = 0;
764 struct ieee80211_sub_if_data *monitor_sdata =
765 rcu_dereference(local->monitor_sdata);
766 bool only_monitor = false;
767 unsigned int min_head_len;
768
769 if (WARN_ON_ONCE(status->flag & RX_FLAG_RADIOTAP_TLV_AT_END &&
770 !skb_mac_header_was_set(origskb))) {
771 /* with this skb no way to know where frame payload starts */
772 dev_kfree_skb(origskb);
773 return NULL;
774 }
775
800 if (status->flag & RX_FLAG_RADIOTAP_HE)
801 rtap_space += sizeof(struct ieee80211_radiotap_he);
802
803 if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
804 rtap_space += sizeof(struct ieee80211_radiotap_he_mu);
805
806 if (status->flag & RX_FLAG_RADIOTAP_LSIG)
807 rtap_space += sizeof(struct ieee80211_radiotap_lsig);
808
776 if (status->flag & RX_FLAG_RADIOTAP_HE)
777 rtap_space += sizeof(struct ieee80211_radiotap_he);
778
779 if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
780 rtap_space += sizeof(struct ieee80211_radiotap_he_mu);
781
782 if (status->flag & RX_FLAG_RADIOTAP_LSIG)
783 rtap_space += sizeof(struct ieee80211_radiotap_lsig);
784
809 if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
810 struct ieee80211_vendor_radiotap *rtap =
811 (void *)(origskb->data + rtap_space);
785 if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END)
786 rtap_space += skb_mac_header(origskb) - &origskb->data[rtap_space];
812
787
813 rtap_space += sizeof(*rtap) + rtap->len + rtap->pad;
814 }
815
816 min_head_len = rtap_space;
817
818 /*
819 * First, we may need to make a copy of the skb because
820 * (1) we need to modify it for radiotap (if not present), and
821 * (2) the other RX handlers will modify the skb we got.
822 *
823 * We don't need to, of course, if we aren't going to return

--- 4512 unchanged lines hidden ---
788 min_head_len = rtap_space;
789
790 /*
791 * First, we may need to make a copy of the skb because
792 * (1) we need to modify it for radiotap (if not present), and
793 * (2) the other RX handlers will modify the skb we got.
794 *
795 * We don't need to, of course, if we aren't going to return

--- 4512 unchanged lines hidden ---