[PATCHv2 07/21] 802.1X: release unused VLAN-WEP-Keys

Michael Braun michael-dev at fami-braun.de
Thu Jun 6 06:09:28 EDT 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