Patchwork [PATCHv2,10a/21] VLAN: Use new data type for VLAN description.

login
register
mail settings
Submitter michael-dev@fami-braun.de
Date May 17, 2013, 9:44 a.m.
Message ID <a90ff9623644aa263ff05ef827ca7eeea27c31de2.1370512966.git.michael-dev@fami-braun.de>
Download mbox | patch
Permalink /patch/249388/
State Superseded
Headers show

Comments

michael-dev@fami-braun.de - May 17, 2013, 9:44 a.m.
This hides away the details of the currently in-use VLAN model
and is preparing for adding tagged VLAN support later on.
Implementing this as inline functions lets the compiler create
as fast code as before the change.

Signed-hostap: Michael Braun <michael-dev@fami-braun.de>

 create mode 100644 src/common/vlan.h

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index eb049fe..ad21880 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -31,7 +31,8 @@  static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
 {
 	FILE *f;
 	char buf[128], *pos, *pos2;
-	int line = 0, vlan_id;
+	int line = 0;
+	vlan_t vlan_id = VLAN_NULL;
 	struct hostapd_vlan *vlan;
 
 	f = fopen(fname, "r");
@@ -57,17 +58,18 @@  static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
 			continue;
 
 		if (buf[0] == '*') {
-			vlan_id = VLAN_ID_WILDCARD;
+			vlan_alloc(&vlan_id, VLAN_ID_WILDCARD);
 			pos = buf + 1;
 		} else {
-			vlan_id = strtol(buf, &pos, 10);
-			if (buf == pos || vlan_id < 1 ||
-			    vlan_id > MAX_VLAN_ID) {
+			int untagged_vlan_id = strtol(buf, &pos, 10);
+			if (buf == pos || untagged_vlan_id < 1 ||
+			    untagged_vlan_id > MAX_VLAN_ID) {
 				wpa_printf(MSG_ERROR, "Invalid VLAN ID at "
 					   "line %d in '%s'", line, fname);
 				fclose(f);
 				return -1;
 			}
+			vlan_alloc(&vlan_id, untagged_vlan_id);
 		}
 
 		while (*pos == ' ' || *pos == '\t')
@@ -91,7 +93,8 @@  static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
 			return -1;
 		}
 
-		vlan->vlan_id = vlan_id;
+		vlan_alloc_copy(&vlan->vlan_id, &vlan_id);
+		vlan_free(&vlan_id);
 		os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
 		vlan->next = bss->vlan;
 		bss->vlan = vlan;
@@ -120,7 +123,7 @@  static int hostapd_config_read_maclist(const char *fname,
 	int line = 0;
 	u8 addr[ETH_ALEN];
 	struct mac_acl_entry *newacl;
-	int vlan_id;
+	vlan_t vlan_id = VLAN_NULL;
 
 	if (!fname)
 		return 0;
@@ -154,14 +157,14 @@  static int hostapd_config_read_maclist(const char *fname,
 			return -1;
 		}
 
-		vlan_id = 0;
+		vlan_id = VLAN_NULL;
 		pos = buf;
 		while (*pos != '\0' && *pos != ' ' && *pos != '\t')
 			pos++;
 		while (*pos == ' ' || *pos == '\t')
 			pos++;
 		if (*pos != '\0')
-			vlan_id = atoi(pos);
+			vlan_alloc(&vlan_id, atoi(pos));
 
 		newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
 		if (newacl == NULL) {
@@ -172,8 +175,9 @@  static int hostapd_config_read_maclist(const char *fname,
 
 		*acl = newacl;
 		os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
-		(*acl)[*num].vlan_id = vlan_id;
+		vlan_alloc_copy(&(*acl)[*num].vlan_id, &vlan_id);
 		(*num)++;
+		vlan_free(&vlan_id);
 	}
 
 	fclose(f);
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index c9e62ce..aac8a50 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -573,7 +573,7 @@  void hostapd_config_free(struct hostapd_config *conf)
  * Perform a binary search for given MAC address from a pre-sorted list.
  */
 int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
-			  const u8 *addr, int *vlan_id)
+			  const u8 *addr, vlan_t *vlan_id)
 {
 	int start, end, middle, res;
 
@@ -585,7 +585,7 @@  int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
 		res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
 		if (res == 0) {
 			if (vlan_id)
-				*vlan_id = list[middle].vlan_id;
+				vlan_alloc_copy(vlan_id, &list[middle].vlan_id);
 			return 1;
 		}
 		if (res < 0)
@@ -613,22 +613,24 @@  int hostapd_rate_found(int *list, int rate)
 }
 
 
-int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, int vlan_id)
+int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, vlan_t vlan_id)
 {
 	struct hostapd_vlan *v = vlan;
 	while (v) {
-		if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
+		if (vlan_cmp(&v->vlan_id, &vlan_id) ||
+		    vlan_untagged(&v->vlan_id) == VLAN_ID_WILDCARD)
 			return 1;
 		v = v->next;
 	}
 	return 0;
 }
 
