aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211.c140
-rw-r--r--net/mac80211/ieee80211_i.h1
2 files changed, 118 insertions, 23 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 8b57eaa2a271..85f23fd866ad 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -57,6 +57,17 @@ static const unsigned char eapol_header[] =
57 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; 57 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
58 58
59 59
60/*
61 * For seeing transmitted packets on monitor interfaces
62 * we have a radiotap header too.
63 */
64struct ieee80211_tx_status_rtap_hdr {
65 struct ieee80211_radiotap_header hdr;
66 __le16 tx_flags;
67 u8 data_retries;
68} __attribute__ ((packed));
69
70
60static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata, 71static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata,
61 struct ieee80211_hdr *hdr) 72 struct ieee80211_hdr *hdr)
62{ 73{
@@ -529,7 +540,7 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
529 /* reserve enough extra head and tail room for possible 540 /* reserve enough extra head and tail room for possible
530 * encryption */ 541 * encryption */
531 frag = frags[i] = 542 frag = frags[i] =
532 dev_alloc_skb(tx->local->hw.extra_tx_headroom + 543 dev_alloc_skb(tx->local->tx_headroom +
533 frag_threshold + 544 frag_threshold +
534 IEEE80211_ENCRYPT_HEADROOM + 545 IEEE80211_ENCRYPT_HEADROOM +
535 IEEE80211_ENCRYPT_TAILROOM); 546 IEEE80211_ENCRYPT_TAILROOM);
@@ -538,8 +549,8 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
538 /* Make sure that all fragments use the same priority so 549 /* Make sure that all fragments use the same priority so
539 * that they end up using the same TX queue */ 550 * that they end up using the same TX queue */
540 frag->priority = first->priority; 551 frag->priority = first->priority;
541 skb_reserve(frag, tx->local->hw.extra_tx_headroom + 552 skb_reserve(frag, tx->local->tx_headroom +
542 IEEE80211_ENCRYPT_HEADROOM); 553 IEEE80211_ENCRYPT_HEADROOM);
543 fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); 554 fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen);
544 memcpy(fhdr, first->data, hdrlen); 555 memcpy(fhdr, first->data, hdrlen);
545 if (i == num_fragm - 2) 556 if (i == num_fragm - 2)
@@ -1636,8 +1647,7 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb,
1636 } 1647 }
1637 osdata = IEEE80211_DEV_TO_SUB_IF(odev); 1648 osdata = IEEE80211_DEV_TO_SUB_IF(odev);
1638 1649
1639 headroom = osdata->local->hw.extra_tx_headroom + 1650 headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM;
1640 IEEE80211_ENCRYPT_HEADROOM;
1641 if (skb_headroom(skb) < headroom) { 1651 if (skb_headroom(skb) < headroom) {
1642 if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { 1652 if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
1643 dev_kfree_skb(skb); 1653 dev_kfree_skb(skb);
@@ -1833,7 +1843,7 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,
1833 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and 1843 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and
1834 * alloc_skb() (net/core/skbuff.c) 1844 * alloc_skb() (net/core/skbuff.c)
1835 */ 1845 */
1836 head_need = hdrlen + encaps_len + local->hw.extra_tx_headroom; 1846 head_need = hdrlen + encaps_len + local->tx_headroom;
1837 head_need -= skb_headroom(skb); 1847 head_need -= skb_headroom(skb);
1838 1848
1839 /* We are going to modify skb data, so make a copy of it if happens to 1849 /* We are going to modify skb data, so make a copy of it if happens to
@@ -1920,9 +1930,9 @@ ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
1920 return 0; 1930 return 0;
1921 } 1931 }
1922 1932
1923 if (skb_headroom(skb) < sdata->local->hw.extra_tx_headroom) { 1933 if (skb_headroom(skb) < sdata->local->tx_headroom) {
1924 if (pskb_expand_head(skb, 1934 if (pskb_expand_head(skb, sdata->local->tx_headroom,
1925 sdata->local->hw.extra_tx_headroom, 0, GFP_ATOMIC)) { 1935 0, GFP_ATOMIC)) {
1926 dev_kfree_skb(skb); 1936 dev_kfree_skb(skb);
1927 return 0; 1937 return 0;
1928 } 1938 }
@@ -2061,12 +2071,12 @@ struct sk_buff * ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
2061 bh_len = ap->beacon_head_len; 2071 bh_len = ap->beacon_head_len;
2062 bt_len = ap->beacon_tail_len; 2072 bt_len = ap->beacon_tail_len;
2063 2073
2064 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 2074 skb = dev_alloc_skb(local->tx_headroom +
2065 bh_len + bt_len + 256 /* maximum TIM len */); 2075 bh_len + bt_len + 256 /* maximum TIM len */);
2066 if (!skb) 2076 if (!skb)
2067 return NULL; 2077 return NULL;
2068 2078
2069 skb_reserve(skb, local->hw.extra_tx_headroom); 2079 skb_reserve(skb, local->tx_headroom);
2070 memcpy(skb_put(skb, bh_len), b_head, bh_len); 2080 memcpy(skb_put(skb, bh_len), b_head, bh_len);
2071 2081
2072 ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data); 2082 ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data);
@@ -4498,6 +4508,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
4498 struct ieee80211_local *local = hw_to_local(hw); 4508 struct ieee80211_local *local = hw_to_local(hw);
4499 u16 frag, type; 4509 u16 frag, type;
4500 u32 msg_type; 4510 u32 msg_type;
4511 struct ieee80211_tx_status_rtap_hdr *rthdr;
4512 struct ieee80211_sub_if_data *sdata;
4513 int monitors;
4501 4514
4502 if (!status) { 4515 if (!status) {
4503 printk(KERN_ERR 4516 printk(KERN_ERR
@@ -4609,27 +4622,100 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
4609 local->dot11FailedCount++; 4622 local->dot11FailedCount++;
4610 } 4623 }
4611 4624
4612 if (!(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) 4625 msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ?
4613 || unlikely(!local->apdev)) { 4626 ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail;
4627
4628 /* this was a transmitted frame, but now we want to reuse it */
4629 skb_orphan(skb);
4630
4631 if ((status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) &&
4632 local->apdev) {
4633 if (local->monitors) {
4634 skb2 = skb_clone(skb, GFP_ATOMIC);
4635 } else {
4636 skb2 = skb;
4637 skb = NULL;
4638 }
4639
4640 if (skb2)
4641 /* Send frame to hostapd */
4642 ieee80211_rx_mgmt(local, skb2, NULL, msg_type);
4643
4644 if (!skb)
4645 return;
4646 }
4647
4648 if (!local->monitors) {
4614 dev_kfree_skb(skb); 4649 dev_kfree_skb(skb);
4615 return; 4650 return;
4616 } 4651 }
4617 4652
4618 msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ? 4653 /* send frame to monitor interfaces now */
4619 ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail;
4620 4654
4621 /* skb was the original skb used for TX. Clone it and give the clone 4655 if (skb_headroom(skb) < sizeof(*rthdr)) {
4622 * to netif_rx(). Free original skb. */ 4656 printk(KERN_ERR "ieee80211_tx_status: headroom too small\n");
4623 skb2 = skb_copy(skb, GFP_ATOMIC);
4624 if (!skb2) {
4625 dev_kfree_skb(skb); 4657 dev_kfree_skb(skb);
4626 return; 4658 return;
4627 } 4659 }
4628 dev_kfree_skb(skb);
4629 skb = skb2;
4630 4660
4631 /* Send frame to hostapd */ 4661 rthdr = (struct ieee80211_tx_status_rtap_hdr*)
4632 ieee80211_rx_mgmt(local, skb, NULL, msg_type); 4662 skb_push(skb, sizeof(*rthdr));
4663
4664 memset(rthdr, 0, sizeof(*rthdr));
4665 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
4666 rthdr->hdr.it_present =
4667 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
4668 (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
4669
4670 if (!(status->flags & IEEE80211_TX_STATUS_ACK) &&
4671 !is_multicast_ether_addr(hdr->addr1))
4672 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
4673
4674 if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
4675 (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT))
4676 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
4677 else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS)
4678 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
4679
4680 rthdr->data_retries = status->retry_count;
4681
4682 read_lock(&local->sub_if_lock);
4683 monitors = local->monitors;
4684 list_for_each_entry(sdata, &local->sub_if_list, list) {
4685 /*
4686 * Using the monitors counter is possibly racy, but
4687 * if the value is wrong we simply either clone the skb
4688 * once too much or forget sending it to one monitor iface
4689 * The latter case isn't nice but fixing the race is much
4690 * more complicated.
4691 */
4692 if (!monitors || !skb)
4693 goto out;
4694
4695 if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
4696 if (!netif_running(sdata->dev))
4697 continue;
4698 monitors--;
4699 if (monitors)
4700 skb2 = skb_clone(skb, GFP_KERNEL);
4701 else
4702 skb2 = NULL;
4703 skb->dev = sdata->dev;
4704 /* XXX: is this sufficient for BPF? */
4705 skb_set_mac_header(skb, 0);
4706 skb->ip_summed = CHECKSUM_UNNECESSARY;
4707 skb->pkt_type = PACKET_OTHERHOST;
4708 skb->protocol = htons(ETH_P_802_2);
4709 memset(skb->cb, 0, sizeof(skb->cb));
4710 netif_rx(skb);
4711 skb = skb2;
4712 break;
4713 }
4714 }
4715 out:
4716 read_unlock(&local->sub_if_lock);
4717 if (skb)
4718 dev_kfree_skb(skb);
4633} 4719}
4634EXPORT_SYMBOL(ieee80211_tx_status); 4720EXPORT_SYMBOL(ieee80211_tx_status);
4635 4721
@@ -4926,6 +5012,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
4926 goto fail_workqueue; 5012 goto fail_workqueue;
4927 } 5013 }
4928 5014
5015 /*
5016 * The hardware needs headroom for sending the frame,
5017 * and we need some headroom for passing the frame to monitor
5018 * interfaces, but never both at the same time.
5019 */
5020 local->tx_headroom = max(local->hw.extra_tx_headroom,
5021 sizeof(struct ieee80211_tx_status_rtap_hdr));
5022
4929 debugfs_hw_add(local); 5023 debugfs_hw_add(local);
4930 5024
4931 local->hw.conf.beacon_int = 1000; 5025 local->hw.conf.beacon_int = 1000;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index af4d14d0b969..5a91e179efa0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -392,6 +392,7 @@ struct ieee80211_local {
392 int monitors; 392 int monitors;
393 struct iw_statistics wstats; 393 struct iw_statistics wstats;
394 u8 wstats_flags; 394 u8 wstats_flags;
395 int tx_headroom; /* required headroom for hardware/radiotap */
395 396
396 enum { 397 enum {
397 IEEE80211_DEV_UNINITIALIZED = 0, 398 IEEE80211_DEV_UNINITIALIZED = 0,