VLAN: Factor out per-vid code in newlink/dellink

To prepare for adding tagged VLAN support in vlan_init.c, vlan_newlink()
and vlan_dellink() are split into multiple functions. This reduces
indention and eases adding tagged VLANs as well.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
This commit is contained in:
Michael Braun 2016-01-21 14:51:58 +01:00 committed by Jouni Malinen
parent 8e44c192da
commit f9c00188ca

View File

@ -623,56 +623,22 @@ static int vlan_set_name_type(unsigned int name_type)
#endif /* CONFIG_VLAN_NETLINK */ #endif /* CONFIG_VLAN_NETLINK */
static void vlan_newlink(char *ifname, struct hostapd_data *hapd) static void vlan_newlink_tagged(int vlan_naming, const char *tagged_interface,
const char *br_name, int vid,
struct hostapd_data *hapd)
{ {
char vlan_ifname[IFNAMSIZ]; char vlan_ifname[IFNAMSIZ];
char br_name[IFNAMSIZ]; int clean;
struct hostapd_vlan *vlan = hapd->conf->vlan;
char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
int vlan_naming = hapd->conf->ssid.vlan_naming;
int clean, untagged;
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname); if (vlan_naming == DYNAMIC_VLAN_NAMING_WITH_DEVICE)
os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s.%d",
while (vlan) { tagged_interface, vid);
untagged = vlan->vlan_desc.untagged;
if (os_strcmp(ifname, vlan->ifname) == 0 && !vlan->configured) {
vlan->configured = 1;
if (hapd->conf->vlan_bridge[0]) {
os_snprintf(br_name, sizeof(br_name), "%s%d",
hapd->conf->vlan_bridge,
untagged);
} else if (tagged_interface) {
os_snprintf(br_name, sizeof(br_name),
"br%s.%d", tagged_interface,
untagged);
} else {
os_snprintf(br_name, sizeof(br_name),
"brvlan%d", untagged);
}
dyn_iface_get(hapd, br_name,
br_addbr(br_name) ? 0 : DVLAN_CLEAN_BR);
ifconfig_up(br_name);
if (tagged_interface) {
if (vlan_naming ==
DYNAMIC_VLAN_NAMING_WITH_DEVICE)
os_snprintf(vlan_ifname,
sizeof(vlan_ifname),
"%s.%d", tagged_interface,
untagged);
else else
os_snprintf(vlan_ifname, os_snprintf(vlan_ifname, sizeof(vlan_ifname), "vlan%d", vid);
sizeof(vlan_ifname),
"vlan%d", untagged);
clean = 0; clean = 0;
ifconfig_up(tagged_interface); ifconfig_up(tagged_interface);
if (!vlan_add(tagged_interface, untagged, if (!vlan_add(tagged_interface, vid, vlan_ifname))
vlan_ifname))
clean |= DVLAN_CLEAN_VLAN; clean |= DVLAN_CLEAN_VLAN;
if (!br_addif(br_name, vlan_ifname)) if (!br_addif(br_name, vlan_ifname))
@ -681,64 +647,87 @@ static void vlan_newlink(char *ifname, struct hostapd_data *hapd)
dyn_iface_get(hapd, vlan_ifname, clean); dyn_iface_get(hapd, vlan_ifname, clean);
ifconfig_up(vlan_ifname); ifconfig_up(vlan_ifname);
} }
if (!br_addif(br_name, ifname))
vlan->clean |= DVLAN_CLEAN_WLAN_PORT;
ifconfig_up(ifname); static void vlan_bridge_name(char *br_name, struct hostapd_data *hapd, int vid)
{
char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
break; if (hapd->conf->vlan_bridge[0]) {
} os_snprintf(br_name, IFNAMSIZ, "%s%d",
vlan = vlan->next; hapd->conf->vlan_bridge, vid);
} else if (tagged_interface) {
os_snprintf(br_name, IFNAMSIZ, "br%s.%d",
tagged_interface, vid);
} else {
os_snprintf(br_name, IFNAMSIZ, "brvlan%d", vid);
} }
} }
static void vlan_dellink(char *ifname, struct hostapd_data *hapd) static void vlan_get_bridge(const char *br_name, struct hostapd_data *hapd,
int vid)
{ {
char vlan_ifname[IFNAMSIZ];
char br_name[IFNAMSIZ];
struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan;
char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
int vlan_naming = hapd->conf->ssid.vlan_naming; int vlan_naming = hapd->conf->ssid.vlan_naming;
int clean, untagged;
wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname); dyn_iface_get(hapd, br_name, br_addbr(br_name) ? 0 : DVLAN_CLEAN_BR);
first = prev = vlan; ifconfig_up(br_name);
if (tagged_interface)
vlan_newlink_tagged(vlan_naming, tagged_interface, br_name,
vid, hapd);
}
static void vlan_newlink(const char *ifname, struct hostapd_data *hapd)
{
char br_name[IFNAMSIZ];
struct hostapd_vlan *vlan;
int untagged;
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);
for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) {
if (vlan->configured ||
os_strcmp(ifname, vlan->ifname) != 0)
continue;
break;
}
if (!vlan)
return;
vlan->configured = 1;
while (vlan) {
untagged = vlan->vlan_desc.untagged; untagged = vlan->vlan_desc.untagged;
if (os_strcmp(ifname, vlan->ifname) == 0 &&
vlan->configured) { if (untagged > 0 && untagged <= MAX_VLAN_ID) {
if (hapd->conf->vlan_bridge[0]) { vlan_bridge_name(br_name, hapd, untagged);
os_snprintf(br_name, sizeof(br_name), "%s%d",
hapd->conf->vlan_bridge, vlan_get_bridge(br_name, hapd, untagged);
untagged);
} else if (tagged_interface) { if (!br_addif(br_name, ifname))
os_snprintf(br_name, sizeof(br_name), vlan->clean |= DVLAN_CLEAN_WLAN_PORT;
"br%s.%d", tagged_interface,
untagged);
} else {
os_snprintf(br_name, sizeof(br_name),
"brvlan%d", untagged);
} }
if (vlan->clean & DVLAN_CLEAN_WLAN_PORT) ifconfig_up(ifname);
br_delif(br_name, vlan->ifname); }
if (tagged_interface) {
if (vlan_naming == static void vlan_dellink_tagged(int vlan_naming, const char *tagged_interface,
DYNAMIC_VLAN_NAMING_WITH_DEVICE) const char *br_name, int vid,
os_snprintf(vlan_ifname, struct hostapd_data *hapd)
sizeof(vlan_ifname), {
"%s.%d", tagged_interface, char vlan_ifname[IFNAMSIZ];
untagged); int clean;
if (vlan_naming == DYNAMIC_VLAN_NAMING_WITH_DEVICE)
os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s.%d",
tagged_interface, vid);
else else
os_snprintf(vlan_ifname, os_snprintf(vlan_ifname, sizeof(vlan_ifname), "vlan%d", vid);
sizeof(vlan_ifname),
"vlan%d", untagged);
clean = dyn_iface_put(hapd, vlan_ifname); clean = dyn_iface_put(hapd, vlan_ifname);
@ -749,29 +738,67 @@ static void vlan_dellink(char *ifname, struct hostapd_data *hapd)
ifconfig_down(vlan_ifname); ifconfig_down(vlan_ifname);
vlan_rem(vlan_ifname); vlan_rem(vlan_ifname);
} }
} }
static void vlan_put_bridge(const char *br_name, struct hostapd_data *hapd,
int vid)
{
int clean;
char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
int vlan_naming = hapd->conf->ssid.vlan_naming;
if (tagged_interface)
vlan_dellink_tagged(vlan_naming, tagged_interface, br_name,
vid, hapd);
clean = dyn_iface_put(hapd, br_name); clean = dyn_iface_put(hapd, br_name);
if ((clean & DVLAN_CLEAN_BR) && if ((clean & DVLAN_CLEAN_BR) && br_getnumports(br_name) == 0) {
br_getnumports(br_name) == 0) {
ifconfig_down(br_name); ifconfig_down(br_name);
br_delbr(br_name); br_delbr(br_name);
} }
} }
if (os_strcmp(ifname, vlan->ifname) == 0) {
if (vlan == first) {
hapd->conf->vlan = vlan->next;
} else {
prev->next = vlan->next;
}
os_free(vlan);
break; static void vlan_dellink(const char *ifname, struct hostapd_data *hapd)
} {
struct hostapd_vlan *first, *prev, *vlan = hapd->conf->vlan;
wpa_printf(MSG_DEBUG, "VLAN: vlan_dellink(%s)", ifname);
first = prev = vlan;
while (vlan) {
if (os_strcmp(ifname, vlan->ifname) != 0) {
prev = vlan; prev = vlan;
vlan = vlan->next; vlan = vlan->next;
continue;
} }
break;
}
if (!vlan)
return;
if (vlan->configured) {
int untagged = vlan->vlan_desc.untagged;
char br_name[IFNAMSIZ];
if (untagged > 0 && untagged <= MAX_VLAN_ID) {
vlan_bridge_name(br_name, hapd, untagged);
if (vlan->clean & DVLAN_CLEAN_WLAN_PORT)
br_delif(br_name, vlan->ifname);
vlan_put_bridge(br_name, hapd, untagged);
}
}
if (vlan == first)
hapd->conf->vlan = vlan->next;
else
prev->next = vlan->next;
os_free(vlan);
} }