-const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
+const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
+                                        vlan_t vlan_id)
 {
 	struct hostapd_vlan *v = vlan;
 	while (v) {
-		if (v->vlan_id == vlan_id)
+		if (vlan_cmp(&v->vlan_id, &vlan_id))
 			return v->ifname;
 		v = v->next;
 	}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index e15fa9c..f6fdbfa 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -10,6 +10,7 @@ 
 #define HOSTAPD_CONFIG_H
 
 #include "common/defs.h"
+#include "common/vlan.h"
 #include "ip_addr.h"
 #include "common/wpa_common.h"
 #include "common/ieee802_11_common.h"
@@ -22,7 +23,7 @@  typedef u8 macaddr[ETH_ALEN];
 
 struct mac_acl_entry {
 	macaddr addr;
-	int vlan_id;
+	vlan_t vlan_id;
 };
 
 struct hostapd_radius_servers;
@@ -41,7 +42,7 @@  struct hostapd_wep_keys {
 };
 
 struct hostapd_vlan_wep_keys {
-	int vlan_id;
+	vlan_t vlan_id;
 	int numSTAonLastRekey;
 	struct hostapd_wep_keys key;
 };
@@ -89,7 +90,8 @@  struct hostapd_ssid {
 
 struct hostapd_vlan {
 	struct hostapd_vlan *next;
-	int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */
+	/* untagged = VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */
+	vlan_t vlan_id;
 	char ifname[IFNAMSIZ + 1];
 	int dynamic_vlan;
 #ifdef CONFIG_FULL_DYNAMIC_VLAN
@@ -546,7 +548,7 @@  struct hostapd_config * hostapd_config_defaults(void);
 void hostapd_config_defaults_bss(struct hostapd_bss_config *bss);
 void hostapd_config_free(struct hostapd_config *conf);
 int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
-			  const u8 *addr, int *vlan_id);
+			  const u8 *addr, vlan_t *vlan_id);
 int hostapd_rate_found(int *list, int rate);
 int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
 			struct hostapd_wep_keys *b);
@@ -556,8 +558,8 @@  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);
 const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
-					int vlan_id);
-int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, int vlan_id);
+					vlan_t vlan_id);
+int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, vlan_t vlan_id);
 struct hostapd_radius_attr *
 hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type);
 
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 70fab55..46d0a89 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -120,7 +120,7 @@  static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
 
 static inline int hostapd_drv_set_sta_vlan(const char *ifname,
 					   struct hostapd_data *hapd,
-					   const u8 *addr, int vlan_id)
+					   const u8 *addr, vlan_t vlan_id)
 {
 	if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
 		return 0;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 5503af1..8eb7f02 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -544,7 +544,7 @@  static void handle_auth(struct hostapd_data *hapd,
 	u16 fc;
 	const u8 *challenge = NULL;
 	u32 session_timeout, acct_interim_interval;
-	int vlan_id = 0;
+	vlan_t vlan_id = VLAN_NULL;
 	struct hostapd_sta_wpa_psk_short *psk = NULL;
 	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
 	size_t resp_ies_len = 0;
@@ -649,19 +649,21 @@  static void handle_auth(struct hostapd_data *hapd,
 		goto fail;
 	}
 
-	if (vlan_id > 0) {
+	if (vlan_notempty(&vlan_id) && vlan_untagged(&vlan_id) >= 0) {
 		if (!hostapd_vlan_id_valid(hapd->conf->vlan, vlan_id)) {
 			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
 				       HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
 				       "%d received from RADIUS server",
-				       vlan_id);
+				       vlan_untagged(&vlan_id));
 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 			goto fail;
 		}
-		sta->vlan_id = vlan_id;
+		vlan_alloc_copy(&sta->vlan_id, &vlan_id);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
-			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
+			       HOSTAPD_LEVEL_INFO, "VLAN ID %d",
+			       vlan_untagged(&sta->vlan_id));
 	}
