openwrt/package/network/services/hostapd/patches/700-wifi-reload.patch
Felix Fietkau e56c5f7b27 hostapd: add ucode support, use ucode for the main ubus object
This implements vastly improved dynamic configuration reload support.
It can handle configuration changes on individual wifi interfaces, as well
as adding/removing interfaces.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2023-08-01 10:08:03 +02:00

233 lines
7.7 KiB
Diff

--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2420,6 +2420,8 @@ static int hostapd_config_fill(struct ho
bss->isolate = atoi(pos);
} else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
bss->ap_max_inactivity = atoi(pos);
+ } else if (os_strcmp(buf, "config_id") == 0) {
+ bss->config_id = os_strdup(pos);
} else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
bss->skip_inactivity_poll = atoi(pos);
} else if (os_strcmp(buf, "config_id") == 0) {
@@ -3130,6 +3132,8 @@ static int hostapd_config_fill(struct ho
}
} else if (os_strcmp(buf, "acs_exclude_dfs") == 0) {
conf->acs_exclude_dfs = atoi(pos);
+ } else if (os_strcmp(buf, "radio_config_id") == 0) {
+ conf->config_id = os_strdup(pos);
} else if (os_strcmp(buf, "op_class") == 0) {
conf->op_class = atoi(pos);
} else if (os_strcmp(buf, "channel") == 0) {
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -998,6 +998,7 @@ void hostapd_config_free(struct hostapd_
for (i = 0; i < conf->num_bss; i++)
hostapd_config_free_bss(conf->bss[i]);
+ os_free(conf->config_id);
os_free(conf->bss);
os_free(conf->supported_rates);
os_free(conf->basic_rates);
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -998,6 +998,7 @@ struct eht_phy_capabilities_info {
struct hostapd_config {
struct hostapd_bss_config **bss, *last_bss;
size_t num_bss;
+ char *config_id;
u16 beacon_int;
int rts_threshold;
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -127,7 +127,7 @@ void hostapd_reconfig_encryption(struct
}
-static void hostapd_reload_bss(struct hostapd_data *hapd)
+void hostapd_reload_bss(struct hostapd_data *hapd)
{
struct hostapd_ssid *ssid;
@@ -255,6 +255,10 @@ static int hostapd_iface_conf_changed(st
{
size_t i;
+ if (newconf->config_id != oldconf->config_id)
+ if (strcmp(newconf->config_id, oldconf->config_id))
+ return 1;
+
if (newconf->num_bss != oldconf->num_bss)
return 1;
@@ -268,7 +272,7 @@ static int hostapd_iface_conf_changed(st
}
-int hostapd_reload_config(struct hostapd_iface *iface)
+int hostapd_reload_config(struct hostapd_iface *iface, int reconf)
{
struct hapd_interfaces *interfaces = iface->interfaces;
struct hostapd_data *hapd = iface->bss[0];
@@ -298,6 +302,9 @@ int hostapd_reload_config(struct hostapd
char *fname;
int res;
+ if (reconf)
+ return -1;
+
hostapd_clear_old(iface);
wpa_printf(MSG_DEBUG,
@@ -324,6 +331,24 @@ int hostapd_reload_config(struct hostapd
wpa_printf(MSG_ERROR,
"Failed to enable interface on config reload");
return res;
+ } else {
+ for (j = 0; j < iface->num_bss; j++) {
+ hapd = iface->bss[j];
+ if (!hapd->config_id || strcmp(hapd->config_id, newconf->bss[j]->config_id)) {
+ hostapd_flush_old_stations(iface->bss[j],
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+#ifdef CONFIG_WEP
+ hostapd_broadcast_wep_clear(iface->bss[j]);
+#endif
+
+#ifndef CONFIG_NO_RADIUS
+ /* TODO: update dynamic data based on changed configuration
+ * items (e.g., open/close sockets, etc.) */
+ radius_client_flush(iface->bss[j]->radius, 0);
+#endif /* CONFIG_NO_RADIUS */
+ wpa_printf(MSG_INFO, "bss %zu changed", j);
+ }
+ }
}
iface->conf = newconf;
@@ -340,6 +365,12 @@ int hostapd_reload_config(struct hostapd
for (j = 0; j < iface->num_bss; j++) {
hapd = iface->bss[j];
+ if (hapd->config_id) {
+ os_free(hapd->config_id);
+ hapd->config_id = NULL;
+ }
+ if (newconf->bss[j]->config_id)
+ hapd->config_id = strdup(newconf->bss[j]->config_id);
if (!hapd->conf->config_id || !newconf->bss[j]->config_id ||
os_strcmp(hapd->conf->config_id,
newconf->bss[j]->config_id) != 0)
@@ -1236,8 +1267,7 @@ static int hostapd_start_beacon(struct h
* initialized. Most of the modules that are initialized here will be
* deinitialized in hostapd_cleanup().
*/
-static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
- bool start_beacon)
+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon)
{
struct hostapd_bss_config *conf = hapd->conf;
u8 ssid[SSID_MAX_LEN + 1];
@@ -2705,6 +2735,10 @@ hostapd_alloc_bss_data(struct hostapd_if
hapd->iconf = conf;
hapd->conf = bss;
hapd->iface = hapd_iface;
+ if (bss && bss->config_id)
+ hapd->config_id = strdup(bss->config_id);
+ else
+ hapd->config_id = NULL;
if (conf)
hapd->driver = conf->driver;
hapd->ctrl_sock = -1;
@@ -2723,7 +2757,7 @@ hostapd_alloc_bss_data(struct hostapd_if
}
-static void hostapd_bss_deinit(struct hostapd_data *hapd)
+void hostapd_bss_deinit(struct hostapd_data *hapd)
{
if (!hapd)
return;
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -48,7 +48,7 @@ struct mesh_conf;
struct hostapd_iface;
struct hapd_interfaces {
- int (*reload_config)(struct hostapd_iface *iface);
+ int (*reload_config)(struct hostapd_iface *iface, int reconf);
struct hostapd_config * (*config_read_cb)(const char *config_fname);
int (*ctrl_iface_init)(struct hostapd_data *hapd);
void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
@@ -192,6 +192,7 @@ struct hostapd_data {
struct hostapd_bss_config *conf;
struct hostapd_ubus_bss ubus;
struct hostapd_ucode_bss ucode;
+ char *config_id;
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
@@ -696,7 +697,9 @@ struct hostapd_iface {
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
int (*cb)(struct hostapd_iface *iface,
void *ctx), void *ctx);
-int hostapd_reload_config(struct hostapd_iface *iface);
+int hostapd_reload_config(struct hostapd_iface *iface, int reconf);
+void hostapd_reload_bss(struct hostapd_data *hapd);
+void hostapd_bss_deinit(struct hostapd_data *hapd);
void hostapd_reconfig_encryption(struct hostapd_data *hapd);
struct hostapd_data *
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
@@ -713,6 +716,7 @@ struct hostapd_iface * hostapd_init(stru
struct hostapd_iface *
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
const char *config_fname, int debug);
+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon);
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
int reassoc);
void hostapd_interface_deinit_free(struct hostapd_iface *iface);
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5322,6 +5322,9 @@ static int wpa_driver_nl80211_set_ap(voi
if (ret) {
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
ret, strerror(-ret));
+ if (!bss->flink->beacon_set)
+ ret = 0;
+ bss->flink->beacon_set = 0;
} else {
link->beacon_set = 1;
nl80211_set_bss(bss, params->cts_protect, params->preamble,
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -187,7 +187,7 @@ static int hostapd_ctrl_iface_update(str
iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read;
reload_opts = txt;
- hostapd_reload_config(iface);
+ hostapd_reload_config(iface, 0);
iface->interfaces->config_read_cb = config_read_cb;
}
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -410,7 +410,7 @@ static void handle_term(int sig, void *s
static int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
{
- if (hostapd_reload_config(iface) < 0) {
+ if (hostapd_reload_config(iface, 0) < 0) {
wpa_printf(MSG_WARNING, "Failed to read new configuration "
"file - continuing with old.");
}
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -315,7 +315,7 @@ static void wps_reload_config(void *eloo
wpa_printf(MSG_DEBUG, "WPS: Reload configuration data");
if (iface->interfaces == NULL ||
- iface->interfaces->reload_config(iface) < 0) {
+ iface->interfaces->reload_config(iface, 1) < 0) {
wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated "
"configuration");
}