From patchwork Sat Jul 27 19:56:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 262523 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 35DB62C0112 for ; Sun, 28 Jul 2013 06:01:43 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 123F517C19D; Sat, 27 Jul 2013 16:01:41 -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 mJwJMchoreNE; Sat, 27 Jul 2013 16:01:40 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id AC44E17C1A2; Sat, 27 Jul 2013 15:58:12 -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 500BD17C1A1 for ; Sat, 27 Jul 2013 15:58:12 -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 KdSBkYE206ZJ for ; Sat, 27 Jul 2013 15:58:07 -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 8CB879D3E7 for ; Sat, 27 Jul 2013 15:56:13 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP id 20F556551 for ; Sat, 27 Jul 2013 21:56:13 +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 YIy2UqdfEa6x; Sat, 27 Jul 2013 21:56:12 +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 21:56:12 +0200 (CEST) Received: from [10.42.51.234] (localhost [127.0.0.1]) by a234.fem.tu-ilmenau.de (Postfix) with ESMTP id 56412BED2D; Sat, 27 Jul 2013 21:56:12 +0200 (CEST) Subject: [PATCH v4 21/25] Fix STA dynamic vlan tracking To: hostap@lists.shmoo.com From: Michael Braun Date: Sat, 27 Jul 2013 21:56:12 +0200 Message-ID: <20130727195612.17627.75504.stgit@ray-controller> In-Reply-To: <20130727195247.17627.28374.stgit@ray-controller> References: <20130727195247.17627.28374.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 When an STA is authenticated, it gets moved to appropiate (dynamic) vlan using ap_sta_bind_vlan. Though, it is not removed when the station disconnects - even if the struct sta_info is freed. This results in dynamic interfaces not being removed. Solution: The struct sta_info tracks the dynamic vlans the station has been assigned. This information can be used to release the VLAN the STA has been added to it before. Signed-hostap: Michael Braun --- src/ap/ieee802_1x.c | 2 +- src/ap/sta_info.c | 33 ++++++++++++++++++++++++++++++--- src/ap/sta_info.h | 4 ++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 604b115..e5bf003 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -1360,7 +1360,6 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, if (ap_sta_bind_vlan(hapd, sta, old_vlanid) < 0) break; - vlan_free(&old_vlanid); /* RFC 3580, Ch. 3.17 */ if (session_timeout_set && termination_action == @@ -1415,6 +1414,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, sm->eap_if->aaaEapReq = FALSE; eapol_auth_step(sm); + vlan_free(&old_vlanid); return RADIUS_RX_QUEUED; } diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index d3d9349..5fe1321 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -119,6 +119,22 @@ static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta) } +/** + * This method marks the STA as not being assigned to any VLAN currently. + * It may only be called if the STA is not assigned to its VLAN interface + * in kernel! + * It is used before freeing the sta data structure to release + * tehe vlan_id_bound VLAN pointer. + */ +void ap_unbind_sta_vlan(struct hostapd_data *hapd, struct sta_info *sta) +{ + if (vlan_notempty(&sta->vlan_id_bound) && + vlan_untagged(&sta->vlan_id_bound) >= 0) + vlan_remove_dynamic(hapd, sta->vlan_id_bound); + vlan_free(&sta->vlan_id_bound); +} + + void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) { int set_beacon = 0; @@ -247,6 +263,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) #endif /* CONFIG_SAE */ vlan_free(&sta->vlan_id); + ap_unbind_sta_vlan(hapd, sta); os_free(sta); } @@ -662,12 +679,18 @@ int ap_sta_wps_cancel(struct hostapd_data *hapd, #endif /* CONFIG_WPS */ +/** + * Moves the STA to its VLAN. + * @param old_vlanid Used to check if anything has changed. Might differ from + * sta->bound_vlanid as tracking in hostapd is not exact. + */ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, vlan_t old_vlanid) { #ifndef CONFIG_NO_VLAN const char *iface; struct hostapd_vlan *vlan = NULL; + int boundVLANchanged; int ret; /* @@ -681,8 +704,9 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, * During 1x reauth, if the vlan id changes, then remove the old id and * proceed furthur to add the new one. */ - if (vlan_notempty(&old_vlanid) && vlan_untagged(&old_vlanid) >= 0) - vlan_remove_dynamic(hapd, old_vlanid); + boundVLANchanged = !vlan_cmp(&sta->vlan_id, &sta->vlan_id_bound); + if (boundVLANchanged) + ap_unbind_sta_vlan(hapd, sta); iface = hapd->conf->iface; if (sta->ssid->vlan[0]) @@ -742,7 +766,8 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, "interface '%s'", iface); } else if (vlan && vlan_cmp(&vlan->vlan_id, &sta->vlan_id)) { if (vlan_notempty(&sta->vlan_id) && - vlan_untagged(&sta->vlan_id) >= 0) { + vlan_untagged(&sta->vlan_id) >= 0 && + boundVLANchanged) { vlan->dynamic_vlan++; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, @@ -770,6 +795,8 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, HOSTAPD_LEVEL_DEBUG, "binding station to interface " "'%s'", iface); + if (boundVLANchanged) + vlan_alloc_copy(&sta->vlan_id_bound, &sta->vlan_id); if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0) wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA"); diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index c2d1525..ac25d9b 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -97,7 +97,10 @@ struct sta_info { struct hostapd_ssid *ssid; /* SSID selection based on (Re)AssocReq */ struct hostapd_ssid *ssid_probe; /* SSID selection based on ProbeReq */ + /* VLAN-ID given by auth or acl */ vlan_t vlan_id; + /* VLAN ID currently in use (as counted with vlan->dynamic_vlan) */ + vlan_t vlan_id_bound; /* PSKs from RADIUS authentication server */ struct hostapd_sta_wpa_psk_short *psk; @@ -177,6 +180,7 @@ int ap_sta_wps_cancel(struct hostapd_data *hapd, #endif /* CONFIG_WPS */ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, vlan_t old_vlanid); +void ap_unbind_sta_vlan(struct hostapd_data *hapd, struct sta_info *sta); void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta); void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta); int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta);