[NET]: cleanup 3rd argument in netlink_sendskb
[safe/jmp/linux-2.6] / net / mac80211 / rx.c
index a0dfafb..ece7776 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "ieee80211_i.h"
 #include "ieee80211_led.h"
-#include "ieee80211_common.h"
 #include "wep.h"
 #include "wpa.h"
 #include "tkip.h"
@@ -412,12 +411,7 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
                        return TXRX_DROP;
                }
 
-               if (!rx->local->apdev)
-                       return TXRX_DROP;
-
-               ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-                                 ieee80211_msg_sta_not_assoc);
-               return TXRX_QUEUED;
+               return TXRX_DROP;
        }
 
        return TXRX_CONTINUE;
@@ -425,11 +419,12 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
 
 
 static ieee80211_txrx_result
-ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
+ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
        int keyidx;
        int hdrlen;
+       ieee80211_txrx_result result = TXRX_DROP;
        struct ieee80211_key *stakey = NULL;
 
        /*
@@ -462,7 +457,7 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
                return TXRX_CONTINUE;
 
        /*
-        * No point in finding a key if the frame is neither
+        * No point in finding a key and decrypting if the frame is neither
         * addressed to us nor a multicast frame.
         */
        if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
@@ -513,9 +508,37 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
        if (rx->key) {
                rx->key->tx_rx_count++;
                /* TODO: add threshold stuff again */
+       } else {
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: RX protected frame,"
+                              " but have no key\n", rx->dev->name);
+               return TXRX_DROP;
        }
 
-       return TXRX_CONTINUE;
+       /* Check for weak IVs if possible */
+       if (rx->sta && rx->key->conf.alg == ALG_WEP &&
+           ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+           (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) ||
+            !(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) &&
+           ieee80211_wep_is_weak_iv(rx->skb, rx->key))
+               rx->sta->wep_weak_iv_count++;
+
+       switch (rx->key->conf.alg) {
+       case ALG_WEP:
+               result = ieee80211_crypto_wep_decrypt(rx);
+               break;
+       case ALG_TKIP:
+               result = ieee80211_crypto_tkip_decrypt(rx);
+               break;
+       case ALG_CCMP:
+               result = ieee80211_crypto_ccmp_decrypt(rx);
+               break;
+       }
+
+       /* either the frame has been decrypted or will be dropped */
+       rx->u.rx.status->flag |= RX_FLAG_DECRYPTED;
+
+       return result;
 }
 
 static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)
@@ -643,57 +666,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx)
        return TXRX_CONTINUE;
 } /* ieee80211_rx_h_sta_process */
 
-static ieee80211_txrx_result
-ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
-{
-       if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-           (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           !rx->key || rx->key->conf.alg != ALG_WEP ||
-           !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-               return TXRX_CONTINUE;
-
-       /* Check for weak IVs, if hwaccel did not remove IV from the frame */
-       if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) ||
-           !(rx->u.rx.status->flag & RX_FLAG_DECRYPTED))
-               if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
-                       rx->sta->wep_weak_iv_count++;
-
-       return TXRX_CONTINUE;
-}
-
-static ieee80211_txrx_result
-ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
-{
-       if ((rx->key && rx->key->conf.alg != ALG_WEP) ||
-           !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
-           ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
-            ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
-             (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
-               return TXRX_CONTINUE;
-
-       if (!rx->key) {
-               if (net_ratelimit())
-                       printk(KERN_DEBUG "%s: RX WEP frame, but no key set\n",
-                              rx->dev->name);
-               return TXRX_DROP;
-       }
-
-       if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
-               if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
-                       if (net_ratelimit())
-                               printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
-                                      "failed\n", rx->dev->name);
-                       return TXRX_DROP;
-               }
-       } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
-               ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
-               /* remove ICV */
-               skb_trim(rx->skb, rx->skb->len - 4);
-       }
-
-       return TXRX_CONTINUE;
-}
-
 static inline struct ieee80211_fragment_entry *
 ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
                         unsigned int frag, unsigned int seq, int rx_queue,
@@ -987,15 +959,8 @@ ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx)
 {
        if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
            rx->sdata->type != IEEE80211_IF_TYPE_STA &&
-           (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
-               /* Pass both encrypted and unencrypted EAPOL frames to user
-                * space for processing. */
-               if (!rx->local->apdev)
-                       return TXRX_DROP;
-               ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-                                 ieee80211_msg_normal);
-               return TXRX_QUEUED;
-       }
+           (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
+               return TXRX_CONTINUE;
 
        if (unlikely(rx->sdata->ieee802_1x &&
                     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
@@ -1030,9 +995,8 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
        if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
                     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
                     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
-                    (rx->key || rx->sdata->drop_unencrypted) &&
-                    (rx->sdata->eapol == 0 ||
-                     !ieee80211_is_eapol(rx->skb)))) {
+                    rx->sdata->drop_unencrypted &&
+                    (rx->sdata->eapol == 0 || !ieee80211_is_eapol(rx->skb)))) {
                if (net_ratelimit())
                        printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
                               "encryption\n", rx->dev->name);
@@ -1237,15 +1201,11 @@ ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx)
        sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
        if ((sdata->type == IEEE80211_IF_TYPE_STA ||
             sdata->type == IEEE80211_IF_TYPE_IBSS) &&
-           !rx->local->user_space_mlme) {
+           !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
                ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
-       } else {
-               /* Management frames are sent to hostapd for processing */
-               if (!rx->local->apdev)
-                       return TXRX_DROP;
-               ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
-                                 ieee80211_msg_normal);
-       }
+       else
+               return TXRX_DROP;
+
        return TXRX_QUEUED;
 }
 
@@ -1369,12 +1329,8 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
        ieee80211_rx_h_if_stats,
        ieee80211_rx_h_passive_scan,
        ieee80211_rx_h_check,
-       ieee80211_rx_h_load_key,
+       ieee80211_rx_h_decrypt,
        ieee80211_rx_h_sta_process,
-       ieee80211_rx_h_ccmp_decrypt,
-       ieee80211_rx_h_tkip_decrypt,
-       ieee80211_rx_h_wep_weak_iv_detection,
-       ieee80211_rx_h_wep_decrypt,
        ieee80211_rx_h_defragment,
        ieee80211_rx_h_ps_poll,
        ieee80211_rx_h_michael_mic_verify,
@@ -1431,6 +1387,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
                        rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb,
                                                         bssid, hdr->addr2);
                break;
+       case IEEE80211_IF_TYPE_VLAN:
        case IEEE80211_IF_TYPE_AP:
                if (!bssid) {
                        if (compare_ether_addr(sdata->dev->dev_addr,
@@ -1455,6 +1412,13 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
                if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
                        return 0;
                break;
+       case IEEE80211_IF_TYPE_MNTR:
+               /* take everything */
+               break;
+       case IEEE80211_IF_TYPE_INVALID:
+               /* should never get here */
+               WARN_ON(1);
+               break;
        }
 
        return 1;
@@ -1529,7 +1493,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
        skb = rx.skb;
 
        if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) &&
-           !local->iff_promiscs && !is_multicast_ether_addr(hdr->addr1)) {
+           !atomic_read(&local->iff_promiscs) &&
+           !is_multicast_ether_addr(hdr->addr1)) {
                rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
                ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx,
                                             rx.sta);