[PATCHv2 05/21] Remove WPA per-VLAN groups when all stations left on rekeying
Michael Braun
michael-dev
Thu Jun 6 03:09:33 PDT 2013
This adds a references counter to struct wpa_group and frees
a group if it is unused during rekeying.
This is useful when extending the number of VLANs supported.
Signed-hostap: Michael Braun <michael-dev at fami-braun.de>
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 83cc857..f08ded8 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -211,6 +211,14 @@ static int wpa_use_aes_cmac(struct wpa_state_machine *sm)
}
+static void wpa_group_free(struct wpa_group *group)
+{
+ wpa_printf(MSG_DEBUG, "WPA: Remove group state machine for VLAN-ID %d",
+ group->vlan_id);
+ os_free(group);
+}
+
+
static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_authenticator *wpa_auth = eloop_ctx;
@@ -234,15 +242,26 @@ static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx)
static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_authenticator *wpa_auth = eloop_ctx;
- struct wpa_group *group;
+ struct wpa_group *group, *prev;
wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK");
- for (group = wpa_auth->group; group; group = group->next) {
+ group = wpa_auth->group;
+ prev = NULL;
+ while (group) {
group->GTKReKey = TRUE;
do {
group->changed = FALSE;
wpa_group_sm_step(wpa_auth, group);
} while (group->changed);
+ if (group->references == 0 && prev) {
+ /* this does never delete the special first group */
+ prev->next = group->next;
+ wpa_group_free(group);
+ group = prev->next;
+ } else {
+ prev = group;
+ group = group->next;
+ }
}
if (wpa_auth->conf.wpa_group_rekey) {
@@ -519,6 +538,7 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr)
sm->wpa_auth = wpa_auth;
sm->group = wpa_auth->group;
+ sm->group->references++;
return sm;
}
@@ -581,6 +601,7 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
#endif /* CONFIG_IEEE80211R */
os_free(sm->last_rx_eapol_key);
os_free(sm->wpa_ie);
+ sm->group->references--;
os_free(sm);
}
@@ -3007,7 +3028,10 @@ int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state "
"machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id);
+ sm->group->references--;
sm->group = group;
+ sm->group->references++;
+
return 0;
}
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index 97489d3..8fbd4ff 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -151,6 +151,8 @@ struct wpa_group {
u8 IGTK[2][WPA_IGTK_LEN];
int GN_igtk, GM_igtk;
#endif /* CONFIG_IEEE80211W */
+ /* number of references except those in struct wpa_group->next */
+ unsigned int references;
};
More information about the Hostap
mailing list