hostapd: Support for overriding the bridge name per VLAN via vlan_file

This makes it easier to integrate dynamic VLANs in custom network
configurations. The bridge name is added after the interface name in the
vlan_file line, also separated by whitespace.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Felix Fietkau 2018-11-14 17:50:23 +01:00 committed by Jouni Malinen
parent d2b5138116
commit 4d663233e6
5 changed files with 26 additions and 8 deletions

View file

@ -37,7 +37,7 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
const char *fname) const char *fname)
{ {
FILE *f; FILE *f;
char buf[128], *pos, *pos2; char buf[128], *pos, *pos2, *pos3;
int line = 0, vlan_id; int line = 0, vlan_id;
struct hostapd_vlan *vlan; struct hostapd_vlan *vlan;
@ -82,7 +82,10 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
pos2 = pos; pos2 = pos;
while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0') while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
pos2++; pos2++;
*pos2 = '\0';
if (*pos2 != '\0')
*(pos2++) = '\0';
if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) { if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d " wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d "
"in '%s'", line, fname); "in '%s'", line, fname);
@ -90,6 +93,13 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
return -1; return -1;
} }
while (*pos2 == ' ' || *pos2 == '\t')
pos2++;
pos3 = pos2;
while (*pos3 != ' ' && *pos3 != '\t' && *pos3 != '\0')
pos3++;
*pos3 = '\0';
vlan = os_zalloc(sizeof(*vlan)); vlan = os_zalloc(sizeof(*vlan));
if (vlan == NULL) { if (vlan == NULL) {
wpa_printf(MSG_ERROR, "Out of memory while reading " 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.untagged = vlan_id;
vlan->vlan_desc.notempty = !!vlan_id; vlan->vlan_desc.notempty = !!vlan_id;
os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname)); os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
os_strlcpy(vlan->bridge, pos2, sizeof(vlan->bridge));
vlan->next = bss->vlan; vlan->next = bss->vlan;
bss->vlan = vlan; bss->vlan = vlan;
} }

View file

@ -1135,6 +1135,7 @@ own_ip_addr=127.0.0.1
# white space (space or tab). # white space (space or tab).
# If no entries are provided by this file, the station is statically mapped # If no entries are provided by this file, the station is statically mapped
# to <bss-iface>.<vlan-id> interfaces. # to <bss-iface>.<vlan-id> interfaces.
# Each line can optionally also contain the name of a bridge to add the VLAN to
#vlan_file=/etc/hostapd.vlan #vlan_file=/etc/hostapd.vlan
# Interface where 802.1q tagged packets should appear when a RADIUS server is # Interface where 802.1q tagged packets should appear when a RADIUS server is

View file

@ -123,6 +123,7 @@ struct hostapd_vlan {
int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */ int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */
struct vlan_description vlan_desc; struct vlan_description vlan_desc;
char ifname[IFNAMSIZ + 1]; char ifname[IFNAMSIZ + 1];
char bridge[IFNAMSIZ + 1];
int configured; int configured;
int dynamic_vlan; int dynamic_vlan;
#ifdef CONFIG_FULL_DYNAMIC_VLAN #ifdef CONFIG_FULL_DYNAMIC_VLAN

View file

@ -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; char *tagged_interface = hapd->conf->ssid.vlan_tagged_interface;
int ret; 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", ret = os_snprintf(br_name, IFNAMSIZ, "%s%d",
hapd->conf->vlan_bridge, vid); hapd->conf->vlan_bridge, vid);
} else if (tagged_interface) { } else if (tagged_interface) {
@ -456,7 +460,7 @@ void vlan_newlink(const char *ifname, struct hostapd_data *hapd)
!br_addif(hapd->conf->bridge, ifname)) !br_addif(hapd->conf->bridge, ifname))
vlan->clean |= DVLAN_CLEAN_WLAN_PORT; vlan->clean |= DVLAN_CLEAN_WLAN_PORT;
} else if (untagged > 0 && untagged <= MAX_VLAN_ID) { } 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); 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 || tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID ||
(i > 0 && tagged[i] == tagged[i - 1])) (i > 0 && tagged[i] == tagged[i - 1]))
continue; 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_get_bridge(br_name, hapd, tagged[i]);
vlan_newlink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE, vlan_newlink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE,
ifname, br_name, tagged[i], hapd); 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 || tagged[i] <= 0 || tagged[i] > MAX_VLAN_ID ||
(i > 0 && tagged[i] == tagged[i - 1])) (i > 0 && tagged[i] == tagged[i - 1]))
continue; 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, vlan_dellink_tagged(DYNAMIC_VLAN_NAMING_WITH_DEVICE,
ifname, br_name, tagged[i], hapd); ifname, br_name, tagged[i], hapd);
vlan_put_bridge(br_name, hapd, tagged[i]); 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)) (vlan->clean & DVLAN_CLEAN_WLAN_PORT))
br_delif(hapd->conf->bridge, ifname); br_delif(hapd->conf->bridge, ifname);
} else if (untagged > 0 && untagged <= MAX_VLAN_ID) { } 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) if (vlan->clean & DVLAN_CLEAN_WLAN_PORT)
br_delif(br_name, vlan->ifname); br_delif(br_name, vlan->ifname);

View file

@ -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, os_snprintf(n->ifname, sizeof(n->ifname), "%s%d%s", ifname, vlan_id,
pos); pos);
os_strlcpy(n->bridge, vlan->bridge, sizeof(n->bridge));
n->next = hapd->conf->vlan; n->next = hapd->conf->vlan;
hapd->conf->vlan = n; hapd->conf->vlan = n;