diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-11-16 06:00:39 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-18 17:09:16 -0500 |
commit | af2ced6a32dafb71d21b726c06df57fc574093d7 (patch) | |
tree | 001775c68ec09aad0d8f93a5e8234c13f4e84eb3 | |
parent | c951ad3550ab40071bb0f222ba6125845769c08a (diff) |
mac80211: push michael MIC report after DA check
When we receive a michael MIC failure report from the
hardware we currently do not check whether it is actually
reported on a frame that is destined to us. It shouldn't
be possible to get a michael MIC failure report on other
frames, but it also doesn't hurt to verify.
Also, since we then don't need the station struct that
early, move looking it up a bit later in the RX path.
Finally, while at it, a few code cleanups in the area.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/mac80211/rx.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6bce97ee2534..68d9e9c86595 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1818,11 +1818,11 @@ static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | |||
1818 | * Some hardware seem to generate incorrect Michael MIC | 1818 | * Some hardware seem to generate incorrect Michael MIC |
1819 | * reports; ignore them to avoid triggering countermeasures. | 1819 | * reports; ignore them to avoid triggering countermeasures. |
1820 | */ | 1820 | */ |
1821 | goto ignore; | 1821 | return; |
1822 | } | 1822 | } |
1823 | 1823 | ||
1824 | if (!ieee80211_has_protected(hdr->frame_control)) | 1824 | if (!ieee80211_has_protected(hdr->frame_control)) |
1825 | goto ignore; | 1825 | return; |
1826 | 1826 | ||
1827 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { | 1827 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { |
1828 | /* | 1828 | /* |
@@ -1831,18 +1831,15 @@ static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | |||
1831 | * group keys and only the AP is sending real multicast | 1831 | * group keys and only the AP is sending real multicast |
1832 | * frames in the BSS. | 1832 | * frames in the BSS. |
1833 | */ | 1833 | */ |
1834 | goto ignore; | 1834 | return; |
1835 | } | 1835 | } |
1836 | 1836 | ||
1837 | if (!ieee80211_is_data(hdr->frame_control) && | 1837 | if (!ieee80211_is_data(hdr->frame_control) && |
1838 | !ieee80211_is_auth(hdr->frame_control)) | 1838 | !ieee80211_is_auth(hdr->frame_control)) |
1839 | goto ignore; | 1839 | return; |
1840 | 1840 | ||
1841 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, | 1841 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, |
1842 | GFP_ATOMIC); | 1842 | GFP_ATOMIC); |
1843 | ignore: | ||
1844 | dev_kfree_skb(rx->skb); | ||
1845 | rx->skb = NULL; | ||
1846 | } | 1843 | } |
1847 | 1844 | ||
1848 | /* TODO: use IEEE80211_RX_FRAGMENTED */ | 1845 | /* TODO: use IEEE80211_RX_FRAGMENTED */ |
@@ -2064,8 +2061,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2064 | return 0; | 2061 | return 0; |
2065 | break; | 2062 | break; |
2066 | case NL80211_IFTYPE_MONITOR: | 2063 | case NL80211_IFTYPE_MONITOR: |
2067 | /* take everything */ | ||
2068 | break; | ||
2069 | case NL80211_IFTYPE_UNSPECIFIED: | 2064 | case NL80211_IFTYPE_UNSPECIFIED: |
2070 | case __NL80211_IFTYPE_AFTER_LAST: | 2065 | case __NL80211_IFTYPE_AFTER_LAST: |
2071 | /* should never get here */ | 2066 | /* should never get here */ |
@@ -2097,24 +2092,12 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2097 | memset(&rx, 0, sizeof(rx)); | 2092 | memset(&rx, 0, sizeof(rx)); |
2098 | rx.skb = skb; | 2093 | rx.skb = skb; |
2099 | rx.local = local; | 2094 | rx.local = local; |
2100 | |||
2101 | rx.status = status; | 2095 | rx.status = status; |
2102 | rx.rate = rate; | 2096 | rx.rate = rate; |
2103 | 2097 | ||
2104 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) | 2098 | if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) |
2105 | local->dot11ReceivedFragmentCount++; | 2099 | local->dot11ReceivedFragmentCount++; |
2106 | 2100 | ||
2107 | rx.sta = sta_info_get(local, hdr->addr2); | ||
2108 | if (rx.sta) { | ||
2109 | rx.sdata = rx.sta->sdata; | ||
2110 | rx.dev = rx.sta->sdata->dev; | ||
2111 | } | ||
2112 | |||
2113 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { | ||
2114 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2115 | return; | ||
2116 | } | ||
2117 | |||
2118 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2101 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2119 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2102 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2120 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2103 | rx.flags |= IEEE80211_RX_IN_SCAN; |
@@ -2122,13 +2105,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2122 | ieee80211_parse_qos(&rx); | 2105 | ieee80211_parse_qos(&rx); |
2123 | ieee80211_verify_alignment(&rx); | 2106 | ieee80211_verify_alignment(&rx); |
2124 | 2107 | ||
2125 | skb = rx.skb; | 2108 | rx.sta = sta_info_get(local, hdr->addr2); |
2109 | if (rx.sta) { | ||
2110 | rx.sdata = rx.sta->sdata; | ||
2111 | rx.dev = rx.sta->sdata->dev; | ||
2112 | } | ||
2126 | 2113 | ||
2127 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { | 2114 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { |
2128 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2115 | rx.flags |= IEEE80211_RX_RA_MATCH; |
2129 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | 2116 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); |
2130 | if (prepares) | 2117 | if (prepares) { |
2131 | prev = rx.sdata; | 2118 | if (status->flag & RX_FLAG_MMIC_ERROR) { |
2119 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2120 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2121 | } else | ||
2122 | prev = rx.sdata; | ||
2123 | } | ||
2132 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 2124 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
2133 | if (!netif_running(sdata->dev)) | 2125 | if (!netif_running(sdata->dev)) |
2134 | continue; | 2126 | continue; |
@@ -2143,6 +2135,13 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2143 | if (!prepares) | 2135 | if (!prepares) |
2144 | continue; | 2136 | continue; |
2145 | 2137 | ||
2138 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2139 | rx.sdata = sdata; | ||
2140 | if (rx.flags & IEEE80211_RX_RA_MATCH) | ||
2141 | ieee80211_rx_michael_mic_report(hdr, &rx); | ||
2142 | continue; | ||
2143 | } | ||
2144 | |||
2146 | /* | 2145 | /* |
2147 | * frame is destined for this interface, but if it's not | 2146 | * frame is destined for this interface, but if it's not |
2148 | * also for the previous one we handle that after the | 2147 | * also for the previous one we handle that after the |