[PATCH 2/6] vlan: transform untagged/tagged vlan description into vlan_id
michael-dev at fami-braun.de
michael-dev
Mon Apr 8 09:11:11 PDT 2013
From: Michael Braun <michael-dev at fami-braun.de>
Signed-hostap: Michael Braun <michael-dev at fami-braun.de>
---
src/ap/vlan_init.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/ap/vlan_init.h | 16 ++++++++++
2 files changed, 107 insertions(+)
diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c
index c25381d..27afbc8 100644
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -35,6 +35,18 @@
#include "drivers/priv_netlink.h"
#include "utils/eloop.h"
+#endif /* CONFIG_FULL_DYNAMIC_VLAN */
+
+#ifdef CONFIG_VLAN_TAGGED
+struct vlan_info_list {
+ unsigned int counter;
+ unsigned int size;
+ struct vlan_info *vlan;
+};
+static struct vlan_info_list vlan_mapping;
+#endif /* CONFIG_VLAN_TAGGED */
+
+#ifdef CONFIG_FULL_DYNAMIC_VLAN
struct full_dynamic_vlan {
int s; /* socket on which to listen for new/removed interfaces. */
@@ -952,3 +964,82 @@ int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id)
return 0;
}
+
+#ifdef CONFIG_VLAN_TAGGED
+static int cmp_vlan(const void *a, const void *b)
+{
+ const int *ia = (const int *) a;
+ const int *ib = (const int *) b;
+ return (*ia > *ib) - (*ia < *ib);
+}
+
+/* make tagged vlans unique and sorted */
+void vlan_cleanup(struct vlan_info *a) {
+ int i, offset=0;
+ qsort(a->tagged, a->num_tagged, sizeof(int), cmp_vlan);
+ for (i=1; i < a->num_tagged; i++) {
+ if (a->tagged[i-1-offset] == a->tagged[i])
+ offset++;
+ else if (offset > 0)
+ a->tagged[i-offset] = a->tagged[i];
+ }
+ a->num_tagged -= offset;
+}
+
+int vlan_equals(struct vlan_info *a, struct vlan_info *b) {
+ int i;
+ if (!a && !b) return 1;
+ if (!a || !b) return 0;
+ if (a->untagged != b->untagged) return 0;
+ if (a->num_tagged != b->num_tagged) return 0;
+ for (i=0; i < a->num_tagged; i++)
+ if (a->tagged[i] != b->tagged[i]) return 0;
+ return 1;
+}
+
+int vlan_get_id(struct vlan_info* a) {
+ int i;
+
+ /* no tagged/untagged vlan => vlan_id = 0 */
+ if (!a) return 0;
+ if (!a->untagged && !a->num_tagged) return 0;
+
+ /* all other untagged/tagged configurations get vlan_id > 0 */
+ if(vlan_mapping.counter > vlan_mapping.size) {
+ wpa_printf(MSG_ERROR, "VLAN: internal mapping data structure is corrupt.");
+ return -1;
+ }
+ for (i=0; i < vlan_mapping.counter; i++)
+ if (vlan_equals(a, &vlan_mapping.vlan[i]))
+ return i + 1;
+ /* resize cache, amortized O(1) */
+ if (vlan_mapping.size == vlan_mapping.counter) {
+ unsigned int newsize = 2 * vlan_mapping.size;
+ if (newsize == 0)
+ newsize = 1;
+ if (newsize < vlan_mapping.size) /* overflow */
+ return -1;
+ struct vlan_info *new_vlan = os_malloc(sizeof(struct vlan_info) * newsize);
+ if (!new_vlan)
+ return -1;
+ if (vlan_mapping.size > 0)
+ os_memcpy(new_vlan, vlan_mapping.vlan, sizeof(struct vlan_info) * vlan_mapping.size);
+ os_free(vlan_mapping.vlan);
+ vlan_mapping.vlan = new_vlan; new_vlan = NULL;
+ vlan_mapping.size = newsize;
+ }
+ /* add new entry */
+ vlan_mapping.vlan[vlan_mapping.counter] = *a;
+ vlan_mapping.counter++;
+
+ char buf[IFNAMSIZ], *pos;
+ pos = buf;
+ pos += os_snprintf(pos, sizeof(buf) + buf - pos, "%d", a->untagged);
+ for (i=0; i < a->num_tagged; i++) {
+ pos += os_snprintf(pos, sizeof(buf) + buf - pos, "t%d", a->tagged[i]);
+ }
+
+ wpa_printf(MSG_DEBUG, "VLAN: assign %s to %d", buf, vlan_mapping.counter);
+ return vlan_mapping.counter;
+}
+#endif
diff --git a/src/ap/vlan_init.h b/src/ap/vlan_init.h
index 382d5de..75fda69 100644
--- a/src/ap/vlan_init.h
+++ b/src/ap/vlan_init.h
@@ -17,6 +17,12 @@
#define VLAN_INIT_H
#ifndef CONFIG_NO_VLAN
+struct vlan_info {
+ int untagged;
+ unsigned int num_tagged;
+ int* tagged;
+};
+
int vlan_init(struct hostapd_data *hapd);
void vlan_deinit(struct hostapd_data *hapd);
struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd,
@@ -26,6 +32,16 @@ int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id);
int vlan_setup_encryption_dyn(struct hostapd_data *hapd,
struct hostapd_ssid *mssid,
const char *dyn_vlan);
+#ifdef CONFIG_VLAN_TAGGED
+int vlan_get_id(struct vlan_info *a);
+void vlan_cleanup(struct vlan_info *a);
+#else
+static inline int vlan_get_id(struct vlan_info *a) {
+ if (!a) return 0;
+ return a->untagged;
+}
+#endif /* VLAN_CONFIG_TAGGED */
+
#else /* CONFIG_NO_VLAN */
static inline int vlan_init(struct hostapd_data *hapd)
{
--
1.8.1.5
More information about the Hostap
mailing list