1 #include <linux/slab.h>
2 #include <linux/export.h>
12 static unsigned char rfc1042_header[] =
13 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
15 static unsigned char bridge_tunnel_header[] =
16 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
62 struct hostap_interface *iface;
64 int need_headroom, need_tailroom = 0;
68 WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
71 int hdr_len, encaps_len, skip_header_bytes;
73 struct hostap_skb_tx_data *
meta;
75 iface = netdev_priv(dev);
80 "(len=%d)\n", dev->
name, skb->
len);
85 if (local->ddev != dev) {
87 !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ?
88 WDS_OWN_FRAME : WDS_COMPLIANT_FRAME;
89 if (dev == local->stadev) {
92 }
else if (dev == local->apdev) {
94 "AP device with Ethernet net dev\n", dev->
name);
101 "non-WDS link in Repeater mode\n", dev->
name);
105 (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
110 use_wds = WDS_COMPLIANT_FRAME;
121 ethertype = (skb->
data[12] << 8) | skb->
data[13];
123 memset(&hdr, 0,
sizeof(hdr));
130 encaps_data = bridge_tunnel_header;
131 encaps_len =
sizeof(bridge_tunnel_header);
132 skip_header_bytes -= 2;
133 }
else if (ethertype >= 0x600) {
134 encaps_data = rfc1042_header;
135 encaps_len =
sizeof(rfc1042_header);
136 skip_header_bytes -= 2;
142 if (use_wds != WDS_NO) {
151 if (use_wds == WDS_COMPLIANT_FRAME) {
155 skb_copy_from_linear_data_offset(skb,
ETH_ALEN,
169 skb_copy_from_linear_data_offset(skb,
ETH_ALEN,
176 if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) &&
179 else if (iface->type == HOSTAP_INTERFACE_WDS)
197 local->assoc_ap_addr : local->bssid,
ETH_ALEN);
212 need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
213 if (skb_tailroom(skb) < need_tailroom) {
216 iface->stats.tx_dropped++;
222 iface->stats.tx_dropped++;
225 }
else if (skb_headroom(skb) < need_headroom) {
230 iface->stats.tx_dropped++;
236 iface->stats.tx_dropped++;
244 if (use_wds == WDS_OWN_FRAME) {
248 iface->stats.tx_packets++;
249 iface->stats.tx_bytes += skb->
len;
251 skb_reset_mac_header(skb);
252 meta = (
struct hostap_skb_tx_data *) skb->cb;
253 memset(meta, 0,
sizeof(*meta));
254 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
256 meta->flags |= HOSTAP_TX_FLAGS_WDS;
271 struct hostap_interface *iface;
273 struct hostap_skb_tx_data *
meta;
277 iface = netdev_priv(dev);
278 local = iface->local;
282 "(len=%d)\n", dev->
name, skb->
len);
287 iface->stats.tx_packets++;
288 iface->stats.tx_bytes += skb->
len;
290 meta = (
struct hostap_skb_tx_data *) skb->cb;
291 memset(meta, 0,
sizeof(*meta));
292 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
301 sizeof(rfc1042_header)];
302 meta->ethertype = (pos[0] << 8) | pos[1];
317 struct hostap_interface *iface;
322 iface = netdev_priv(skb->
dev);
323 local = iface->local;
330 if (local->tkip_countermeasures &&
335 "TX packet to %pM\n",
346 prefix_len = crypt->
ops->extra_mpdu_prefix_len +
347 crypt->
ops->extra_msdu_prefix_len;
348 postfix_len = crypt->
ops->extra_mpdu_postfix_len +
349 crypt->
ops->extra_msdu_postfix_len;
350 if ((skb_headroom(skb) < prefix_len ||
351 skb_tailroom(skb) < postfix_len) &&
364 if (crypt->
ops->encrypt_msdu)
365 res = crypt->
ops->encrypt_msdu(skb, hdr_len, crypt->
priv);
366 if (res == 0 && crypt->
ops->encrypt_mpdu)
367 res = crypt->
ops->encrypt_mpdu(skb, hdr_len, crypt->
priv);
384 struct hostap_interface *iface;
390 struct hostap_skb_tx_data *
meta;
394 iface = netdev_priv(dev);
395 local = iface->local;
400 meta = (
struct hostap_skb_tx_data *) skb->cb;
401 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
403 "expected 0x%08x)\n",
404 dev->
name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
406 iface->stats.tx_dropped++;
410 if (local->host_encrypt) {
413 tx.
crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx];
422 "(len=%d)\n", dev->
name, skb->
len);
424 iface->stats.tx_dropped++;
434 meta = (
struct hostap_skb_tx_data *) skb->cb;
441 if (local->ieee_802_1x &&
444 !(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
446 "port (IEEE 802.1X): ethertype=0x%04x\n",
447 dev->
name, meta->ethertype);
451 iface->stats.tx_dropped++;
457 iface->stats.tx_dropped++;
472 local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) {
473 meta->tx_cb_idx = local->ap->tx_callback_idx;
476 fc &= ~IEEE80211_FCTL_VERS;
485 if (local->ieee_802_1x && meta->ethertype ==
ETH_P_PAE && tx.
crypt &&
488 PDEBUG(DEBUG_EXTRA2,
"%s: TX: IEEE 802.1X - passing "
489 "unencrypted EAPOL frame\n", dev->
name);
495 else if ((tx.
crypt ||
496 local->crypt_info.crypt[local->crypt_info.tx_keyidx]) &&
502 }
else if (local->drop_unencrypted &&
507 "frame (drop_unencrypted=1)\n", dev->
name);
509 iface->stats.tx_dropped++;
515 skb = hostap_tx_encrypt(skb, tx.
crypt);
522 meta = (
struct hostap_skb_tx_data *) skb->cb;
523 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
525 "expected 0x%08x) after hostap_tx_encrypt\n",
526 dev->
name, meta->magic,
527 HOSTAP_SKB_TX_DATA_MAGIC);
529 iface->stats.tx_dropped++;
534 if (local->func->tx ==
NULL || local->func->tx(skb, dev)) {
536 iface->stats.tx_dropped++;
539 iface->stats.tx_packets++;
540 iface->stats.tx_bytes += skb->
len;