aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-16 06:00:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:16 -0500
commitaf2ced6a32dafb71d21b726c06df57fc574093d7 (patch)
tree001775c68ec09aad0d8f93a5e8234c13f4e84eb3
parentc951ad3550ab40071bb0f222ba6125845769c08a (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.c47
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