]> err.no Git - linux-2.6/blobdiff - net/mac80211/util.c
mac80211: move tx crypto decision
[linux-2.6] / net / mac80211 / util.c
index c970996ba6f96ccb89acc3a1476bf55769ee9104..2b02b2b9d645880dd1670f2784e4921d73eaf369 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bitmap.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
+#include <net/rtnetlink.h>
 
 #include "ieee80211_i.h"
 #include "ieee80211_rate.h"
@@ -39,10 +40,6 @@ const unsigned char rfc1042_header[] =
 const unsigned char bridge_tunnel_header[] =
        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 
-/* No encapsulation header if EtherType < 0x600 (=length) */
-static const unsigned char eapol_header[] =
-       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
-
 
 static int rate_list_match(const int *rate_list, int rate)
 {
@@ -93,16 +90,14 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
                        if (rate->rate == 10 || rate->rate == 20)
                                rate->flags |= IEEE80211_RATE_BASIC;
                        break;
-               case MODE_ATHEROS_TURBO:
-                       if (rate->rate == 120 || rate->rate == 240 ||
-                           rate->rate == 480)
-                               rate->flags |= IEEE80211_RATE_BASIC;
-                       break;
                case MODE_IEEE80211G:
                        if (rate->rate == 10 || rate->rate == 20 ||
                            rate->rate == 55 || rate->rate == 110)
                                rate->flags |= IEEE80211_RATE_BASIC;
                        break;
+               case NUM_IEEE80211_MODES:
+                       /* not useful */
+                       break;
                }
 
                /* Set ERP and MANDATORY flags based on phymode */
@@ -116,8 +111,6 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
                        if (rate->rate == 10)
                                rate->flags |= IEEE80211_RATE_MANDATORY;
                        break;
-               case MODE_ATHEROS_TURBO:
-                       break;
                case MODE_IEEE80211G:
                        if (rate->rate == 10 || rate->rate == 20 ||
                            rate->rate == 55 || rate->rate == 110 ||
@@ -125,6 +118,9 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
                            rate->rate == 240)
                                rate->flags |= IEEE80211_RATE_MANDATORY;
                        break;
+               case NUM_IEEE80211_MODES:
+                       /* not useful */
+                       break;
                }
                if (ieee80211_is_erp_rate(mode->mode, rate->rate))
                        rate->flags |= IEEE80211_RATE_ERP;
@@ -135,13 +131,16 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
 {
        u16 fc;
 
-       if (len < 24)
+        /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
+       if (len < 16)
                return NULL;
 
        fc = le16_to_cpu(hdr->frame_control);
 
        switch (fc & IEEE80211_FCTL_FTYPE) {
        case IEEE80211_FTYPE_DATA:
+               if (len < 24) /* drop incorrect hdr len (data) */
+                       return NULL;
                switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
                case IEEE80211_FCTL_TODS:
                        return hdr->addr1;
@@ -154,6 +153,8 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
                }
                break;
        case IEEE80211_FTYPE_MGMT:
+               if (len < 24) /* drop incorrect hdr len (mgmt) */
+                       return NULL;
                return hdr->addr3;
        case IEEE80211_FTYPE_CTL:
                if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)
@@ -218,31 +219,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
 
-int ieee80211_is_eapol(const struct sk_buff *skb)
-{
-       const struct ieee80211_hdr *hdr;
-       u16 fc;
-       int hdrlen;
-
-       if (unlikely(skb->len < 10))
-               return 0;
-
-       hdr = (const struct ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-               return 0;
-
-       hdrlen = ieee80211_get_hdrlen(fc);
-
-       if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
-                    memcmp(skb->data + hdrlen, eapol_header,
-                           sizeof(eapol_header)) == 0))
-               return 1;
-
-       return 0;
-}
-
 void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
@@ -273,8 +249,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
         * DIV_ROUND_UP() operations.
         */
 
-       if (local->hw.conf.phymode == MODE_IEEE80211A || erp ||
-           local->hw.conf.phymode == MODE_ATHEROS_TURBO) {
+       if (local->hw.conf.phymode == MODE_IEEE80211A || erp) {
                /*
                 * OFDM:
                 *
@@ -288,7 +263,6 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
                 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
                 *      signal ext = 6 usec
                 */
-               /* FIX: Atheros Turbo may have different (shorter) duration? */
                dur = 16; /* SIFS + signal ext */
                dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */
                dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */
@@ -487,3 +461,36 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
                ieee80211_wake_queue(hw, i);
 }
 EXPORT_SYMBOL(ieee80211_wake_queues);
+
+void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
+                                        void (*iterator)(void *data, u8 *mac,
+                                                         int if_id),
+                                        void *data)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       struct ieee80211_sub_if_data *sdata;
+
+       rcu_read_lock();
+
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+               switch (sdata->type) {
+               case IEEE80211_IF_TYPE_INVALID:
+               case IEEE80211_IF_TYPE_MNTR:
+               case IEEE80211_IF_TYPE_VLAN:
+                       continue;
+               case IEEE80211_IF_TYPE_AP:
+               case IEEE80211_IF_TYPE_STA:
+               case IEEE80211_IF_TYPE_IBSS:
+               case IEEE80211_IF_TYPE_WDS:
+                       break;
+               }
+               if (sdata->dev == local->mdev)
+                       continue;
+               if (netif_running(sdata->dev))
+                       iterator(data, sdata->dev->dev_addr,
+                                sdata->dev->ifindex);
+       }
+
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);