diff options
author | David S. Miller <davem@davemloft.net> | 2010-06-11 14:34:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-11 14:34:06 -0400 |
commit | 14599f1e341ee219abdd15f4eee5872d6f2d29f1 (patch) | |
tree | 3875181429010e58416ab34e6c06ef42de52e756 /net/mac80211/rx.c | |
parent | d8d1f30b95a635dbd610dcc5eb641aca8f4768cf (diff) | |
parent | 832c10fd733893f86c63bde1c65b005d5a2fe346 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/wireless/wl12xx/wl1271.h
drivers/net/wireless/wl12xx/wl1271_cmd.h
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index dd232061e4c4..6a15632e7eca 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -825,6 +825,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
825 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 825 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
826 | struct ieee80211_key *stakey = NULL; | 826 | struct ieee80211_key *stakey = NULL; |
827 | int mmie_keyidx = -1; | 827 | int mmie_keyidx = -1; |
828 | __le16 fc; | ||
828 | 829 | ||
829 | /* | 830 | /* |
830 | * Key selection 101 | 831 | * Key selection 101 |
@@ -866,13 +867,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
866 | if (rx->sta) | 867 | if (rx->sta) |
867 | stakey = rcu_dereference(rx->sta->key); | 868 | stakey = rcu_dereference(rx->sta->key); |
868 | 869 | ||
869 | if (!ieee80211_has_protected(hdr->frame_control)) | 870 | fc = hdr->frame_control; |
871 | |||
872 | if (!ieee80211_has_protected(fc)) | ||
870 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | 873 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); |
871 | 874 | ||
872 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 875 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { |
873 | rx->key = stakey; | 876 | rx->key = stakey; |
874 | /* Skip decryption if the frame is not protected. */ | 877 | /* Skip decryption if the frame is not protected. */ |
875 | if (!ieee80211_has_protected(hdr->frame_control)) | 878 | if (!ieee80211_has_protected(fc)) |
876 | return RX_CONTINUE; | 879 | return RX_CONTINUE; |
877 | } else if (mmie_keyidx >= 0) { | 880 | } else if (mmie_keyidx >= 0) { |
878 | /* Broadcast/multicast robust management frame / BIP */ | 881 | /* Broadcast/multicast robust management frame / BIP */ |
@@ -884,7 +887,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
884 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | 887 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) |
885 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | 888 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ |
886 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | 889 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); |
887 | } else if (!ieee80211_has_protected(hdr->frame_control)) { | 890 | } else if (!ieee80211_has_protected(fc)) { |
888 | /* | 891 | /* |
889 | * The frame was not protected, so skip decryption. However, we | 892 | * The frame was not protected, so skip decryption. However, we |
890 | * need to set rx->key if there is a key that could have been | 893 | * need to set rx->key if there is a key that could have been |
@@ -892,7 +895,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
892 | * have been expected. | 895 | * have been expected. |
893 | */ | 896 | */ |
894 | struct ieee80211_key *key = NULL; | 897 | struct ieee80211_key *key = NULL; |
895 | if (ieee80211_is_mgmt(hdr->frame_control) && | 898 | if (ieee80211_is_mgmt(fc) && |
896 | is_multicast_ether_addr(hdr->addr1) && | 899 | is_multicast_ether_addr(hdr->addr1) && |
897 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | 900 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) |
898 | rx->key = key; | 901 | rx->key = key; |
@@ -914,7 +917,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
914 | (status->flag & RX_FLAG_IV_STRIPPED)) | 917 | (status->flag & RX_FLAG_IV_STRIPPED)) |
915 | return RX_CONTINUE; | 918 | return RX_CONTINUE; |
916 | 919 | ||
917 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 920 | hdrlen = ieee80211_hdrlen(fc); |
918 | 921 | ||
919 | if (rx->skb->len < 8 + hdrlen) | 922 | if (rx->skb->len < 8 + hdrlen) |
920 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | 923 | return RX_DROP_UNUSABLE; /* TODO: count this? */ |
@@ -947,19 +950,17 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
947 | 950 | ||
948 | if (skb_linearize(rx->skb)) | 951 | if (skb_linearize(rx->skb)) |
949 | return RX_DROP_UNUSABLE; | 952 | return RX_DROP_UNUSABLE; |
950 | 953 | /* the hdr variable is invalid now! */ | |
951 | hdr = (struct ieee80211_hdr *)rx->skb->data; | ||
952 | |||
953 | /* Check for weak IVs if possible */ | ||
954 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | ||
955 | ieee80211_is_data(hdr->frame_control) && | ||
956 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | ||
957 | !(status->flag & RX_FLAG_DECRYPTED)) && | ||
958 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
959 | rx->sta->wep_weak_iv_count++; | ||
960 | 954 | ||
961 | switch (rx->key->conf.alg) { | 955 | switch (rx->key->conf.alg) { |
962 | case ALG_WEP: | 956 | case ALG_WEP: |
957 | /* Check for weak IVs if possible */ | ||
958 | if (rx->sta && ieee80211_is_data(fc) && | ||
959 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | ||
960 | !(status->flag & RX_FLAG_DECRYPTED)) && | ||
961 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
962 | rx->sta->wep_weak_iv_count++; | ||
963 | |||
963 | result = ieee80211_crypto_wep_decrypt(rx); | 964 | result = ieee80211_crypto_wep_decrypt(rx); |
964 | break; | 965 | break; |
965 | case ALG_TKIP: | 966 | case ALG_TKIP: |
@@ -1852,7 +1853,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
1852 | return RX_QUEUED; | 1853 | return RX_QUEUED; |
1853 | } | 1854 | } |
1854 | 1855 | ||
1855 | return RX_CONTINUE; | 1856 | /* |
1857 | * After this point, we only want management frames, | ||
1858 | * so we can drop all remaining control frames to | ||
1859 | * cooked monitor interfaces. | ||
1860 | */ | ||
1861 | return RX_DROP_MONITOR; | ||
1856 | } | 1862 | } |
1857 | 1863 | ||
1858 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | 1864 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, |
@@ -1944,6 +1950,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1944 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1950 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1945 | break; | 1951 | break; |
1946 | 1952 | ||
1953 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
1954 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | ||
1955 | |||
1947 | switch (mgmt->u.action.u.addba_req.action_code) { | 1956 | switch (mgmt->u.action.u.addba_req.action_code) { |
1948 | case WLAN_ACTION_ADDBA_REQ: | 1957 | case WLAN_ACTION_ADDBA_REQ: |
1949 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1958 | if (len < (IEEE80211_MIN_ACTION_SIZE + |