diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 503 |
1 files changed, 330 insertions, 173 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa0f37e4afe4..aa41e382bbb3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -538,20 +538,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | |||
538 | int index, | 538 | int index, |
539 | struct sk_buff_head *frames) | 539 | struct sk_buff_head *frames) |
540 | { | 540 | { |
541 | struct ieee80211_supported_band *sband; | ||
542 | struct ieee80211_rate *rate = NULL; | ||
543 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 541 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
544 | struct ieee80211_rx_status *status; | ||
545 | 542 | ||
546 | if (!skb) | 543 | if (!skb) |
547 | goto no_frame; | 544 | goto no_frame; |
548 | 545 | ||
549 | status = IEEE80211_SKB_RXCB(skb); | 546 | /* release the frame from the reorder ring buffer */ |
550 | |||
551 | /* release the reordered frames to stack */ | ||
552 | sband = hw->wiphy->bands[status->band]; | ||
553 | if (!(status->flag & RX_FLAG_HT)) | ||
554 | rate = &sband->bitrates[status->rate_idx]; | ||
555 | tid_agg_rx->stored_mpdu_num--; | 547 | tid_agg_rx->stored_mpdu_num--; |
556 | tid_agg_rx->reorder_buf[index] = NULL; | 548 | tid_agg_rx->reorder_buf[index] = NULL; |
557 | __skb_queue_tail(frames, skb); | 549 | __skb_queue_tail(frames, skb); |
@@ -580,9 +572,80 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
580 | * frames that have not yet been received are assumed to be lost and the skb | 572 | * frames that have not yet been received are assumed to be lost and the skb |
581 | * can be released for processing. This may also release other skb's from the | 573 | * can be released for processing. This may also release other skb's from the |
582 | * reorder buffer if there are no additional gaps between the frames. | 574 | * reorder buffer if there are no additional gaps between the frames. |
575 | * | ||
576 | * Callers must hold tid_agg_rx->reorder_lock. | ||
583 | */ | 577 | */ |
584 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 578 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
585 | 579 | ||
580 | static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | ||
581 | struct tid_ampdu_rx *tid_agg_rx, | ||
582 | struct sk_buff_head *frames) | ||
583 | { | ||
584 | int index, j; | ||
585 | |||
586 | /* release the buffer until next missing frame */ | ||
587 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
588 | tid_agg_rx->buf_size; | ||
589 | if (!tid_agg_rx->reorder_buf[index] && | ||
590 | tid_agg_rx->stored_mpdu_num > 1) { | ||
591 | /* | ||
592 | * No buffers ready to be released, but check whether any | ||
593 | * frames in the reorder buffer have timed out. | ||
594 | */ | ||
595 | int skipped = 1; | ||
596 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | ||
597 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
598 | if (!tid_agg_rx->reorder_buf[j]) { | ||
599 | skipped++; | ||
600 | continue; | ||
601 | } | ||
602 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | ||
603 | HT_RX_REORDER_BUF_TIMEOUT)) | ||
604 | goto set_release_timer; | ||
605 | |||
606 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
607 | if (net_ratelimit()) | ||
608 | printk(KERN_DEBUG "%s: release an RX reorder " | ||
609 | "frame due to timeout on earlier " | ||
610 | "frames\n", | ||
611 | wiphy_name(hw->wiphy)); | ||
612 | #endif | ||
613 | ieee80211_release_reorder_frame(hw, tid_agg_rx, | ||
614 | j, frames); | ||
615 | |||
616 | /* | ||
617 | * Increment the head seq# also for the skipped slots. | ||
618 | */ | ||
619 | tid_agg_rx->head_seq_num = | ||
620 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; | ||
621 | skipped = 0; | ||
622 | } | ||
623 | } else while (tid_agg_rx->reorder_buf[index]) { | ||
624 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); | ||
625 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
626 | tid_agg_rx->buf_size; | ||
627 | } | ||
628 | |||
629 | if (tid_agg_rx->stored_mpdu_num) { | ||
630 | j = index = seq_sub(tid_agg_rx->head_seq_num, | ||
631 | tid_agg_rx->ssn) % tid_agg_rx->buf_size; | ||
632 | |||
633 | for (; j != (index - 1) % tid_agg_rx->buf_size; | ||
634 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
635 | if (tid_agg_rx->reorder_buf[j]) | ||
636 | break; | ||
637 | } | ||
638 | |||
639 | set_release_timer: | ||
640 | |||
641 | mod_timer(&tid_agg_rx->reorder_timer, | ||
642 | tid_agg_rx->reorder_time[j] + | ||
643 | HT_RX_REORDER_BUF_TIMEOUT); | ||
644 | } else { | ||
645 | del_timer(&tid_agg_rx->reorder_timer); | ||
646 | } | ||
647 | } | ||
648 | |||
586 | /* | 649 | /* |
587 | * As this function belongs to the RX path it must be under | 650 | * As this function belongs to the RX path it must be under |
588 | * rcu_read_lock protection. It returns false if the frame | 651 | * rcu_read_lock protection. It returns false if the frame |
@@ -598,14 +661,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
598 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | 661 | u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; |
599 | u16 head_seq_num, buf_size; | 662 | u16 head_seq_num, buf_size; |
600 | int index; | 663 | int index; |
664 | bool ret = true; | ||
601 | 665 | ||
602 | buf_size = tid_agg_rx->buf_size; | 666 | buf_size = tid_agg_rx->buf_size; |
603 | head_seq_num = tid_agg_rx->head_seq_num; | 667 | head_seq_num = tid_agg_rx->head_seq_num; |
604 | 668 | ||
669 | spin_lock(&tid_agg_rx->reorder_lock); | ||
605 | /* frame with out of date sequence number */ | 670 | /* frame with out of date sequence number */ |
606 | if (seq_less(mpdu_seq_num, head_seq_num)) { | 671 | if (seq_less(mpdu_seq_num, head_seq_num)) { |
607 | dev_kfree_skb(skb); | 672 | dev_kfree_skb(skb); |
608 | return true; | 673 | goto out; |
609 | } | 674 | } |
610 | 675 | ||
611 | /* | 676 | /* |
@@ -626,7 +691,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
626 | /* check if we already stored this frame */ | 691 | /* check if we already stored this frame */ |
627 | if (tid_agg_rx->reorder_buf[index]) { | 692 | if (tid_agg_rx->reorder_buf[index]) { |
628 | dev_kfree_skb(skb); | 693 | dev_kfree_skb(skb); |
629 | return true; | 694 | goto out; |
630 | } | 695 | } |
631 | 696 | ||
632 | /* | 697 | /* |
@@ -636,58 +701,19 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
636 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && | 701 | if (mpdu_seq_num == tid_agg_rx->head_seq_num && |
637 | tid_agg_rx->stored_mpdu_num == 0) { | 702 | tid_agg_rx->stored_mpdu_num == 0) { |
638 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 703 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
639 | return false; | 704 | ret = false; |
705 | goto out; | ||
640 | } | 706 | } |
641 | 707 | ||
642 | /* put the frame in the reordering buffer */ | 708 | /* put the frame in the reordering buffer */ |
643 | tid_agg_rx->reorder_buf[index] = skb; | 709 | tid_agg_rx->reorder_buf[index] = skb; |
644 | tid_agg_rx->reorder_time[index] = jiffies; | 710 | tid_agg_rx->reorder_time[index] = jiffies; |
645 | tid_agg_rx->stored_mpdu_num++; | 711 | tid_agg_rx->stored_mpdu_num++; |
646 | /* release the buffer until next missing frame */ | 712 | ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); |
647 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
648 | tid_agg_rx->buf_size; | ||
649 | if (!tid_agg_rx->reorder_buf[index] && | ||
650 | tid_agg_rx->stored_mpdu_num > 1) { | ||
651 | /* | ||
652 | * No buffers ready to be released, but check whether any | ||
653 | * frames in the reorder buffer have timed out. | ||
654 | */ | ||
655 | int j; | ||
656 | int skipped = 1; | ||
657 | for (j = (index + 1) % tid_agg_rx->buf_size; j != index; | ||
658 | j = (j + 1) % tid_agg_rx->buf_size) { | ||
659 | if (!tid_agg_rx->reorder_buf[j]) { | ||
660 | skipped++; | ||
661 | continue; | ||
662 | } | ||
663 | if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + | ||
664 | HT_RX_REORDER_BUF_TIMEOUT)) | ||
665 | break; | ||
666 | |||
667 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
668 | if (net_ratelimit()) | ||
669 | printk(KERN_DEBUG "%s: release an RX reorder " | ||
670 | "frame due to timeout on earlier " | ||
671 | "frames\n", | ||
672 | wiphy_name(hw->wiphy)); | ||
673 | #endif | ||
674 | ieee80211_release_reorder_frame(hw, tid_agg_rx, | ||
675 | j, frames); | ||
676 | 713 | ||
677 | /* | 714 | out: |
678 | * Increment the head seq# also for the skipped slots. | 715 | spin_unlock(&tid_agg_rx->reorder_lock); |
679 | */ | 716 | return ret; |
680 | tid_agg_rx->head_seq_num = | ||
681 | (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; | ||
682 | skipped = 0; | ||
683 | } | ||
684 | } else while (tid_agg_rx->reorder_buf[index]) { | ||
685 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); | ||
686 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | ||
687 | tid_agg_rx->buf_size; | ||
688 | } | ||
689 | |||
690 | return true; | ||
691 | } | 717 | } |
692 | 718 | ||
693 | /* | 719 | /* |
@@ -873,6 +899,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
873 | 899 | ||
874 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 900 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { |
875 | rx->key = stakey; | 901 | rx->key = stakey; |
902 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
903 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
904 | return RX_CONTINUE; | ||
876 | /* Skip decryption if the frame is not protected. */ | 905 | /* Skip decryption if the frame is not protected. */ |
877 | if (!ieee80211_has_protected(fc)) | 906 | if (!ieee80211_has_protected(fc)) |
878 | return RX_CONTINUE; | 907 | return RX_CONTINUE; |
@@ -935,7 +964,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
935 | * pairwise or station-to-station keys, but for WEP we allow | 964 | * pairwise or station-to-station keys, but for WEP we allow |
936 | * using a key index as well. | 965 | * using a key index as well. |
937 | */ | 966 | */ |
938 | if (rx->key && rx->key->conf.alg != ALG_WEP && | 967 | if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && |
968 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
939 | !is_multicast_ether_addr(hdr->addr1)) | 969 | !is_multicast_ether_addr(hdr->addr1)) |
940 | rx->key = NULL; | 970 | rx->key = NULL; |
941 | } | 971 | } |
@@ -951,8 +981,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
951 | return RX_DROP_UNUSABLE; | 981 | return RX_DROP_UNUSABLE; |
952 | /* the hdr variable is invalid now! */ | 982 | /* the hdr variable is invalid now! */ |
953 | 983 | ||
954 | switch (rx->key->conf.alg) { | 984 | switch (rx->key->conf.cipher) { |
955 | case ALG_WEP: | 985 | case WLAN_CIPHER_SUITE_WEP40: |
986 | case WLAN_CIPHER_SUITE_WEP104: | ||
956 | /* Check for weak IVs if possible */ | 987 | /* Check for weak IVs if possible */ |
957 | if (rx->sta && ieee80211_is_data(fc) && | 988 | if (rx->sta && ieee80211_is_data(fc) && |
958 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | 989 | (!(status->flag & RX_FLAG_IV_STRIPPED) || |
@@ -962,13 +993,13 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
962 | 993 | ||
963 | result = ieee80211_crypto_wep_decrypt(rx); | 994 | result = ieee80211_crypto_wep_decrypt(rx); |
964 | break; | 995 | break; |
965 | case ALG_TKIP: | 996 | case WLAN_CIPHER_SUITE_TKIP: |
966 | result = ieee80211_crypto_tkip_decrypt(rx); | 997 | result = ieee80211_crypto_tkip_decrypt(rx); |
967 | break; | 998 | break; |
968 | case ALG_CCMP: | 999 | case WLAN_CIPHER_SUITE_CCMP: |
969 | result = ieee80211_crypto_ccmp_decrypt(rx); | 1000 | result = ieee80211_crypto_ccmp_decrypt(rx); |
970 | break; | 1001 | break; |
971 | case ALG_AES_CMAC: | 1002 | case WLAN_CIPHER_SUITE_AES_CMAC: |
972 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | 1003 | result = ieee80211_crypto_aes_cmac_decrypt(rx); |
973 | break; | 1004 | break; |
974 | } | 1005 | } |
@@ -1265,7 +1296,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1265 | /* This is the first fragment of a new frame. */ | 1296 | /* This is the first fragment of a new frame. */ |
1266 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, | 1297 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |
1267 | rx->queue, &(rx->skb)); | 1298 | rx->queue, &(rx->skb)); |
1268 | if (rx->key && rx->key->conf.alg == ALG_CCMP && | 1299 | if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && |
1269 | ieee80211_has_protected(fc)) { | 1300 | ieee80211_has_protected(fc)) { |
1270 | int queue = ieee80211_is_mgmt(fc) ? | 1301 | int queue = ieee80211_is_mgmt(fc) ? |
1271 | NUM_RX_DATA_QUEUES : rx->queue; | 1302 | NUM_RX_DATA_QUEUES : rx->queue; |
@@ -1294,7 +1325,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1294 | int i; | 1325 | int i; |
1295 | u8 pn[CCMP_PN_LEN], *rpn; | 1326 | u8 pn[CCMP_PN_LEN], *rpn; |
1296 | int queue; | 1327 | int queue; |
1297 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) | 1328 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) |
1298 | return RX_DROP_UNUSABLE; | 1329 | return RX_DROP_UNUSABLE; |
1299 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 1330 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); |
1300 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 1331 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { |
@@ -1909,13 +1940,36 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | |||
1909 | } | 1940 | } |
1910 | 1941 | ||
1911 | static ieee80211_rx_result debug_noinline | 1942 | static ieee80211_rx_result debug_noinline |
1943 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | ||
1944 | { | ||
1945 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | ||
1946 | |||
1947 | /* | ||
1948 | * From here on, look only at management frames. | ||
1949 | * Data and control frames are already handled, | ||
1950 | * and unknown (reserved) frames are useless. | ||
1951 | */ | ||
1952 | if (rx->skb->len < 24) | ||
1953 | return RX_DROP_MONITOR; | ||
1954 | |||
1955 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | ||
1956 | return RX_DROP_MONITOR; | ||
1957 | |||
1958 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | ||
1959 | return RX_DROP_MONITOR; | ||
1960 | |||
1961 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
1962 | return RX_DROP_UNUSABLE; | ||
1963 | |||
1964 | return RX_CONTINUE; | ||
1965 | } | ||
1966 | |||
1967 | static ieee80211_rx_result debug_noinline | ||
1912 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | 1968 | ieee80211_rx_h_action(struct ieee80211_rx_data *rx) |
1913 | { | 1969 | { |
1914 | struct ieee80211_local *local = rx->local; | 1970 | struct ieee80211_local *local = rx->local; |
1915 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1971 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1916 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1972 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1917 | struct sk_buff *nskb; | ||
1918 | struct ieee80211_rx_status *status; | ||
1919 | int len = rx->skb->len; | 1973 | int len = rx->skb->len; |
1920 | 1974 | ||
1921 | if (!ieee80211_is_action(mgmt->frame_control)) | 1975 | if (!ieee80211_is_action(mgmt->frame_control)) |
@@ -1931,9 +1985,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1931 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1985 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
1932 | return RX_DROP_UNUSABLE; | 1986 | return RX_DROP_UNUSABLE; |
1933 | 1987 | ||
1934 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
1935 | return RX_DROP_UNUSABLE; | ||
1936 | |||
1937 | switch (mgmt->u.action.category) { | 1988 | switch (mgmt->u.action.category) { |
1938 | case WLAN_CATEGORY_BACK: | 1989 | case WLAN_CATEGORY_BACK: |
1939 | /* | 1990 | /* |
@@ -2024,17 +2075,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2024 | goto queue; | 2075 | goto queue; |
2025 | } | 2076 | } |
2026 | 2077 | ||
2078 | return RX_CONTINUE; | ||
2079 | |||
2027 | invalid: | 2080 | invalid: |
2028 | /* | 2081 | rx->flags |= IEEE80211_MALFORMED_ACTION_FRM; |
2029 | * For AP mode, hostapd is responsible for handling any action | 2082 | /* will return in the next handlers */ |
2030 | * frames that we didn't handle, including returning unknown | 2083 | return RX_CONTINUE; |
2031 | * ones. For all other modes we will return them to the sender, | 2084 | |
2032 | * setting the 0x80 bit in the action category, as required by | 2085 | handled: |
2033 | * 802.11-2007 7.3.1.11. | 2086 | if (rx->sta) |
2034 | */ | 2087 | rx->sta->rx_packets++; |
2035 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 2088 | dev_kfree_skb(rx->skb); |
2036 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 2089 | return RX_QUEUED; |
2037 | return RX_DROP_MONITOR; | 2090 | |
2091 | queue: | ||
2092 | rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; | ||
2093 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
2094 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2095 | if (rx->sta) | ||
2096 | rx->sta->rx_packets++; | ||
2097 | return RX_QUEUED; | ||
2098 | } | ||
2099 | |||
2100 | static ieee80211_rx_result debug_noinline | ||
2101 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | ||
2102 | { | ||
2103 | struct ieee80211_rx_status *status; | ||
2104 | |||
2105 | /* skip known-bad action frames and return them in the next handler */ | ||
2106 | if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM) | ||
2107 | return RX_CONTINUE; | ||
2038 | 2108 | ||
2039 | /* | 2109 | /* |
2040 | * Getting here means the kernel doesn't know how to handle | 2110 | * Getting here means the kernel doesn't know how to handle |
@@ -2044,10 +2114,44 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2044 | */ | 2114 | */ |
2045 | status = IEEE80211_SKB_RXCB(rx->skb); | 2115 | status = IEEE80211_SKB_RXCB(rx->skb); |
2046 | 2116 | ||
2047 | if (cfg80211_rx_action(rx->sdata->dev, status->freq, | 2117 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, |
2048 | rx->skb->data, rx->skb->len, | 2118 | rx->skb->data, rx->skb->len, |
2049 | GFP_ATOMIC)) | 2119 | GFP_ATOMIC)) { |
2050 | goto handled; | 2120 | if (rx->sta) |
2121 | rx->sta->rx_packets++; | ||
2122 | dev_kfree_skb(rx->skb); | ||
2123 | return RX_QUEUED; | ||
2124 | } | ||
2125 | |||
2126 | |||
2127 | return RX_CONTINUE; | ||
2128 | } | ||
2129 | |||
2130 | static ieee80211_rx_result debug_noinline | ||
2131 | ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | ||
2132 | { | ||
2133 | struct ieee80211_local *local = rx->local; | ||
2134 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | ||
2135 | struct sk_buff *nskb; | ||
2136 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
2137 | |||
2138 | if (!ieee80211_is_action(mgmt->frame_control)) | ||
2139 | return RX_CONTINUE; | ||
2140 | |||
2141 | /* | ||
2142 | * For AP mode, hostapd is responsible for handling any action | ||
2143 | * frames that we didn't handle, including returning unknown | ||
2144 | * ones. For all other modes we will return them to the sender, | ||
2145 | * setting the 0x80 bit in the action category, as required by | ||
2146 | * 802.11-2007 7.3.1.11. | ||
2147 | * Newer versions of hostapd shall also use the management frame | ||
2148 | * registration mechanisms, but older ones still use cooked | ||
2149 | * monitor interfaces so push all frames there. | ||
2150 | */ | ||
2151 | if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) && | ||
2152 | (sdata->vif.type == NL80211_IFTYPE_AP || | ||
2153 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
2154 | return RX_DROP_MONITOR; | ||
2051 | 2155 | ||
2052 | /* do not return rejected action frames */ | 2156 | /* do not return rejected action frames */ |
2053 | if (mgmt->u.action.category & 0x80) | 2157 | if (mgmt->u.action.category & 0x80) |
@@ -2066,20 +2170,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2066 | 2170 | ||
2067 | ieee80211_tx_skb(rx->sdata, nskb); | 2171 | ieee80211_tx_skb(rx->sdata, nskb); |
2068 | } | 2172 | } |
2069 | |||
2070 | handled: | ||
2071 | if (rx->sta) | ||
2072 | rx->sta->rx_packets++; | ||
2073 | dev_kfree_skb(rx->skb); | 2173 | dev_kfree_skb(rx->skb); |
2074 | return RX_QUEUED; | 2174 | return RX_QUEUED; |
2075 | |||
2076 | queue: | ||
2077 | rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; | ||
2078 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
2079 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2080 | if (rx->sta) | ||
2081 | rx->sta->rx_packets++; | ||
2082 | return RX_QUEUED; | ||
2083 | } | 2175 | } |
2084 | 2176 | ||
2085 | static ieee80211_rx_result debug_noinline | 2177 | static ieee80211_rx_result debug_noinline |
@@ -2090,15 +2182,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2090 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; | 2182 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; |
2091 | __le16 stype; | 2183 | __le16 stype; |
2092 | 2184 | ||
2093 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | ||
2094 | return RX_DROP_MONITOR; | ||
2095 | |||
2096 | if (rx->skb->len < 24) | ||
2097 | return RX_DROP_MONITOR; | ||
2098 | |||
2099 | if (ieee80211_drop_unencrypted_mgmt(rx)) | ||
2100 | return RX_DROP_UNUSABLE; | ||
2101 | |||
2102 | rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); | 2185 | rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); |
2103 | if (rxs != RX_CONTINUE) | 2186 | if (rxs != RX_CONTINUE) |
2104 | return rxs; | 2187 | return rxs; |
@@ -2267,19 +2350,46 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2267 | dev_kfree_skb(skb); | 2350 | dev_kfree_skb(skb); |
2268 | } | 2351 | } |
2269 | 2352 | ||
2353 | static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, | ||
2354 | ieee80211_rx_result res) | ||
2355 | { | ||
2356 | switch (res) { | ||
2357 | case RX_DROP_MONITOR: | ||
2358 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); | ||
2359 | if (rx->sta) | ||
2360 | rx->sta->rx_dropped++; | ||
2361 | /* fall through */ | ||
2362 | case RX_CONTINUE: { | ||
2363 | struct ieee80211_rate *rate = NULL; | ||
2364 | struct ieee80211_supported_band *sband; | ||
2365 | struct ieee80211_rx_status *status; | ||
2366 | |||
2367 | status = IEEE80211_SKB_RXCB((rx->skb)); | ||
2368 | |||
2369 | sband = rx->local->hw.wiphy->bands[status->band]; | ||
2370 | if (!(status->flag & RX_FLAG_HT)) | ||
2371 | rate = &sband->bitrates[status->rate_idx]; | ||
2372 | |||
2373 | ieee80211_rx_cooked_monitor(rx, rate); | ||
2374 | break; | ||
2375 | } | ||
2376 | case RX_DROP_UNUSABLE: | ||
2377 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); | ||
2378 | if (rx->sta) | ||
2379 | rx->sta->rx_dropped++; | ||
2380 | dev_kfree_skb(rx->skb); | ||
2381 | break; | ||
2382 | case RX_QUEUED: | ||
2383 | I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued); | ||
2384 | break; | ||
2385 | } | ||
2386 | } | ||
2270 | 2387 | ||
2271 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 2388 | static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, |
2272 | struct ieee80211_rx_data *rx, | 2389 | struct sk_buff_head *frames) |
2273 | struct sk_buff *skb, | ||
2274 | struct ieee80211_rate *rate) | ||
2275 | { | 2390 | { |
2276 | struct sk_buff_head reorder_release; | ||
2277 | ieee80211_rx_result res = RX_DROP_MONITOR; | 2391 | ieee80211_rx_result res = RX_DROP_MONITOR; |
2278 | 2392 | struct sk_buff *skb; | |
2279 | __skb_queue_head_init(&reorder_release); | ||
2280 | |||
2281 | rx->skb = skb; | ||
2282 | rx->sdata = sdata; | ||
2283 | 2393 | ||
2284 | #define CALL_RXH(rxh) \ | 2394 | #define CALL_RXH(rxh) \ |
2285 | do { \ | 2395 | do { \ |
@@ -2288,17 +2398,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
2288 | goto rxh_next; \ | 2398 | goto rxh_next; \ |
2289 | } while (0); | 2399 | } while (0); |
2290 | 2400 | ||
2291 | /* | 2401 | while ((skb = __skb_dequeue(frames))) { |
2292 | * NB: the rxh_next label works even if we jump | ||
2293 | * to it from here because then the list will | ||
2294 | * be empty, which is a trivial check | ||
2295 | */ | ||
2296 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2297 | CALL_RXH(ieee80211_rx_h_check) | ||
2298 | |||
2299 | ieee80211_rx_reorder_ampdu(rx, &reorder_release); | ||
2300 | |||
2301 | while ((skb = __skb_dequeue(&reorder_release))) { | ||
2302 | /* | 2402 | /* |
2303 | * all the other fields are valid across frames | 2403 | * all the other fields are valid across frames |
2304 | * that belong to an aMPDU since they are on the | 2404 | * that belong to an aMPDU since they are on the |
@@ -2316,42 +2416,91 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | |||
2316 | CALL_RXH(ieee80211_rx_h_remove_qos_control) | 2416 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
2317 | CALL_RXH(ieee80211_rx_h_amsdu) | 2417 | CALL_RXH(ieee80211_rx_h_amsdu) |
2318 | #ifdef CONFIG_MAC80211_MESH | 2418 | #ifdef CONFIG_MAC80211_MESH |
2319 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2419 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
2320 | CALL_RXH(ieee80211_rx_h_mesh_fwding); | 2420 | CALL_RXH(ieee80211_rx_h_mesh_fwding); |
2321 | #endif | 2421 | #endif |
2322 | CALL_RXH(ieee80211_rx_h_data) | 2422 | CALL_RXH(ieee80211_rx_h_data) |
2323 | 2423 | ||
2324 | /* special treatment -- needs the queue */ | 2424 | /* special treatment -- needs the queue */ |
2325 | res = ieee80211_rx_h_ctrl(rx, &reorder_release); | 2425 | res = ieee80211_rx_h_ctrl(rx, frames); |
2326 | if (res != RX_CONTINUE) | 2426 | if (res != RX_CONTINUE) |
2327 | goto rxh_next; | 2427 | goto rxh_next; |
2328 | 2428 | ||
2429 | CALL_RXH(ieee80211_rx_h_mgmt_check) | ||
2329 | CALL_RXH(ieee80211_rx_h_action) | 2430 | CALL_RXH(ieee80211_rx_h_action) |
2431 | CALL_RXH(ieee80211_rx_h_userspace_mgmt) | ||
2432 | CALL_RXH(ieee80211_rx_h_action_return) | ||
2330 | CALL_RXH(ieee80211_rx_h_mgmt) | 2433 | CALL_RXH(ieee80211_rx_h_mgmt) |
2331 | 2434 | ||
2435 | rxh_next: | ||
2436 | ieee80211_rx_handlers_result(rx, res); | ||
2437 | |||
2332 | #undef CALL_RXH | 2438 | #undef CALL_RXH |
2439 | } | ||
2440 | } | ||
2441 | |||
2442 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | ||
2443 | struct ieee80211_rx_data *rx, | ||
2444 | struct sk_buff *skb) | ||
2445 | { | ||
2446 | struct sk_buff_head reorder_release; | ||
2447 | ieee80211_rx_result res = RX_DROP_MONITOR; | ||
2448 | |||
2449 | __skb_queue_head_init(&reorder_release); | ||
2450 | |||
2451 | rx->skb = skb; | ||
2452 | rx->sdata = sdata; | ||
2453 | |||
2454 | #define CALL_RXH(rxh) \ | ||
2455 | do { \ | ||
2456 | res = rxh(rx); \ | ||
2457 | if (res != RX_CONTINUE) \ | ||
2458 | goto rxh_next; \ | ||
2459 | } while (0); | ||
2460 | |||
2461 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2462 | CALL_RXH(ieee80211_rx_h_check) | ||
2463 | |||
2464 | ieee80211_rx_reorder_ampdu(rx, &reorder_release); | ||
2465 | |||
2466 | ieee80211_rx_handlers(rx, &reorder_release); | ||
2467 | return; | ||
2333 | 2468 | ||
2334 | rxh_next: | 2469 | rxh_next: |
2335 | switch (res) { | 2470 | ieee80211_rx_handlers_result(rx, res); |
2336 | case RX_DROP_MONITOR: | 2471 | |
2337 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 2472 | #undef CALL_RXH |
2338 | if (rx->sta) | 2473 | } |
2339 | rx->sta->rx_dropped++; | 2474 | |
2340 | /* fall through */ | 2475 | /* |
2341 | case RX_CONTINUE: | 2476 | * This function makes calls into the RX path. Therefore the |
2342 | ieee80211_rx_cooked_monitor(rx, rate); | 2477 | * caller must hold the sta_info->lock and everything has to |
2343 | break; | 2478 | * be under rcu_read_lock protection as well. |
2344 | case RX_DROP_UNUSABLE: | 2479 | */ |
2345 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 2480 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) |
2346 | if (rx->sta) | 2481 | { |
2347 | rx->sta->rx_dropped++; | 2482 | struct sk_buff_head frames; |
2348 | dev_kfree_skb(rx->skb); | 2483 | struct ieee80211_rx_data rx = { }; |
2349 | break; | 2484 | |
2350 | case RX_QUEUED: | 2485 | __skb_queue_head_init(&frames); |
2351 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 2486 | |
2352 | break; | 2487 | /* construct rx struct */ |
2353 | } | 2488 | rx.sta = sta; |
2354 | } | 2489 | rx.sdata = sta->sdata; |
2490 | rx.local = sta->local; | ||
2491 | rx.queue = tid; | ||
2492 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2493 | |||
2494 | if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) || | ||
2495 | test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning))) | ||
2496 | rx.flags |= IEEE80211_RX_IN_SCAN; | ||
2497 | |||
2498 | spin_lock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); | ||
2499 | ieee80211_sta_reorder_release(&sta->local->hw, | ||
2500 | sta->ampdu_mlme.tid_rx[tid], &frames); | ||
2501 | spin_unlock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); | ||
2502 | |||
2503 | ieee80211_rx_handlers(&rx, &frames); | ||
2355 | } | 2504 | } |
2356 | 2505 | ||
2357 | /* main receive path */ | 2506 | /* main receive path */ |
@@ -2433,7 +2582,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2433 | break; | 2582 | break; |
2434 | case NL80211_IFTYPE_MONITOR: | 2583 | case NL80211_IFTYPE_MONITOR: |
2435 | case NL80211_IFTYPE_UNSPECIFIED: | 2584 | case NL80211_IFTYPE_UNSPECIFIED: |
2436 | case __NL80211_IFTYPE_AFTER_LAST: | 2585 | case NUM_NL80211_IFTYPES: |
2437 | /* should never get here */ | 2586 | /* should never get here */ |
2438 | WARN_ON(1); | 2587 | WARN_ON(1); |
2439 | break; | 2588 | break; |
@@ -2447,8 +2596,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2447 | * be called with rcu_read_lock protection. | 2596 | * be called with rcu_read_lock protection. |
2448 | */ | 2597 | */ |
2449 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2598 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2450 | struct sk_buff *skb, | 2599 | struct sk_buff *skb) |
2451 | struct ieee80211_rate *rate) | ||
2452 | { | 2600 | { |
2453 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2601 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2454 | struct ieee80211_local *local = hw_to_local(hw); | 2602 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -2556,7 +2704,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2556 | prev->name); | 2704 | prev->name); |
2557 | goto next; | 2705 | goto next; |
2558 | } | 2706 | } |
2559 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); | 2707 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); |
2560 | next: | 2708 | next: |
2561 | prev = sdata; | 2709 | prev = sdata; |
2562 | } | 2710 | } |
@@ -2572,7 +2720,7 @@ next: | |||
2572 | } | 2720 | } |
2573 | } | 2721 | } |
2574 | if (prev) | 2722 | if (prev) |
2575 | ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); | 2723 | ieee80211_invoke_rx_handlers(prev, &rx, skb); |
2576 | else | 2724 | else |
2577 | dev_kfree_skb(skb); | 2725 | dev_kfree_skb(skb); |
2578 | } | 2726 | } |
@@ -2615,28 +2763,37 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2615 | if (WARN_ON(!local->started)) | 2763 | if (WARN_ON(!local->started)) |
2616 | goto drop; | 2764 | goto drop; |
2617 | 2765 | ||
2618 | if (status->flag & RX_FLAG_HT) { | 2766 | if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { |
2619 | /* | 2767 | /* |
2620 | * rate_idx is MCS index, which can be [0-76] as documented on: | 2768 | * Validate the rate, unless a PLCP error means that |
2621 | * | 2769 | * we probably can't have a valid rate here anyway. |
2622 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n | ||
2623 | * | ||
2624 | * Anything else would be some sort of driver or hardware error. | ||
2625 | * The driver should catch hardware errors. | ||
2626 | */ | 2770 | */ |
2627 | if (WARN((status->rate_idx < 0 || | 2771 | |
2628 | status->rate_idx > 76), | 2772 | if (status->flag & RX_FLAG_HT) { |
2629 | "Rate marked as an HT rate but passed " | 2773 | /* |
2630 | "status->rate_idx is not " | 2774 | * rate_idx is MCS index, which can be [0-76] |
2631 | "an MCS index [0-76]: %d (0x%02x)\n", | 2775 | * as documented on: |
2632 | status->rate_idx, | 2776 | * |
2633 | status->rate_idx)) | 2777 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n |
2634 | goto drop; | 2778 | * |
2635 | } else { | 2779 | * Anything else would be some sort of driver or |
2636 | if (WARN_ON(status->rate_idx < 0 || | 2780 | * hardware error. The driver should catch hardware |
2637 | status->rate_idx >= sband->n_bitrates)) | 2781 | * errors. |
2638 | goto drop; | 2782 | */ |
2639 | rate = &sband->bitrates[status->rate_idx]; | 2783 | if (WARN((status->rate_idx < 0 || |
2784 | status->rate_idx > 76), | ||
2785 | "Rate marked as an HT rate but passed " | ||
2786 | "status->rate_idx is not " | ||
2787 | "an MCS index [0-76]: %d (0x%02x)\n", | ||
2788 | status->rate_idx, | ||
2789 | status->rate_idx)) | ||
2790 | goto drop; | ||
2791 | } else { | ||
2792 | if (WARN_ON(status->rate_idx < 0 || | ||
2793 | status->rate_idx >= sband->n_bitrates)) | ||
2794 | goto drop; | ||
2795 | rate = &sband->bitrates[status->rate_idx]; | ||
2796 | } | ||
2640 | } | 2797 | } |
2641 | 2798 | ||
2642 | /* | 2799 | /* |
@@ -2658,7 +2815,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2658 | return; | 2815 | return; |
2659 | } | 2816 | } |
2660 | 2817 | ||
2661 | __ieee80211_rx_handle_packet(hw, skb, rate); | 2818 | __ieee80211_rx_handle_packet(hw, skb); |
2662 | 2819 | ||
2663 | rcu_read_unlock(); | 2820 | rcu_read_unlock(); |
2664 | 2821 | ||