]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Support for overriding the bridge name per VLAN via vlan_file
authorFelix Fietkau <nbd@nbd.name>
Wed, 14 Nov 2018 16:50:23 +0000 (17:50 +0100)
committerJouni Malinen <j@w1.fi>
Fri, 21 Dec 2018 10:02:57 +0000 (12:02 +0200)
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>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/vlan_full.c
src/ap/vlan_init.c

index b76d3a3b0709ed971cd8bc1b635cee8191195c26..306afcee45ca35ce584fc784de9f34e845d5cdfb 100644 (file)
@@ -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;
        }
index 75f4e4ef57550ce5d6ebfe3770490b25c9e507fb..613455984bc1c442cbb860d7077cb9bf874d5574 100644 (file)
@@ -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 <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
 
 # Interface where 802.1q tagged packets should appear when a RADIUS server is
index 902f2fc82d9e1937ea94ccb4e997bec48a6b7e11..5371d0e0d7d394b6d0e1f1cafb2822684bd739b3 100644 (file)
@@ -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
index 93cef958dfa3dbfe8ce3fccdd1c4418ce6e48a89..cb39a8f214c96fb8f57c8304f748b00a2314d4e3 100644 (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;
        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);
index 01fecee026a11b90bba17c29b431766f6ec28760..ce37fdaf9078ee92bb8541609c310f4ed298f4a3 100644 (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,
                    pos);
+       os_strlcpy(n->bridge, vlan->bridge, sizeof(n->bridge));
 
        n->next = hapd->conf->vlan;
        hapd->conf->vlan = n;