+	vlan_free(&vlan_id);
 
 	hostapd_free_psk_list(sta->psk);
 	if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
@@ -1929,11 +1931,11 @@  static void handle_assoc_cb(struct hostapd_data *hapd,
 		 * so bind it to the selected VLAN interface now, since the
 		 * interface selection is not going to change anymore.
 		 */
-		if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
+		if (ap_sta_bind_vlan(hapd, sta, VLAN_NULL) < 0)
 			goto fail;
-	} else if (sta->vlan_id) {
+	} else if (vlan_notempty(&sta->vlan_id)) {
 		/* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
-		if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
+		if (ap_sta_bind_vlan(hapd, sta, VLAN_NULL) < 0)
 			goto fail;
 	}
 
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index c311e55..604b54a 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -35,7 +35,7 @@  struct hostapd_cached_radius_acl {
 	struct hostapd_cached_radius_acl *next;
 	u32 session_timeout;
 	u32 acct_interim_interval;
-	int vlan_id;
+	vlan_t vlan_id;
 	struct hostapd_sta_wpa_psk_short *psk;
 	char *identity;
 	char *radius_cui;
@@ -58,6 +58,7 @@  static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e)
 	os_free(e->identity);
 	os_free(e->radius_cui);
 	hostapd_free_psk_list(e->psk);
+	vlan_free(&e->vlan_id);
 	os_free(e);
 }
 
@@ -99,7 +100,7 @@  static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
 
 static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
 				 u32 *session_timeout,
-				 u32 *acct_interim_interval, int *vlan_id,
+				 u32 *acct_interim_interval, vlan_t *vlan_id,
 				 struct hostapd_sta_wpa_psk_short **psk,
 				 char **identity, char **radius_cui)
 {
@@ -121,7 +122,7 @@  static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
 			*acct_interim_interval =
 				entry->acct_interim_interval;
 		if (vlan_id)
-			*vlan_id = entry->vlan_id;
+			vlan_alloc_copy(vlan_id, &entry->vlan_id);
 		copy_psk_list(psk, entry->psk);
 		if (identity) {
 			if (entry->identity)
@@ -230,7 +231,7 @@  static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
  */
 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
 			    const u8 *msg, size_t len, u32 *session_timeout,
-			    u32 *acct_interim_interval, int *vlan_id,
+			    u32 *acct_interim_interval, vlan_t *vlan_id,
 			    struct hostapd_sta_wpa_psk_short **psk,
 			    char **identity, char **radius_cui)
 {
@@ -239,7 +240,7 @@  int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
 	if (acct_interim_interval)
 		*acct_interim_interval = 0;
 	if (vlan_id)
-		*vlan_id = 0;
+		vlan_free(vlan_id);
 	if (psk)
 		*psk = NULL;
 	if (identity)
@@ -539,7 +540,7 @@  hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
 			cache->acct_interim_interval = 0;
 		}
 
-		cache->vlan_id = radius_msg_get_vlanid(msg);
+		vlan_alloc(&cache->vlan_id, radius_msg_get_vlanid(msg));
 
 		decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
 					msg, req, cache);
diff --git a/src/ap/ieee802_11_auth.h b/src/ap/ieee802_11_auth.h
index 2bc1065..69bde7e 100644
--- a/src/ap/ieee802_11_auth.h
+++ b/src/ap/ieee802_11_auth.h
@@ -18,7 +18,7 @@  enum {
 
 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
 			    const u8 *msg, size_t len, u32 *session_timeout,
-			    u32 *acct_interim_interval, int *vlan_id,
+			    u32 *acct_interim_interval, vlan_t *vlan_id,
 			    struct hostapd_sta_wpa_psk_short **psk,
 			    char **identity, char **radius_cui);
 int hostapd_acl_init(struct hostapd_data *hapd);
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 9486516..78a260e 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -189,7 +189,7 @@  static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
 #ifndef CONFIG_NO_VLAN
 static struct hostapd_vlan_wep_keys *
 ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname,
