Replace sta_aid array with bitfield
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 25 Mar 2009 13:54:25 +0000 (15:54 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 25 Mar 2009 13:54:25 +0000 (15:54 +0200)
The actual pointer to struct sta_info was not really used and it is
enough to use a single bit to indicate whether an AID is allocated. This
makes the BSS data take less memory while making the allocation routine
faster and removing the arbitrary MAX_AID_TABLE_SIZE limit of 128 STAs.

hostapd/ap.h
hostapd/hostapd.h
hostapd/ieee802_11.c
hostapd/sta_info.c

index 2c6d7e9..2440fbd 100644 (file)
@@ -113,14 +113,6 @@ struct sta_info {
 };
 
 
-/* Maximum number of AIDs to use for STAs; must be 2007 or lower
- * (8802.11 limitation) */
-#define MAX_AID_TABLE_SIZE 128
-
-#define STA_HASH_SIZE 256
-#define STA_HASH(sta) (sta[5])
-
-
 /* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has
  * passed since last received frame from the station, a nullfunc data frame is
  * sent to the station. If this frame is not acknowledged and no other frames
index c7b1947..8bdd58c 100644 (file)
@@ -44,13 +44,17 @@ struct hostapd_data {
 
        int num_sta; /* number of entries in sta_list */
        struct sta_info *sta_list; /* STA info list head */
+#define STA_HASH_SIZE 256
+#define STA_HASH(sta) (sta[5])
        struct sta_info *sta_hash[STA_HASH_SIZE];
 
-       /* pointers to STA info; based on allocated AID or NULL if AID free
-        * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
-        * and so on
+       /*
+        * Bitfield for indicating which AIDs are allocated. Only AID values
+        * 1-2007 are used and as such, the bit at index 0 corresponds to AID
+        * 1.
         */
-       struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
+#define AID_WORDS ((2008 + 31) / 32)
+       u32 sta_aid[AID_WORDS];
 
        const struct wpa_driver_ops *driver;
        void *drv_priv;
index 6b1a4a9..0ef02c1 100644 (file)
@@ -667,21 +667,32 @@ static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
 
 static int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
 {
+       int i, j = 32, aid;
+
        /* get a unique AID */
        if (sta->aid > 0) {
                wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
                return 0;
        }
 
-       for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
-               if (hapd->sta_aid[sta->aid - 1] == NULL)
+       for (i = 0; i < AID_WORDS; i++) {
+               if (hapd->sta_aid[i] == (u32) -1)
+                       continue;
+               for (j = 0; j < 32; j++) {
+                       if (!(hapd->sta_aid[i] & BIT(j)))
+                               break;
+               }
+               if (j < 32)
                        break;
-       if (sta->aid > MAX_AID_TABLE_SIZE) {
-               sta->aid = 0;
-               return -1;
        }
+       if (j == 32)
+               return -1;
+       aid = i * 32 + j + 1;
+       if (aid > 2007)
+               return -1;
 
-       hapd->sta_aid[sta->aid - 1] = sta;
+       sta->aid = aid;
+       hapd->sta_aid[i] |= BIT(j);
        wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
        return 0;
 }
index a3589b8..16e292f 100644 (file)
@@ -128,7 +128,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        ap_sta_list_del(hapd, sta);
 
        if (sta->aid > 0)
-               hapd->sta_aid[sta->aid - 1] = NULL;
+               hapd->sta_aid[(sta->aid - 1) / 32] &=
+                       ~BIT((sta->aid - 1) % 32);
 
        hapd->num_sta--;
        if (sta->nonerp_set) {