[PATCHv2 07/21] 802.1X: release unused VLAN-WEP-Keys
Michael Braun
michael-dev
Thu Jun 6 03:09:28 PDT 2013
Reuse the WEP rekeying timer to remove keys for which no sta exists.
Signed-hostap: Michael Braun <michael-dev at fami-braun.de>
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 7a3a8d9..c9e62ce 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -383,7 +383,7 @@ static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
}
-static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
+void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
{
int i;
for (i = 0; i < NUM_WEP_KEYS; i++) {
@@ -393,6 +393,15 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
}
+void hostapd_config_free_vlan_wep(struct hostapd_vlan_wep_keys *key)
+{
+ if (!key)
+ return;
+ hostapd_config_free_wep(&key->key);
+ os_free(key);
+}
+
+
static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
{
struct hostapd_wpa_psk *psk, *prev;
@@ -454,10 +463,8 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
struct hostapd_ssid *ssid = &conf->ssid;
size_t i;
for (i = 0; i <= ssid->count_dyn_vlan_keys; i++) {
- if (ssid->dyn_vlan_keys[i] == NULL)
- continue;
- hostapd_config_free_wep(&ssid->dyn_vlan_keys[i]->key);
- os_free(ssid->dyn_vlan_keys[i]);
+ hostapd_config_free_vlan_wep(ssid->dyn_vlan_keys[i]);
+ ssid->dyn_vlan_keys[i] = NULL;
}
os_free(ssid->dyn_vlan_keys);
ssid->dyn_vlan_keys = NULL;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 7ca4647..2d918f0 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -42,6 +42,7 @@ struct hostapd_wep_keys {
struct hostapd_vlan_wep_keys {
int vlan_id;
+ int numSTAonLastRekey;
struct hostapd_wep_keys key;
};
@@ -549,6 +550,8 @@ int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
int hostapd_rate_found(int *list, int rate);
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
struct hostapd_wep_keys *b);
+void hostapd_config_free_wep(struct hostapd_wep_keys *keys);
+void hostapd_config_free_vlan_wep(struct hostapd_vlan_wep_keys *key);
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
const u8 *addr, const u8 *prev_psk);
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 8b5076d..9486516 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1579,6 +1579,67 @@ static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
}
+#ifndef CONFIG_NO_VLAN
+static int ieee802_1x_sta_check_group(struct hostapd_data *hapd,
+ struct sta_info *sta, void *ctx)
+{
+ int i;
+ struct hostapd_ssid *ssid = sta->ssid;
+
+ if (sta->vlan_id <= 0)
+ return 0;
+
+ for (i = 0; i < ssid->count_dyn_vlan_keys; i++) {
+ struct hostapd_vlan_wep_keys *key = ssid->dyn_vlan_keys[i];
+ if (!key)
+ continue;
+ if (key->vlan_id == sta->vlan_id)
+ continue;
+ key->numSTAonLastRekey++;
+ }
+ return 0;
+}
+
+static void ieee802_1x_cleanup_vlan_keys(struct hostapd_data *hapd)
+{
+ int i, offs;
+ struct hostapd_ssid *ssid = &hapd->conf->ssid;
+ struct hostapd_vlan_wep_keys **tmp;
+
+ for (i = 0; i < ssid->count_dyn_vlan_keys; i++) {
+ struct hostapd_vlan_wep_keys *key = ssid->dyn_vlan_keys[i];
+ if (!key)
+ continue;
+ key->numSTAonLastRekey = 0;
+ }
+ ap_for_each_sta(hapd, ieee802_1x_sta_check_group, NULL);
+ for (i = 0, offs = 0; i < ssid->count_dyn_vlan_keys; i++) {
+ struct hostapd_vlan_wep_keys *key = ssid->dyn_vlan_keys[i];
+ if (!key) {
+ offs++;
+ } else if (key->numSTAonLastRekey == 0) {
+ hostapd_config_free_vlan_wep(key);
+ ssid->dyn_vlan_keys[i] = NULL;
+ offs++;
+ } else if (offs > 0) {
+ ssid->dyn_vlan_keys[i - offs] = ssid->dyn_vlan_keys[i];
+ ssid->dyn_vlan_keys[i] = NULL;
+ }
+ }
+ if (offs > ssid->count_dyn_vlan_keys / 2) {
+ /* half of memory is free */
+ tmp = os_realloc_array(ssid->dyn_vlan_keys,
+ ssid->count_dyn_vlan_keys / 2,
+ sizeof(*ssid->dyn_vlan_keys));
+ if (!tmp) {
+ return;
+ }
+ ssid->dyn_vlan_keys = tmp;
+ ssid->count_dyn_vlan_keys = ssid->count_dyn_vlan_keys / 2;
+ }
+}
+#endif /* CONFIG_NO_VLAN */
+
static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,
struct sta_info *sta, void *ctx)
{
@@ -1629,6 +1690,9 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
}
ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL);
+ #ifndef CONFIG_NO_VLAN
+ ieee802_1x_cleanup_vlan_keys(hapd);
+ #endif
if (hapd->conf->wep_rekeying_period > 0) {
eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,
More information about the Hostap
mailing list