[PATCHv2 06/21] 802.1X: Make VLAN-keys a list instead of an array.
Michael Braun
michael-dev
Thu Jun 6 03:09:34 PDT 2013
Currently, 802.1X code relies on vlan_id to be a small integer
so it can use an array to keep them. When increasing the number
of VLANs supported, this no longer is feasable.
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 4c69dd6..7a3a8d9 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -453,10 +453,10 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
if (conf->ssid.dyn_vlan_keys) {
struct hostapd_ssid *ssid = &conf->ssid;
size_t i;
- for (i = 0; i <= ssid->max_dyn_vlan_keys; 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]);
+ hostapd_config_free_wep(&ssid->dyn_vlan_keys[i]->key);
os_free(ssid->dyn_vlan_keys[i]);
}
os_free(ssid->dyn_vlan_keys);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 98783fe..7ca4647 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -40,6 +40,11 @@ struct hostapd_wep_keys {
size_t default_len; /* key length used for dynamic key generation */
};
+struct hostapd_vlan_wep_keys {
+ int vlan_id;
+ struct hostapd_wep_keys key;
+};
+
typedef enum hostap_security_policy {
SECURITY_PLAINTEXT = 0,
SECURITY_STATIC_WEP = 1,
@@ -74,8 +79,8 @@ struct hostapd_ssid {
#ifdef CONFIG_FULL_DYNAMIC_VLAN
char *vlan_tagged_interface;
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
- struct hostapd_wep_keys **dyn_vlan_keys;
- size_t max_dyn_vlan_keys;
+ struct hostapd_vlan_wep_keys **dyn_vlan_keys;
+ size_t count_dyn_vlan_keys;
};
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 780b2e2..8860632 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -210,6 +210,8 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
{
int errors = 0, idx;
struct hostapd_ssid *ssid = &hapd->conf->ssid;
+ const char *ifname;
+ struct hostapd_vlan_wep_keys *key;
idx = ssid->wep.idx;
if (ssid->wep.default_len &&
@@ -223,21 +225,20 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
if (ssid->dyn_vlan_keys) {
size_t i;
- for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
- const char *ifname;
- struct hostapd_wep_keys *key = ssid->dyn_vlan_keys[i];
+ for (i = 0; i <= ssid->count_dyn_vlan_keys; i++) {
+ key = ssid->dyn_vlan_keys[i];
if (key == NULL)
continue;
ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan,
- i);
+ key->vlan_id);
if (ifname == NULL)
continue;
- idx = key->idx;
+ idx = key->key.idx;
if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_WEP,
broadcast_ether_addr, idx, 1,
- NULL, 0, key->key[idx],
- key->len[idx])) {
+ NULL, 0, key->key.key[idx],
+ key->key.len[idx])) {
wpa_printf(MSG_WARNING, "Could not set "
"dynamic VLAN WEP encryption.");
errors++;
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index d3dda14..8b5076d 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -187,15 +187,18 @@ static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
#ifndef CONFIG_NO_VLAN
-static struct hostapd_wep_keys *
-ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
+static struct hostapd_vlan_wep_keys *
+ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname,
+ int vlan_id)
{
+ struct hostapd_vlan_wep_keys *vlan_key;
struct hostapd_wep_keys *key;
-
- key = os_zalloc(sizeof(*key));
- if (key == NULL)
+ vlan_key = os_zalloc(sizeof(*vlan_key));
+ if (vlan_key == NULL)
return NULL;
+ key = &vlan_key->key;
+ vlan_key->vlan_id = vlan_id;
key->default_len = hapd->conf->default_wep_key_len;
if (key->idx >= hapd->conf->broadcast_key_idx_max ||
@@ -229,7 +232,7 @@ ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
hostapd_set_drv_ieee8021x(hapd, ifname, 1);
- return key;
+ return vlan_key;
}
@@ -238,13 +241,21 @@ ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
size_t vlan_id)
{
const char *ifname;
+ int i;
+ int free = -1;
if (vlan_id == 0)
return &ssid->wep;
- if (vlan_id <= ssid->max_dyn_vlan_keys && ssid->dyn_vlan_keys &&
- ssid->dyn_vlan_keys[vlan_id])
- return ssid->dyn_vlan_keys[vlan_id];
+ for (i = 0; i < ssid->count_dyn_vlan_keys; i++) {
+ struct hostapd_vlan_wep_keys *key = ssid->dyn_vlan_keys[i];
+ if (!key && free < 0)
+ free = i;
+ if (!key)
+ continue;
+ if (key->vlan_id == vlan_id)
+ return &key->key;
+ }
wpa_printf(MSG_DEBUG, "IEEE 802.1X: Creating new group "
"state machine for VLAN ID %lu",
@@ -258,30 +269,26 @@ ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
return NULL;
}
- if (ssid->dyn_vlan_keys == NULL) {
- int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
- ssid->dyn_vlan_keys = os_zalloc(size);
- if (ssid->dyn_vlan_keys == NULL)
- return NULL;
- ssid->max_dyn_vlan_keys = vlan_id;
- }
+ if (free < 0) {
+ /* resize array */
+ int free = ssid->count_dyn_vlan_keys; /* aka oldsize */
+ int newsize = (free == 0) ? 1 : 2 * free;
- if (ssid->max_dyn_vlan_keys < vlan_id) {
- struct hostapd_wep_keys **na;
- int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
- na = os_realloc(ssid->dyn_vlan_keys, size);
+ struct hostapd_vlan_wep_keys **na;
+ na = os_realloc_array(ssid->dyn_vlan_keys, newsize,
+ sizeof(*ssid->dyn_vlan_keys));
if (na == NULL)
return NULL;
+ os_memset(&ssid->dyn_vlan_keys[free + 1], 0,
+ (newsize - free) * sizeof(ssid->dyn_vlan_keys[0]));
ssid->dyn_vlan_keys = na;
- os_memset(&ssid->dyn_vlan_keys[ssid->max_dyn_vlan_keys + 1], 0,
- (vlan_id - ssid->max_dyn_vlan_keys) *
- sizeof(ssid->dyn_vlan_keys[0]));
- ssid->max_dyn_vlan_keys = vlan_id;
+ ssid->count_dyn_vlan_keys = newsize;
}
- ssid->dyn_vlan_keys[vlan_id] = ieee802_1x_group_alloc(hapd, ifname);
+ ssid->dyn_vlan_keys[free] = ieee802_1x_group_alloc(hapd, ifname,
+ vlan_id);
- return ssid->dyn_vlan_keys[vlan_id];
+ return &ssid->dyn_vlan_keys[free]->key;
}
#endif /* CONFIG_NO_VLAN */
More information about the Hostap
mailing list