-                       int vlan_id)
+                       vlan_t vlan_id)
 {
 	struct hostapd_vlan_wep_keys *vlan_key;
 	struct hostapd_wep_keys *key;
@@ -198,7 +198,7 @@  ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname,
 		return NULL;
 	key = &vlan_key->key;
 
-	vlan_key->vlan_id = vlan_id;
+	vlan_alloc_copy(&vlan_key->vlan_id, &vlan_id);
 	key->default_len = hapd->conf->default_wep_key_len;
 
 	if (key->idx >= hapd->conf->broadcast_key_idx_max ||
@@ -238,13 +238,13 @@  ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname,
 
 static struct hostapd_wep_keys *
 ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
-		     size_t vlan_id)
+		     vlan_t vlan_id)
 {
 	const char *ifname;
 	int i;
 	int free = -1;
 
-	if (vlan_id == 0)
+	if (!vlan_notempty(&vlan_id))
 		return &ssid->wep;
 
 	for (i = 0; i < ssid->count_dyn_vlan_keys; i++) {
@@ -253,19 +253,19 @@  ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
 			free = i;
 		if (!key)
 			continue;
-		if (key->vlan_id == vlan_id)
+		if (vlan_cmp(&key->vlan_id, &vlan_id))
 			return &key->key;
 	}
 
 	wpa_printf(MSG_DEBUG, "IEEE 802.1X: Creating new group "
-		   "state machine for VLAN ID %lu",
-		   (unsigned long) vlan_id);
+		   "state machine for VLAN ID %d",
+		    vlan_untagged(&vlan_id));
 
 	ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
 	if (ifname == NULL) {
-		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Unknown VLAN ID %lu - "
+		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Unknown VLAN ID %d - "
 			   "cannot create group key state machine",
-			   (unsigned long) vlan_id);
+			   vlan_untagged(&vlan_id));
 		return NULL;
 	}
 
@@ -299,7 +299,7 @@  void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
 	struct eapol_state_machine *sm = sta->eapol_sm;
 #ifndef CONFIG_NO_VLAN
 	struct hostapd_wep_keys *key = NULL;
-	int vlan_id;
+	vlan_t *vlan_id = NULL;
 #endif /* CONFIG_NO_VLAN */
 
 	if (sm == NULL || !sm->eap_if->eapKeyData)
@@ -309,12 +309,12 @@  void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
 		   MAC2STR(sta->addr));
 
 #ifndef CONFIG_NO_VLAN
