From patchwork Sat Jul 27 16:08:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 262462 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 9C5332C00C1 for ; Sun, 28 Jul 2013 02:08:55 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 7A38C9D359; Sat, 27 Jul 2013 12:08:53 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id R6HZSnSUg-e2; Sat, 27 Jul 2013 12:08:53 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 6ADB89D35C; Sat, 27 Jul 2013 12:08:48 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 4C2039D34F for ; Sat, 27 Jul 2013 12:08:47 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Yzilwa97Qnlk for ; Sat, 27 Jul 2013 12:08:42 -0400 (EDT) Received: from mail.fem.tu-ilmenau.de (mail.fem.tu-ilmenau.de [141.24.101.79]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 0D54F9D358 for ; Sat, 27 Jul 2013 12:08:42 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP id 9A6E5656D for ; Sat, 27 Jul 2013 18:08:41 +0200 (CEST) X-Virus-Scanned: amavisd-new at fem.tu-ilmenau.de Received: from mail.fem.tu-ilmenau.de ([127.0.0.1]) by localhost (mail.fem.tu-ilmenau.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id LaPZ8Qt1VMmJ; Sat, 27 Jul 2013 18:08:40 +0200 (CEST) Received: from a234.fem.tu-ilmenau.de (unknown [10.42.51.234]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP; Sat, 27 Jul 2013 18:08:40 +0200 (CEST) Received: from [10.42.51.234] (localhost [127.0.0.1]) by a234.fem.tu-ilmenau.de (Postfix) with ESMTP id C0542BD0; Sat, 27 Jul 2013 18:08:40 +0200 (CEST) Subject: [PATCH v3 01/25] Remove WPA per-VLAN groups when all stations left on rekeying To: hostap@lists.shmoo.com From: Michael Braun Date: Sat, 27 Jul 2013 18:08:40 +0200 Message-ID: <20130727160824.1152.49791.stgit@ray-controller> In-Reply-To: <20130727160024.1152.46147.stgit@ray-controller> References: <20130727160024.1152.46147.stgit@ray-controller> User-Agent: StGit/0.16 MIME-Version: 1.0 Cc: projekt-wlan@fem.tu-ilmenau.de X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com This adds a references counter to struct wpa_group and frees a group if it is unused. This is useful when extending the number of VLANs supported. Signed-hostap: Michael Braun V3: Freeing is not done in rekeying timer anymore. --- src/ap/wpa_auth.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ap/wpa_auth_i.h | 2 + 2 files changed, 73 insertions(+) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 83cc857..af7250e 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -41,6 +41,11 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, struct wpa_group *group); static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, struct wpa_group *group); +static void wpa_group_free(void *eloop_ctx, void *timeout_ctx); +static void wpa_group_get(struct wpa_authenticator *wpa_auth, + struct wpa_group *group); +static void wpa_group_put(struct wpa_authenticator *wpa_auth, + struct wpa_group *group); static const u32 dot11RSNAConfigGroupUpdateCount = 4; static const u32 dot11RSNAConfigPairwiseUpdateCount = 4; @@ -52,6 +57,7 @@ static const u32 eapol_key_timeout_first_group = 500; /* ms */ static const int dot11RSNAConfigPMKLifetime = 43200; static const int dot11RSNAConfigPMKReauthThreshold = 70; static const int dot11RSNAConfigSATimeout = 60; +static const int groupFreeTimeout = 5; static inline int wpa_auth_mic_failure_report( @@ -467,6 +473,7 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth) while (group) { prev = group; group = group->next; + eloop_cancel_timeout(wpa_group_free, wpa_auth, group); os_free(prev); } @@ -519,6 +526,7 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr) sm->wpa_auth = wpa_auth; sm->group = wpa_auth->group; + wpa_group_get(sm->wpa_auth, sm->group); return sm; } @@ -581,6 +589,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); + wpa_group_put(sm->wpa_auth, sm->group); os_free(sm); } @@ -2960,6 +2969,65 @@ void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, } +/** + * Remove and free the group from wpa_authenticator. + * This is triggered by a callback to make sure nobody + * is currently iterating the group list while it gets modified. + */ +static void wpa_group_free(void *eloop_ctx, void *timeout_ctx) +{ + struct wpa_authenticator *wpa_auth = eloop_ctx; + struct wpa_group *group = timeout_ctx; + struct wpa_group *prev = wpa_auth->group; + + wpa_printf(MSG_DEBUG, "WPA: Remove group state machine for VLAN-ID %d", + group->vlan_id); + + while (prev) { + if (prev->next == group) { + /* This never frees the special first group as needed */ + prev->next = group->next; + os_free(group); + break; + } + prev = prev->next; + } + +} + + +static void +wpa_group_get(struct wpa_authenticator *wpa_auth, struct wpa_group *group) +{ + // skip the special first group + if (wpa_auth->group == group) + return; + + if (group->references == -1) { + eloop_cancel_timeout(wpa_group_free, wpa_auth, group); + group->references = 0; + } + + group->references++; +} + + +static void +wpa_group_put(struct wpa_authenticator *wpa_auth, struct wpa_group *group) +{ + // skip the special first group + if (wpa_auth->group == group) + return; + + group->references--; + if (group->references != 0) + return; + eloop_register_timeout(groupFreeTimeout, 0, wpa_group_free, wpa_auth, + group); + group->references = -1; +} + + static struct wpa_group * wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id) { @@ -3007,7 +3075,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); + wpa_group_put(sm->wpa_auth, sm->group); sm->group = group; + wpa_group_get(sm->wpa_auth, sm->group); + return 0; } diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index 97489d3..82e6e3a 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 */ + int references; };