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@xxxxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap