[PATCHv2 04/12] vlan: actually add tagged vlans to AP_VLAN
Michael Braun
michael-dev at fami-braun.de
Sun Dec 6 12:47:35 PST 2015
This patch makes vlan_newlink and vlan_dellink add tagged vlans to AP_VLAN
interfaces as given by struct vlan_description.
hostapd_vlan_if_remove is done in vlan_dellink as tagged
interfaces need to be removed before the interface can be
deleted and a DELLINK message can be generated.
Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
src/ap/vlan_init.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 42 insertions(+), 5 deletions(-)
diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c
index 73de433..85260d6 100644
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -683,7 +683,7 @@ static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
{
char br_name[IFNAMSIZ];
struct hostapd_vlan *vlan;
- int untagged;
+ int untagged, *tagged, i;
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);
@@ -696,6 +696,7 @@ static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
vlan->configured = 1;
untagged = vlan->vlan_desc.untagged;
+ tagged = vlan->vlan_desc.tagged;
if (untagged > 0 && untagged <= MAX_VLAN_ID) {
vlan_bridge_name(br_name, hapd, untagged);
@@ -706,6 +707,19 @@ static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
vlan->clean |= DVLAN_CLEAN_WLAN_PORT;
}
+ for (i = 0; i < MAX_NUM_TAGGED_VLAN && tagged[i]; i++) {
+ if (tagged[i] == untagged)
+ continue;
+ if (tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID)
+ continue;
+ if (i > 0 && tagged[i] == tagged[i-1])
+ continue;
+ vlan_bridge_name(br_name, hapd, tagged[i]);
+ vlan_get_bridge(br_name, hapd, tagged[i]);
+ vlan_newlink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE,
+ ifname, br_name, tagged[i], hapd);
+ }
+
ifconfig_up(ifname);
break;
@@ -759,7 +773,7 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd)
{
struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan;
char br_name[IFNAMSIZ];
- int untagged;
+ int untagged, i, *tagged;
wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname);
@@ -776,6 +790,20 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd)
goto skip_counting;
untagged = vlan->vlan_desc.untagged;
+ tagged = vlan->vlan_desc.tagged;
+
+ for (i = 0; i < MAX_NUM_TAGGED_VLAN && tagged[i]; i++) {
+ if (tagged[i] == untagged)
+ continue;
+ if (tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID)
+ continue;
+ if (i > 0 && tagged[i] == tagged[i-1])
+ continue;
+ vlan_bridge_name(br_name, hapd, tagged[i]);
+ vlan_dellink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE,
+ ifname, br_name, tagged[i], hapd);
+ vlan_put_bridge(br_name, hapd, tagged[i]);
+ }
if (untagged > 0 && untagged <= MAX_VLAN_ID) {
vlan_bridge_name(br_name, hapd, untagged);
@@ -787,6 +815,13 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd)
}
skip_counting:
+ /* ensure this vlan interface is actually removed even if
+ * NEWLINK message is only received later */
+ if (if_nametoindex(vlan->ifname) && vlan_if_remove(hapd, vlan))
+ wpa_printf(MSG_ERROR, "VLAN: Could not remove VLAN "
+ "iface: %s: %s",
+ vlan->ifname, strerror(errno));
+
if (vlan == first)
hapd->conf->vlan = vlan->next;
else
@@ -1003,15 +1038,17 @@ static void vlan_dynamic_remove(struct hostapd_data *hapd,
while (vlan) {
next = vlan->next;
+#ifdef CONFIG_FULL_DYNAMIC_VLAN
+ /* vlan_dellink takes care of cleanup and interface removal */
+ if (vlan->vlan_id != VLAN_ID_WILDCARD)
+ vlan_dellink(vlan->ifname, hapd);
+#else
if (vlan->vlan_id != VLAN_ID_WILDCARD &&
vlan_if_remove(hapd, vlan)) {
wpa_printf(MSG_ERROR, "VLAN: Could not remove VLAN "
"iface: %s: %s",
vlan->ifname, strerror(errno));
}
-#ifdef CONFIG_FULL_DYNAMIC_VLAN
- if (vlan->clean)
- vlan_dellink(vlan->ifname, hapd);
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
vlan = next;
--
2.1.4
More information about the Hostap
mailing list