aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
commit5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch)
treefa43345288d7b25fac92b3b35360a177c4947313 /net/mac80211/rx.c
parentfea069152614cdeefba4b2bf80afcddb9c217fc8 (diff)
parenta5e944f1d955f3819503348426763e21e0413ba6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ath/ath5k/phy.c drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c91
1 files changed, 68 insertions, 23 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e0c944fb6fc9..72efbd87c1eb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -39,7 +39,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
39{ 39{
40 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 40 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
41 if (likely(skb->len > FCS_LEN)) 41 if (likely(skb->len > FCS_LEN))
42 skb_trim(skb, skb->len - FCS_LEN); 42 __pskb_trim(skb, skb->len - FCS_LEN);
43 else { 43 else {
44 /* driver bug */ 44 /* driver bug */
45 WARN_ON(1); 45 WARN_ON(1);
@@ -228,6 +228,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
228 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 228 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
229 present_fcs_len = FCS_LEN; 229 present_fcs_len = FCS_LEN;
230 230
231 /* make sure hdr->frame_control is on the linear part */
232 if (!pskb_may_pull(origskb, 2)) {
233 dev_kfree_skb(origskb);
234 return NULL;
235 }
236
231 if (!local->monitors) { 237 if (!local->monitors) {
232 if (should_drop_frame(origskb, present_fcs_len)) { 238 if (should_drop_frame(origskb, present_fcs_len)) {
233 dev_kfree_skb(origskb); 239 dev_kfree_skb(origskb);
@@ -485,7 +491,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
485 491
486 if (ieee80211_is_action(hdr->frame_control)) { 492 if (ieee80211_is_action(hdr->frame_control)) {
487 mgmt = (struct ieee80211_mgmt *)hdr; 493 mgmt = (struct ieee80211_mgmt *)hdr;
488 if (mgmt->u.action.category != MESH_PLINK_CATEGORY) 494 if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
489 return RX_DROP_MONITOR; 495 return RX_DROP_MONITOR;
490 return RX_CONTINUE; 496 return RX_CONTINUE;
491 } 497 }
@@ -715,14 +721,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
715 721
716 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 722 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
717 723
718 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 724 spin_lock(&sta->lock);
719 goto dont_reorder; 725
726 if (!sta->ampdu_mlme.tid_active_rx[tid])
727 goto dont_reorder_unlock;
720 728
721 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; 729 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
722 730
723 /* qos null data frames are excluded */ 731 /* qos null data frames are excluded */
724 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 732 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
725 goto dont_reorder; 733 goto dont_reorder_unlock;
726 734
727 /* new, potentially un-ordered, ampdu frame - process it */ 735 /* new, potentially un-ordered, ampdu frame - process it */
728 736
@@ -734,15 +742,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
734 /* if this mpdu is fragmented - terminate rx aggregation session */ 742 /* if this mpdu is fragmented - terminate rx aggregation session */
735 sc = le16_to_cpu(hdr->seq_ctrl); 743 sc = le16_to_cpu(hdr->seq_ctrl);
736 if (sc & IEEE80211_SCTL_FRAG) { 744 if (sc & IEEE80211_SCTL_FRAG) {
737 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 745 spin_unlock(&sta->lock);
738 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 746 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
747 WLAN_REASON_QSTA_REQUIRE_SETUP);
739 dev_kfree_skb(skb); 748 dev_kfree_skb(skb);
740 return; 749 return;
741 } 750 }
742 751
743 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) 752 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) {
753 spin_unlock(&sta->lock);
744 return; 754 return;
755 }
745 756
757 dont_reorder_unlock:
758 spin_unlock(&sta->lock);
746 dont_reorder: 759 dont_reorder:
747 __skb_queue_tail(frames, skb); 760 __skb_queue_tail(frames, skb);
748} 761}
@@ -889,6 +902,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
889 rx->key = key; 902 rx->key = key;
890 return RX_CONTINUE; 903 return RX_CONTINUE;
891 } else { 904 } else {
905 u8 keyid;
892 /* 906 /*
893 * The device doesn't give us the IV so we won't be 907 * The device doesn't give us the IV so we won't be
894 * able to look up the key. That's ok though, we 908 * able to look up the key. That's ok though, we
@@ -911,7 +925,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
911 * no need to call ieee80211_wep_get_keyidx, 925 * no need to call ieee80211_wep_get_keyidx,
912 * it verifies a bunch of things we've done already 926 * it verifies a bunch of things we've done already
913 */ 927 */
914 keyidx = rx->skb->data[hdrlen + 3] >> 6; 928 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
929 keyidx = keyid >> 6;
915 930
916 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 931 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
917 932
@@ -932,6 +947,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
932 return RX_DROP_MONITOR; 947 return RX_DROP_MONITOR;
933 } 948 }
934 949
950 if (skb_linearize(rx->skb))
951 return RX_DROP_UNUSABLE;
952
953 hdr = (struct ieee80211_hdr *)rx->skb->data;
954
935 /* Check for weak IVs if possible */ 955 /* Check for weak IVs if possible */
936 if (rx->sta && rx->key->conf.alg == ALG_WEP && 956 if (rx->sta && rx->key->conf.alg == ALG_WEP &&
937 ieee80211_is_data(hdr->frame_control) && 957 ieee80211_is_data(hdr->frame_control) &&
@@ -1232,6 +1252,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1232 } 1252 }
1233 I802_DEBUG_INC(rx->local->rx_handlers_fragments); 1253 I802_DEBUG_INC(rx->local->rx_handlers_fragments);
1234 1254
1255 if (skb_linearize(rx->skb))
1256 return RX_DROP_UNUSABLE;
1257
1235 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; 1258 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
1236 1259
1237 if (frag == 0) { 1260 if (frag == 0) {
@@ -1397,21 +1420,24 @@ static int
1397ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) 1420ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1398{ 1421{
1399 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1422 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1423 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1400 __le16 fc = hdr->frame_control; 1424 __le16 fc = hdr->frame_control;
1401 int res;
1402 1425
1403 res = ieee80211_drop_unencrypted(rx, fc); 1426 /*
1404 if (unlikely(res)) 1427 * Pass through unencrypted frames if the hardware has
1405 return res; 1428 * decrypted them already.
1429 */
1430 if (status->flag & RX_FLAG_DECRYPTED)
1431 return 0;
1406 1432
1407 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1433 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1408 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1434 if (unlikely(!ieee80211_has_protected(fc) &&
1435 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1409 rx->key)) 1436 rx->key))
1410 return -EACCES; 1437 return -EACCES;
1411 /* BIP does not use Protected field, so need to check MMIE */ 1438 /* BIP does not use Protected field, so need to check MMIE */
1412 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1439 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1413 ieee80211_get_mmie_keyidx(rx->skb) < 0 && 1440 ieee80211_get_mmie_keyidx(rx->skb) < 0))
1414 rx->key))
1415 return -EACCES; 1441 return -EACCES;
1416 /* 1442 /*
1417 * When using MFP, Action frames are not allowed prior to 1443 * When using MFP, Action frames are not allowed prior to
@@ -1589,6 +1615,9 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1589 skb->dev = dev; 1615 skb->dev = dev;
1590 __skb_queue_head_init(&frame_list); 1616 __skb_queue_head_init(&frame_list);
1591 1617
1618 if (skb_linearize(skb))
1619 return RX_DROP_UNUSABLE;
1620
1592 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1621 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1593 rx->sdata->vif.type, 1622 rx->sdata->vif.type,
1594 rx->local->hw.extra_tx_headroom); 1623 rx->local->hw.extra_tx_headroom);
@@ -1787,10 +1816,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1787 if (ieee80211_is_back_req(bar->frame_control)) { 1816 if (ieee80211_is_back_req(bar->frame_control)) {
1788 if (!rx->sta) 1817 if (!rx->sta)
1789 return RX_DROP_MONITOR; 1818 return RX_DROP_MONITOR;
1819 spin_lock(&rx->sta->lock);
1790 tid = le16_to_cpu(bar->control) >> 12; 1820 tid = le16_to_cpu(bar->control) >> 12;
1791 if (rx->sta->ampdu_mlme.tid_state_rx[tid] 1821 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
1792 != HT_AGG_STATE_OPERATIONAL) 1822 spin_unlock(&rx->sta->lock);
1793 return RX_DROP_MONITOR; 1823 return RX_DROP_MONITOR;
1824 }
1794 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; 1825 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1795 1826
1796 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1827 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
@@ -1804,6 +1835,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1804 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, 1835 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
1805 frames); 1836 frames);
1806 kfree_skb(skb); 1837 kfree_skb(skb);
1838 spin_unlock(&rx->sta->lock);
1807 return RX_QUEUED; 1839 return RX_QUEUED;
1808 } 1840 }
1809 1841
@@ -1965,8 +1997,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1965 goto handled; 1997 goto handled;
1966 } 1998 }
1967 break; 1999 break;
1968 case MESH_PLINK_CATEGORY: 2000 case WLAN_CATEGORY_MESH_PLINK:
1969 case MESH_PATH_SEL_CATEGORY: 2001 case WLAN_CATEGORY_MESH_PATH_SEL:
1970 if (ieee80211_vif_is_mesh(&sdata->vif)) 2002 if (ieee80211_vif_is_mesh(&sdata->vif))
1971 return ieee80211_mesh_rx_mgmt(sdata, rx->skb); 2003 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1972 break; 2004 break;
@@ -2363,29 +2395,42 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2363 struct ieee80211_local *local = hw_to_local(hw); 2395 struct ieee80211_local *local = hw_to_local(hw);
2364 struct ieee80211_sub_if_data *sdata; 2396 struct ieee80211_sub_if_data *sdata;
2365 struct ieee80211_hdr *hdr; 2397 struct ieee80211_hdr *hdr;
2398 __le16 fc;
2366 struct ieee80211_rx_data rx; 2399 struct ieee80211_rx_data rx;
2367 int prepares; 2400 int prepares;
2368 struct ieee80211_sub_if_data *prev = NULL; 2401 struct ieee80211_sub_if_data *prev = NULL;
2369 struct sk_buff *skb_new; 2402 struct sk_buff *skb_new;
2370 struct sta_info *sta, *tmp; 2403 struct sta_info *sta, *tmp;
2371 bool found_sta = false; 2404 bool found_sta = false;
2405 int err = 0;
2372 2406
2373 hdr = (struct ieee80211_hdr *)skb->data; 2407 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
2374 memset(&rx, 0, sizeof(rx)); 2408 memset(&rx, 0, sizeof(rx));
2375 rx.skb = skb; 2409 rx.skb = skb;
2376 rx.local = local; 2410 rx.local = local;
2377 2411
2378 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) 2412 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2379 local->dot11ReceivedFragmentCount++; 2413 local->dot11ReceivedFragmentCount++;
2380 2414
2381 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2415 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2382 test_bit(SCAN_OFF_CHANNEL, &local->scanning))) 2416 test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
2383 rx.flags |= IEEE80211_RX_IN_SCAN; 2417 rx.flags |= IEEE80211_RX_IN_SCAN;
2384 2418
2419 if (ieee80211_is_mgmt(fc))
2420 err = skb_linearize(skb);
2421 else
2422 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
2423
2424 if (err) {
2425 dev_kfree_skb(skb);
2426 return;
2427 }
2428
2429 hdr = (struct ieee80211_hdr *)skb->data;
2385 ieee80211_parse_qos(&rx); 2430 ieee80211_parse_qos(&rx);
2386 ieee80211_verify_alignment(&rx); 2431 ieee80211_verify_alignment(&rx);
2387 2432
2388 if (ieee80211_is_data(hdr->frame_control)) { 2433 if (ieee80211_is_data(fc)) {
2389 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2434 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2390 rx.sta = sta; 2435 rx.sta = sta;
2391 found_sta = true; 2436 found_sta = true;