1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/slab.h>
3 #include <linux/export.h>
4 #include <linux/etherdevice.h>
6 #include "hostap_80211.h"
7 #include "hostap_common.h"
8 #include "hostap_wlan.h"
10 #include "hostap_ap.h"
12 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
13 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
14 static unsigned char rfc1042_header
[] =
15 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
16 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
17 static unsigned char bridge_tunnel_header
[] =
18 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
19 /* No encapsulation header if EtherType < 0x600 (=length) */
21 void hostap_dump_tx_80211(const char *name
, struct sk_buff
*skb
)
23 struct ieee80211_hdr
*hdr
;
26 hdr
= (struct ieee80211_hdr
*) skb
->data
;
28 printk(KERN_DEBUG
"%s: TX len=%d jiffies=%ld\n",
29 name
, skb
->len
, jiffies
);
34 fc
= le16_to_cpu(hdr
->frame_control
);
35 printk(KERN_DEBUG
" FC=0x%04x (type=%d:%d)%s%s",
36 fc
, (fc
& IEEE80211_FCTL_FTYPE
) >> 2,
37 (fc
& IEEE80211_FCTL_STYPE
) >> 4,
38 fc
& IEEE80211_FCTL_TODS
? " [ToDS]" : "",
39 fc
& IEEE80211_FCTL_FROMDS
? " [FromDS]" : "");
41 if (skb
->len
< IEEE80211_DATA_HDR3_LEN
) {
46 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr
->duration_id
),
47 le16_to_cpu(hdr
->seq_ctrl
));
49 printk(KERN_DEBUG
" A1=%pM", hdr
->addr1
);
50 printk(" A2=%pM", hdr
->addr2
);
51 printk(" A3=%pM", hdr
->addr3
);
53 printk(" A4=%pM", hdr
->addr4
);
58 /* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
59 * Convert Ethernet header into a suitable IEEE 802.11 header depending on
60 * device configuration. */
61 netdev_tx_t
hostap_data_start_xmit(struct sk_buff
*skb
,
62 struct net_device
*dev
)
64 struct hostap_interface
*iface
;
66 int need_headroom
, need_tailroom
= 0;
67 struct ieee80211_hdr hdr
;
68 u16 fc
, ethertype
= 0;
70 WDS_NO
= 0, WDS_OWN_FRAME
, WDS_COMPLIANT_FRAME
73 int hdr_len
, encaps_len
, skip_header_bytes
;
75 struct hostap_skb_tx_data
*meta
;
77 iface
= netdev_priv(dev
);
80 if (skb
->len
< ETH_HLEN
) {
81 printk(KERN_DEBUG
"%s: hostap_data_start_xmit: short skb "
82 "(len=%d)\n", dev
->name
, skb
->len
);
87 if (local
->ddev
!= dev
) {
88 use_wds
= (local
->iw_mode
== IW_MODE_MASTER
&&
89 !(local
->wds_type
& HOSTAP_WDS_STANDARD_FRAME
)) ?
90 WDS_OWN_FRAME
: WDS_COMPLIANT_FRAME
;
91 if (dev
== local
->stadev
) {
94 } else if (dev
== local
->apdev
) {
95 printk(KERN_DEBUG
"%s: prism2_tx: trying to use "
96 "AP device with Ethernet net dev\n", dev
->name
);
101 if (local
->iw_mode
== IW_MODE_REPEAT
) {
102 printk(KERN_DEBUG
"%s: prism2_tx: trying to use "
103 "non-WDS link in Repeater mode\n", dev
->name
);
106 } else if (local
->iw_mode
== IW_MODE_INFRA
&&
107 (local
->wds_type
& HOSTAP_WDS_AP_CLIENT
) &&
108 !ether_addr_equal(skb
->data
+ ETH_ALEN
, dev
->dev_addr
)) {
109 /* AP client mode: send frames with foreign src addr
110 * using 4-addr WDS frames */
111 use_wds
= WDS_COMPLIANT_FRAME
;
115 /* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload
117 * Prism2 TX frame with 802.11 header:
118 * txdesc (address order depending on used mode; includes dst_addr and
119 * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel;
120 * proto[2], payload {, possible addr4[6]} */
122 ethertype
= (skb
->data
[12] << 8) | skb
->data
[13];
124 memset(&hdr
, 0, sizeof(hdr
));
126 /* Length of data after IEEE 802.11 header */
129 skip_header_bytes
= ETH_HLEN
;
130 if (ethertype
== ETH_P_AARP
|| ethertype
== ETH_P_IPX
) {
131 encaps_data
= bridge_tunnel_header
;
132 encaps_len
= sizeof(bridge_tunnel_header
);
133 skip_header_bytes
-= 2;
134 } else if (ethertype
>= 0x600) {
135 encaps_data
= rfc1042_header
;
136 encaps_len
= sizeof(rfc1042_header
);
137 skip_header_bytes
-= 2;
140 fc
= IEEE80211_FTYPE_DATA
| IEEE80211_STYPE_DATA
;
141 hdr_len
= IEEE80211_DATA_HDR3_LEN
;
143 if (use_wds
!= WDS_NO
) {
144 /* Note! Prism2 station firmware has problems with sending real
145 * 802.11 frames with four addresses; until these problems can
146 * be fixed or worked around, 4-addr frames needed for WDS are
147 * using incompatible format: FromDS flag is not set and the
148 * fourth address is added after the frame payload; it is
149 * assumed, that the receiving station knows how to handle this
152 if (use_wds
== WDS_COMPLIANT_FRAME
) {
153 fc
|= IEEE80211_FCTL_FROMDS
| IEEE80211_FCTL_TODS
;
154 /* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA,
156 skb_copy_from_linear_data_offset(skb
, ETH_ALEN
,
157 &hdr
.addr4
, ETH_ALEN
);
160 /* bogus 4-addr format to workaround Prism2 station
162 fc
|= IEEE80211_FCTL_TODS
;
163 /* From DS: Addr1 = DA (used as RA),
164 * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA),
167 /* SA from skb->data + ETH_ALEN will be added after
168 * frame payload; use hdr.addr4 as a temporary buffer
170 skb_copy_from_linear_data_offset(skb
, ETH_ALEN
,
171 &hdr
.addr4
, ETH_ALEN
);
172 need_tailroom
+= ETH_ALEN
;
175 /* send broadcast and multicast frames to broadcast RA, if
176 * configured; otherwise, use unicast RA of the WDS link */
177 if ((local
->wds_type
& HOSTAP_WDS_BROADCAST_RA
) &&
178 is_multicast_ether_addr(skb
->data
))
179 eth_broadcast_addr(hdr
.addr1
);
180 else if (iface
->type
== HOSTAP_INTERFACE_WDS
)
181 memcpy(&hdr
.addr1
, iface
->u
.wds
.remote_addr
,
184 memcpy(&hdr
.addr1
, local
->bssid
, ETH_ALEN
);
185 memcpy(&hdr
.addr2
, dev
->dev_addr
, ETH_ALEN
);
186 skb_copy_from_linear_data(skb
, &hdr
.addr3
, ETH_ALEN
);
187 } else if (local
->iw_mode
== IW_MODE_MASTER
&& !to_assoc_ap
) {
188 fc
|= IEEE80211_FCTL_FROMDS
;
189 /* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */
190 skb_copy_from_linear_data(skb
, &hdr
.addr1
, ETH_ALEN
);
191 memcpy(&hdr
.addr2
, dev
->dev_addr
, ETH_ALEN
);
192 skb_copy_from_linear_data_offset(skb
, ETH_ALEN
, &hdr
.addr3
,
194 } else if (local
->iw_mode
== IW_MODE_INFRA
|| to_assoc_ap
) {
195 fc
|= IEEE80211_FCTL_TODS
;
196 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
197 memcpy(&hdr
.addr1
, to_assoc_ap
?
198 local
->assoc_ap_addr
: local
->bssid
, ETH_ALEN
);
199 skb_copy_from_linear_data_offset(skb
, ETH_ALEN
, &hdr
.addr2
,
201 skb_copy_from_linear_data(skb
, &hdr
.addr3
, ETH_ALEN
);
202 } else if (local
->iw_mode
== IW_MODE_ADHOC
) {
203 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
204 skb_copy_from_linear_data(skb
, &hdr
.addr1
, ETH_ALEN
);
205 skb_copy_from_linear_data_offset(skb
, ETH_ALEN
, &hdr
.addr2
,
207 memcpy(&hdr
.addr3
, local
->bssid
, ETH_ALEN
);
210 hdr
.frame_control
= cpu_to_le16(fc
);
212 skb_pull(skb
, skip_header_bytes
);
213 need_headroom
= local
->func
->need_tx_headroom
+ hdr_len
+ encaps_len
;
214 if (skb_tailroom(skb
) < need_tailroom
) {
215 skb
= skb_unshare(skb
, GFP_ATOMIC
);
217 iface
->stats
.tx_dropped
++;
220 if (pskb_expand_head(skb
, need_headroom
, need_tailroom
,
223 iface
->stats
.tx_dropped
++;
226 } else if (skb_headroom(skb
) < need_headroom
) {
227 struct sk_buff
*tmp
= skb
;
228 skb
= skb_realloc_headroom(skb
, need_headroom
);
231 iface
->stats
.tx_dropped
++;
235 skb
= skb_unshare(skb
, GFP_ATOMIC
);
237 iface
->stats
.tx_dropped
++;
243 memcpy(skb_push(skb
, encaps_len
), encaps_data
, encaps_len
);
244 memcpy(skb_push(skb
, hdr_len
), &hdr
, hdr_len
);
245 if (use_wds
== WDS_OWN_FRAME
) {
246 skb_put_data(skb
, &hdr
.addr4
, ETH_ALEN
);
249 iface
->stats
.tx_packets
++;
250 iface
->stats
.tx_bytes
+= skb
->len
;
252 skb_reset_mac_header(skb
);
253 meta
= (struct hostap_skb_tx_data
*) skb
->cb
;
254 memset(meta
, 0, sizeof(*meta
));
255 meta
->magic
= HOSTAP_SKB_TX_DATA_MAGIC
;
257 meta
->flags
|= HOSTAP_TX_FLAGS_WDS
;
258 meta
->ethertype
= ethertype
;
261 /* Send IEEE 802.11 encapsulated frame using the master radio device */
262 skb
->dev
= local
->dev
;
268 /* hard_start_xmit function for hostapd wlan#ap interfaces */
269 netdev_tx_t
hostap_mgmt_start_xmit(struct sk_buff
*skb
,
270 struct net_device
*dev
)
272 struct hostap_interface
*iface
;
274 struct hostap_skb_tx_data
*meta
;
275 struct ieee80211_hdr
*hdr
;
278 iface
= netdev_priv(dev
);
279 local
= iface
->local
;
282 printk(KERN_DEBUG
"%s: hostap_mgmt_start_xmit: short skb "
283 "(len=%d)\n", dev
->name
, skb
->len
);
288 iface
->stats
.tx_packets
++;
289 iface
->stats
.tx_bytes
+= skb
->len
;
291 meta
= (struct hostap_skb_tx_data
*) skb
->cb
;
292 memset(meta
, 0, sizeof(*meta
));
293 meta
->magic
= HOSTAP_SKB_TX_DATA_MAGIC
;
296 if (skb
->len
>= IEEE80211_DATA_HDR3_LEN
+ sizeof(rfc1042_header
) + 2) {
297 hdr
= (struct ieee80211_hdr
*) skb
->data
;
298 fc
= le16_to_cpu(hdr
->frame_control
);
299 if (ieee80211_is_data(hdr
->frame_control
) &&
300 (fc
& IEEE80211_FCTL_STYPE
) == IEEE80211_STYPE_DATA
) {
301 u8
*pos
= &skb
->data
[IEEE80211_DATA_HDR3_LEN
+
302 sizeof(rfc1042_header
)];
303 meta
->ethertype
= (pos
[0] << 8) | pos
[1];
307 /* Send IEEE 802.11 encapsulated frame using the master radio device */
308 skb
->dev
= local
->dev
;
314 /* Called only from software IRQ */
315 static struct sk_buff
* hostap_tx_encrypt(struct sk_buff
*skb
,
316 struct lib80211_crypt_data
*crypt
)
318 struct hostap_interface
*iface
;
320 struct ieee80211_hdr
*hdr
;
321 int prefix_len
, postfix_len
, hdr_len
, res
;
323 iface
= netdev_priv(skb
->dev
);
324 local
= iface
->local
;
326 if (skb
->len
< IEEE80211_DATA_HDR3_LEN
) {
331 if (local
->tkip_countermeasures
&&
332 strcmp(crypt
->ops
->name
, "TKIP") == 0) {
333 hdr
= (struct ieee80211_hdr
*) skb
->data
;
334 if (net_ratelimit()) {
335 printk(KERN_DEBUG
"%s: TKIP countermeasures: dropped "
336 "TX packet to %pM\n",
337 local
->dev
->name
, hdr
->addr1
);
343 skb
= skb_unshare(skb
, GFP_ATOMIC
);
347 prefix_len
= crypt
->ops
->extra_mpdu_prefix_len
+
348 crypt
->ops
->extra_msdu_prefix_len
;
349 postfix_len
= crypt
->ops
->extra_mpdu_postfix_len
+
350 crypt
->ops
->extra_msdu_postfix_len
;
351 if ((skb_headroom(skb
) < prefix_len
||
352 skb_tailroom(skb
) < postfix_len
) &&
353 pskb_expand_head(skb
, prefix_len
, postfix_len
, GFP_ATOMIC
)) {
358 hdr
= (struct ieee80211_hdr
*) skb
->data
;
359 hdr_len
= hostap_80211_get_hdrlen(hdr
->frame_control
);
361 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
362 * call both MSDU and MPDU encryption functions from here. */
363 atomic_inc(&crypt
->refcnt
);
365 if (crypt
->ops
->encrypt_msdu
)
366 res
= crypt
->ops
->encrypt_msdu(skb
, hdr_len
, crypt
->priv
);
367 if (res
== 0 && crypt
->ops
->encrypt_mpdu
)
368 res
= crypt
->ops
->encrypt_mpdu(skb
, hdr_len
, crypt
->priv
);
369 atomic_dec(&crypt
->refcnt
);
379 /* hard_start_xmit function for master radio interface wifi#.
380 * AP processing (TX rate control, power save buffering, etc.).
381 * Use hardware TX function to send the frame. */
382 netdev_tx_t
hostap_master_start_xmit(struct sk_buff
*skb
,
383 struct net_device
*dev
)
385 struct hostap_interface
*iface
;
387 netdev_tx_t ret
= NETDEV_TX_BUSY
;
389 struct hostap_tx_data tx
;
391 struct hostap_skb_tx_data
*meta
;
393 struct ieee80211_hdr
*hdr
;
395 iface
= netdev_priv(dev
);
396 local
= iface
->local
;
401 meta
= (struct hostap_skb_tx_data
*) skb
->cb
;
402 if (meta
->magic
!= HOSTAP_SKB_TX_DATA_MAGIC
) {
403 printk(KERN_DEBUG
"%s: invalid skb->cb magic (0x%08x, "
404 "expected 0x%08x)\n",
405 dev
->name
, meta
->magic
, HOSTAP_SKB_TX_DATA_MAGIC
);
407 iface
->stats
.tx_dropped
++;
411 if (local
->host_encrypt
) {
412 /* Set crypt to default algorithm and key; will be replaced in
413 * AP code if STA has own alg/key */
414 tx
.crypt
= local
->crypt_info
.crypt
[local
->crypt_info
.tx_keyidx
];
422 printk(KERN_DEBUG
"%s: hostap_master_start_xmit: short skb "
423 "(len=%d)\n", dev
->name
, skb
->len
);
425 iface
->stats
.tx_dropped
++;
430 * Wi-Fi 802.11b test plan suggests that AP should ignore power save
431 * bit in authentication and (re)association frames and assume tha
432 * STA remains awake for the response. */
433 tx_ret
= hostap_handle_sta_tx(local
, &tx
);
435 meta
= (struct hostap_skb_tx_data
*) skb
->cb
;
436 hdr
= (struct ieee80211_hdr
*) skb
->data
;
437 fc
= le16_to_cpu(hdr
->frame_control
);
441 case AP_TX_CONTINUE_NOT_AUTHORIZED
:
442 if (local
->ieee_802_1x
&&
443 ieee80211_is_data(hdr
->frame_control
) &&
444 meta
->ethertype
!= ETH_P_PAE
&&
445 !(meta
->flags
& HOSTAP_TX_FLAGS_WDS
)) {
446 printk(KERN_DEBUG
"%s: dropped frame to unauthorized "
447 "port (IEEE 802.1X): ethertype=0x%04x\n",
448 dev
->name
, meta
->ethertype
);
449 hostap_dump_tx_80211(dev
->name
, skb
);
451 ret
= NETDEV_TX_OK
; /* drop packet */
452 iface
->stats
.tx_dropped
++;
457 ret
= NETDEV_TX_OK
; /* drop packet */
458 iface
->stats
.tx_dropped
++;
463 /* do not free skb here, it will be freed when the
464 * buffered frame is sent/timed out */
469 /* Request TX callback if protocol version is 2 in 802.11 header;
470 * this version 2 is a special case used between hostapd and kernel
472 if (((fc
& IEEE80211_FCTL_VERS
) == BIT(1)) &&
473 local
->ap
&& local
->ap
->tx_callback_idx
&& meta
->tx_cb_idx
== 0) {
474 meta
->tx_cb_idx
= local
->ap
->tx_callback_idx
;
476 /* remove special version from the frame header */
477 fc
&= ~IEEE80211_FCTL_VERS
;
478 hdr
->frame_control
= cpu_to_le16(fc
);
481 if (!ieee80211_is_data(hdr
->frame_control
)) {
486 if (local
->ieee_802_1x
&& meta
->ethertype
== ETH_P_PAE
&& tx
.crypt
&&
487 !(fc
& IEEE80211_FCTL_PROTECTED
)) {
489 PDEBUG(DEBUG_EXTRA2
, "%s: TX: IEEE 802.1X - passing "
490 "unencrypted EAPOL frame\n", dev
->name
);
491 tx
.crypt
= NULL
; /* no encryption for IEEE 802.1X frames */
494 if (tx
.crypt
&& (!tx
.crypt
->ops
|| !tx
.crypt
->ops
->encrypt_mpdu
))
496 else if ((tx
.crypt
||
497 local
->crypt_info
.crypt
[local
->crypt_info
.tx_keyidx
]) &&
499 /* Add ISWEP flag both for firmware and host based encryption
501 fc
|= IEEE80211_FCTL_PROTECTED
;
502 hdr
->frame_control
= cpu_to_le16(fc
);
503 } else if (local
->drop_unencrypted
&&
504 ieee80211_is_data(hdr
->frame_control
) &&
505 meta
->ethertype
!= ETH_P_PAE
) {
506 if (net_ratelimit()) {
507 printk(KERN_DEBUG
"%s: dropped unencrypted TX data "
508 "frame (drop_unencrypted=1)\n", dev
->name
);
510 iface
->stats
.tx_dropped
++;
516 skb
= hostap_tx_encrypt(skb
, tx
.crypt
);
518 printk(KERN_DEBUG
"%s: TX - encryption failed\n",
523 meta
= (struct hostap_skb_tx_data
*) skb
->cb
;
524 if (meta
->magic
!= HOSTAP_SKB_TX_DATA_MAGIC
) {
525 printk(KERN_DEBUG
"%s: invalid skb->cb magic (0x%08x, "
526 "expected 0x%08x) after hostap_tx_encrypt\n",
527 dev
->name
, meta
->magic
,
528 HOSTAP_SKB_TX_DATA_MAGIC
);
530 iface
->stats
.tx_dropped
++;
535 if (local
->func
->tx
== NULL
|| local
->func
->tx(skb
, dev
)) {
537 iface
->stats
.tx_dropped
++;
540 iface
->stats
.tx_packets
++;
541 iface
->stats
.tx_bytes
+= skb
->len
;
545 if (ret
== NETDEV_TX_OK
&& skb
)
549 hostap_handle_sta_release(tx
.sta_ptr
);
554 EXPORT_SYMBOL(hostap_master_start_xmit
);