diff --git a/hostapd/config_file.c b/hostapd/config_file.c index b76d3a3b0..306afcee4 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -37,7 +37,7 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, const char *fname) { FILE *f; - char buf[128], *pos, *pos2; + char buf[128], *pos, *pos2, *pos3; int line = 0, vlan_id; struct hostapd_vlan *vlan; @@ -82,7 +82,10 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, pos2 = pos; while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0') pos2++; - *pos2 = '\0'; + + if (*pos2 != '\0') + *(pos2++) = '\0'; + if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) { wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d " "in '%s'", line, fname); @@ -90,6 +93,13 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, return -1; } + while (*pos2 == ' ' || *pos2 == '\t') + pos2++; + pos3 = pos2; + while (*pos3 != ' ' && *pos3 != '\t' && *pos3 != '\0') + pos3++; + *pos3 = '\0'; + vlan = os_zalloc(sizeof(*vlan)); if (vlan == NULL) { wpa_printf(MSG_ERROR, "Out of memory while reading " @@ -102,6 +112,7 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss, vlan->vlan_desc.untagged = vlan_id; vlan->vlan_desc.notempty = !!vlan_id; os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname)); + os_strlcpy(vlan->bridge, pos2, sizeof(vlan->bridge)); vlan->next = bss->vlan; bss->vlan = vlan; } diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 75f4e4ef5..613455984 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1135,6 +1135,7 @@ own_ip_addr=127.0.0.1 # white space (space or tab). # If no entries are provided by this file, the station is statically mapped # to . interfaces. +# Each line can optionally also contain the name of a bridge to add the VLAN to #vlan_file=/etc/hostapd.vlan # Interface where 802.1q tagged packets should appear when a RADIUS server is diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 902f2fc82..5371d0e0d 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -123,6 +123,7 @@ struct hostapd_vlan { int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */ struct vlan_description vlan_desc; char ifname[IFNAMSIZ + 1]; + char bridge[IFNAMSIZ + 1]; int configured; int dynamic_vlan; #ifdef CONFIG_FULL_DYNAMIC_VLAN diff --git a/src/ap/vlan_full.c b/src/ap/vlan_full.c index 93cef958d..cb39a8f21 100644 --- a/src/ap/vlan_full.c +++ b/src/ap/vlan_full.c @@ -390,12 +390,16 @@ static void vlan_newlink_tagged(int vlan_naming, const char *tagged_interface, } -static void vlan_bridge_name(char *br_name, struct hostapd_data *hapd, int vid) +static void vlan_bridge_name(char *br_name, struct hostapd_data *hapd, + struct hostapd_vlan *vlan, int vid) { char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface; int ret; - if (hapd->conf->vlan_bridge[0]) { + if (vlan->bridge[0]) { + os_strlcpy(br_name, vlan->bridge, IFNAMSIZ); + ret = 0; + } else if (hapd->conf->vlan_bridge[0]) { ret = os_snprintf(br_name, IFNAMSIZ, "%s%d", hapd->conf->vlan_bridge, vid); } else if (tagged_interface) { @@ -456,7 +460,7 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) !br_addif(hapd->conf->bridge, ifname)) vlan->clean |= DVLAN_CLEAN_WLAN_PORT; } else if (untagged > 0 && untagged <= MAX_VLAN_ID) { - vlan_bridge_name(br_name, hapd, untagged); + vlan_bridge_name(br_name, hapd, vlan, untagged); vlan_get_bridge(br_name, hapd, untagged); @@ -469,7 +473,7 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd) tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID || (i > 0 && tagged[i] == tagged[i - 1])) continue; - vlan_bridge_name(br_name, hapd, tagged[i]); + vlan_bridge_name(br_name, hapd, vlan, tagged[i]); vlan_get_bridge(br_name, hapd, tagged[i]); vlan_newlink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE, ifname, br_name, tagged[i], hapd); @@ -561,7 +565,7 @@ void vlan_dellink(const char *ifname, struct hostapd_data *hapd) tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID || (i > 0 && tagged[i] == tagged[i - 1])) continue; - vlan_bridge_name(br_name, hapd, tagged[i]); + vlan_bridge_name(br_name, hapd, vlan, tagged[i]); vlan_dellink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE, ifname, br_name, tagged[i], hapd); vlan_put_bridge(br_name, hapd, tagged[i]); @@ -573,7 +577,7 @@ void vlan_dellink(const char *ifname, struct hostapd_data *hapd) (vlan->clean & DVLAN_CLEAN_WLAN_PORT)) br_delif(hapd->conf->bridge, ifname); } else if (untagged > 0 && untagged <= MAX_VLAN_ID) { - vlan_bridge_name(br_name, hapd, untagged); + vlan_bridge_name(br_name, hapd, vlan, untagged); if (vlan->clean & DVLAN_CLEAN_WLAN_PORT) br_delif(br_name, vlan->ifname); diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c index 01fecee02..ce37fdaf9 100644 --- a/src/ap/vlan_init.c +++ b/src/ap/vlan_init.c @@ -210,6 +210,7 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd, os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id, pos); + os_strlcpy(n->bridge, vlan->bridge, sizeof(n->bridge)); n->next = hapd->conf->vlan; hapd->conf->vlan = n;