aboutsummaryrefslogtreecommitdiffstats
path: root/package/network
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2023-09-15 14:25:23 +0200
committerFelix Fietkau <nbd@nbd.name>2023-09-15 14:25:27 +0200
commit50e16efd415132d2a7cee379f5183ddd907acfb2 (patch)
tree5b2ec4bf20812fcc48469c55c655e990f12ac084 /package/network
parent99515fbc367401a96724eaa257d2423e1c69a3db (diff)
downloadupstream-50e16efd415132d2a7cee379f5183ddd907acfb2.tar.gz
upstream-50e16efd415132d2a7cee379f5183ddd907acfb2.tar.bz2
upstream-50e16efd415132d2a7cee379f5183ddd907acfb2.zip
hostapd: support dynamic reload of vlan files when renaming interfaces
Avoids unnecessary AP restart on ifname changes when wifi-vlan sections are present. Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/network')
-rw-r--r--package/network/services/hostapd/files/hostapd.uc10
-rw-r--r--package/network/services/hostapd/src/src/ap/ucode.c89
2 files changed, 94 insertions, 5 deletions
diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc
index 6b6e41b6f79..ebf732bea51 100644
--- a/package/network/services/hostapd/files/hostapd.uc
+++ b/package/network/services/hostapd/files/hostapd.uc
@@ -215,6 +215,7 @@ function bss_remove_file_fields(config)
for (let key in config.hash)
new_cfg.hash[key] = config.hash[key];
delete new_cfg.hash.wpa_psk_file;
+ delete new_cfg.hash.vlan_file;
return new_cfg;
}
@@ -475,11 +476,12 @@ function iface_reload_config(phydev, config, old_config)
bss_remove_file_fields(bss_list_cfg[i]))) {
hostapd.printf(`Update config data files for bss ${ifname}`);
if (bss.set_config(config_inline, i, true) < 0) {
- hostapd.printf(`Failed to update config data files for bss ${ifname}`);
+ hostapd.printf(`Could not update config data files for bss ${ifname}`);
return false;
+ } else {
+ bss.ctrl("RELOAD_WPA_PSK");
+ continue;
}
- bss.ctrl("RELOAD_WPA_PSK");
- continue;
}
bss_reload_psk(bss, config.bss[i], bss_list_cfg[i]);
@@ -487,8 +489,6 @@ function iface_reload_config(phydev, config, old_config)
continue;
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
- hostapd.printf(`old: ${bss_remove_file_fields(bss_list_cfg[i])}`);
- hostapd.printf(`new: ${bss_remove_file_fields(config.bss[i])}`);
if (bss.set_config(config_inline, i) < 0) {
hostapd.printf(`Failed to set config for bss ${ifname}`);
return false;
diff --git a/package/network/services/hostapd/src/src/ap/ucode.c b/package/network/services/hostapd/src/src/ap/ucode.c
index 7bc797acfc6..e79f2420c07 100644
--- a/package/network/services/hostapd/src/src/ap/ucode.c
+++ b/package/network/services/hostapd/src/src/ap/ucode.c
@@ -111,6 +111,94 @@ uc_hostapd_remove_iface(uc_vm_t *vm, size_t nargs)
return NULL;
}
+static struct hostapd_vlan *
+bss_conf_find_vlan(struct hostapd_bss_config *bss, int id)
+{
+ struct hostapd_vlan *vlan;
+
+ for (vlan = bss->vlan; vlan; vlan = vlan->next)
+ if (vlan->vlan_id == id)
+ return vlan;
+
+ return NULL;
+}
+
+static int
+bss_conf_rename_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
+ const char *ifname)
+{
+ if (!strcmp(ifname, vlan->ifname))
+ return 0;
+
+ hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, vlan->ifname, ifname);
+ os_strlcpy(vlan->ifname, ifname, sizeof(vlan->ifname));
+
+ return 0;
+}
+
+static int
+bss_reload_vlans(struct hostapd_data *hapd, struct hostapd_bss_config *bss)
+{
+ struct hostapd_bss_config *old_bss = hapd->conf;
+ struct hostapd_vlan *vlan, *vlan_new, *wildcard;
+ char ifname[IFNAMSIZ + 1], vlan_ifname[IFNAMSIZ + 1], *pos;
+ int ret;
+
+ vlan = bss_conf_find_vlan(old_bss, VLAN_ID_WILDCARD);
+ wildcard = bss_conf_find_vlan(bss, VLAN_ID_WILDCARD);
+ if (!!vlan != !!wildcard)
+ return -1;
+
+ if (vlan && wildcard && strcmp(vlan->ifname, wildcard->ifname) != 0)
+ strcpy(vlan->ifname, wildcard->ifname);
+ else
+ wildcard = NULL;
+
+ for (vlan = bss->vlan; vlan; vlan = vlan->next) {
+ if (vlan->vlan_id == VLAN_ID_WILDCARD ||
+ vlan->dynamic_vlan > 0)
+ continue;
+
+ if (!bss_conf_find_vlan(old_bss, vlan->vlan_id))
+ return -1;
+ }
+
+ for (vlan = old_bss->vlan; vlan; vlan = vlan->next) {
+ if (vlan->vlan_id == VLAN_ID_WILDCARD)
+ continue;
+
+ if (vlan->dynamic_vlan == 0) {
+ vlan_new = bss_conf_find_vlan(bss, vlan->vlan_id);
+ if (!vlan_new)
+ return -1;
+
+ if (bss_conf_rename_vlan(hapd, vlan, vlan_new->ifname))
+ return -1;
+
+ continue;
+ }
+
+ if (!wildcard)
+ continue;
+
+ os_strlcpy(ifname, wildcard->ifname, sizeof(ifname));
+ pos = os_strchr(ifname, '#');
+ if (!pos)
+ return -1;
+
+ *pos++ = '\0';
+ ret = os_snprintf(vlan_ifname, sizeof(vlan_ifname), "%s%d%s",
+ ifname, vlan->vlan_id, pos);
+ if (os_snprintf_error(sizeof(vlan_ifname), ret))
+ return -1;
+
+ if (bss_conf_rename_vlan(hapd, vlan, vlan_ifname))
+ return -1;
+ }
+
+ return 0;
+}
+
static uc_value_t *
uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
{
@@ -150,6 +238,7 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
} while (0)
swap_field(ssid.wpa_psk_file);
+ ret = bss_reload_vlans(hapd, bss);
goto done;
}