-	vlan_id = sta->vlan_id;
-	if (vlan_id < 0 || vlan_id > MAX_VLAN_ID)
-		vlan_id = 0;
+	vlan_id = &sta->vlan_id;
+	if (vlan_untagged(vlan_id) < 0 || vlan_untagged(vlan_id) > MAX_VLAN_ID)
+		vlan_id = NULL;
 
 	if (vlan_id) {
-		key = ieee802_1x_get_group(hapd, sta->ssid, vlan_id);
+		key = ieee802_1x_get_group(hapd, sta->ssid, *vlan_id);
 		if (key && key->key[key->idx])
 			ieee802_1x_tx_key_one(hapd, sta, key->idx, 1,
 					      key->key[key->idx],
@@ -1029,7 +1029,7 @@  void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
 
 	pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
 	if (pmksa) {
-		int old_vlanid;
+		vlan_t old_vlanid = VLAN_NULL;
 
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
 			       HOSTAPD_LEVEL_DEBUG,
@@ -1044,11 +1044,12 @@  void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
 		sta->eapol_sm->authFail = FALSE;
 		if (sta->eapol_sm->eap)
 			eap_sm_notify_cached(sta->eapol_sm->eap);
-		old_vlanid = sta->vlan_id;
+		vlan_alloc_copy(&old_vlanid, &sta->vlan_id);
 		pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm);
 		if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
-			sta->vlan_id = 0;
+			vlan_free(&sta->vlan_id);
 		ap_sta_bind_vlan(hapd, sta, old_vlanid);
+		vlan_free(&old_vlanid);
 	} else {
 		if (reassoc) {
 			/*
@@ -1369,7 +1370,8 @@  ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
 	struct hostapd_data *hapd = data;
 	struct sta_info *sta;
 	u32 session_timeout = 0, termination_action, acct_interim_interval;
-	int session_timeout_set, old_vlanid = 0;
+	int session_timeout_set;
+	vlan_t old_vlanid = VLAN_NULL;
 	struct eapol_state_machine *sm;
 	int override_eapReq = 0;
 	struct radius_hdr *hdr = radius_msg_get_hdr(msg);
@@ -1438,18 +1440,20 @@  ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
 	switch (hdr->code) {
 	case RADIUS_CODE_ACCESS_ACCEPT:
 		if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
-			sta->vlan_id = 0;
+			vlan_free(&sta->vlan_id);
 #ifndef CONFIG_NO_VLAN
 		else {
-			old_vlanid = sta->vlan_id;
-			sta->vlan_id = radius_msg_get_vlanid(msg);
+			vlan_alloc_copy(&old_vlanid, &sta->vlan_id);
+			vlan_alloc(&sta->vlan_id, radius_msg_get_vlanid(msg));
 		}
-		if (sta->vlan_id > 0 &&
+		if (vlan_notempty(&sta->vlan_id) &&
+		    vlan_untagged(&sta->vlan_id) > 0 &&
 		    hostapd_vlan_id_valid(hapd->conf->vlan, sta->vlan_id)) {
 			hostapd_logger(hapd, sta->addr,
 				       HOSTAPD_MODULE_RADIUS,
 				       HOSTAPD_LEVEL_INFO,
-				       "VLAN ID %d", sta->vlan_id);
+				       "VLAN ID %d",
+				       vlan_untagged(&sta->vlan_id));
 		} else if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_REQUIRED) {
 			sta->eapol_sm->authFail = TRUE;
 			hostapd_logger(hapd, sta->addr,
@@ -1463,6 +1467,7 @@  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 ==
@@ -1586,14 +1591,16 @@  static int ieee802_1x_sta_check_group(struct hostapd_data *hapd,
 	int i;
 	struct hostapd_ssid *ssid = sta->ssid;
 
-	if (sta->vlan_id <= 0)
+	if (!vlan_notempty(&sta->vlan_id))
+		return 0;
+	if (vlan_untagged(&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)
+		if (vlan_cmp(&key->vlan_id, &sta->vlan_id))
 			continue;
 		key->numSTAonLastRekey++;
 	}
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 40972e9..0bac0de 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -44,6 +44,7 @@  static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
 #ifndef CONFIG_NO_RADIUS
 	radius_free_class(&entry->radius_class);
 #endif /* CONFIG_NO_RADIUS */
+	vlan_free(&entry->vlan_id);
 	os_free(entry);
 }
 
@@ -143,7 +144,8 @@  static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
 #endif /* CONFIG_NO_RADIUS */
 
 	entry->eap_type_authsrv = eapol->eap_type_authsrv;
-	entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id;
+	vlan_alloc_copy(&entry->vlan_id,
+	                &((struct sta_info *) eapol->sta)->vlan_id);
 }
 
 
@@ -180,7 +182,8 @@  void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
 	}
 
 	eapol->eap_type_authsrv = entry->eap_type_authsrv;
-	((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
+	vlan_alloc_copy(&((struct sta_info *) eapol->sta)->vlan_id,
+	                &entry->vlan_id);
 }
 
 
@@ -314,7 +317,7 @@  pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
 	radius_copy_class(&entry->radius_class, &old_entry->radius_class);
 #endif /* CONFIG_NO_RADIUS */
 	entry->eap_type_authsrv = old_entry->eap_type_authsrv;
-	entry->vlan_id = old_entry->vlan_id;
+	vlan_alloc_copy(&entry->vlan_id, &old_entry->vlan_id);
 	entry->opportunistic = 1;
 
 	pmksa_cache_link_entry(pmksa, entry);
diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h
index aa90024..9ebcbc4 100644
--- a/src/ap/pmksa_cache_auth.h
+++ b/src/ap/pmksa_cache_auth.h
@@ -28,7 +28,7 @@  struct rsn_pmksa_cache_entry {
 	struct wpabuf *cui;
 	struct radius_class_data radius_class;
 	u8 eap_type_authsrv;
-	int vlan_id;
+	vlan_t vlan_id;
 	int opportunistic;
 };