hostapd: Add RELOAD_BSS

When using multiple BSSes on a single radio, it is sometimes desirable
to reconfigure one BSS, without disconnecting the stations already
connected to other BSSes on the same radio.

When a BSS is reconfigured using the SET command, there is no "old"
configuration we can compare to (so we cannot compare a hash of the
configuration for example).

One possible solution would be to make the current RELOAD command
reload only the current BSS. However, that could break the workflow of
existing users. Instead, introduce a new RELOAD_BSS command, which
reloads only the current BSS.

Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
This commit is contained in:
Raphaël Mélotte 2022-08-01 13:08:26 +02:00 committed by Jouni Malinen
parent 1a27b8838a
commit af1528a128
4 changed files with 38 additions and 0 deletions

View file

@ -1384,6 +1384,16 @@ static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
} }
static int hostapd_ctrl_iface_reload_bss(struct hostapd_data *bss)
{
if (hostapd_reload_bss_only(bss) < 0) {
wpa_printf(MSG_ERROR, "Reloading of BSS failed");
return -1;
}
return 0;
}
static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface) static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
{ {
if (hostapd_disable_iface(iface) < 0) { if (hostapd_disable_iface(iface) < 0) {
@ -3376,6 +3386,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) { } else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) {
if (hostapd_ctrl_iface_reload_wpa_psk(hapd)) if (hostapd_ctrl_iface_reload_wpa_psk(hapd))
reply_len = -1; reply_len = -1;
} else if (os_strcmp(buf, "RELOAD_BSS") == 0) {
if (hostapd_ctrl_iface_reload_bss(hapd))
reply_len = -1;
} else if (os_strncmp(buf, "RELOAD", 6) == 0) { } else if (os_strncmp(buf, "RELOAD", 6) == 0) {
if (hostapd_ctrl_iface_reload(hapd->iface)) if (hostapd_ctrl_iface_reload(hapd->iface))
reply_len = -1; reply_len = -1;

View file

@ -1215,6 +1215,13 @@ static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,
} }
static int hostapd_cli_cmd_reload_bss(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_ctrl_command(ctrl, "RELOAD_BSS");
}
static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc, static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
char *argv[]) char *argv[])
{ {
@ -1679,6 +1686,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"= enable hostapd on current interface" }, "= enable hostapd on current interface" },
{ "reload", hostapd_cli_cmd_reload, NULL, { "reload", hostapd_cli_cmd_reload, NULL,
"= reload configuration for current interface" }, "= reload configuration for current interface" },
{ "reload_bss", hostapd_cli_cmd_reload_bss, NULL,
"= reload configuration for current BSS" },
{ "disable", hostapd_cli_cmd_disable, NULL, { "disable", hostapd_cli_cmd_disable, NULL,
"= disable hostapd on current interface" }, "= disable hostapd on current interface" },
{ "update_beacon", hostapd_cli_cmd_update_beacon, NULL, { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,

View file

@ -2813,6 +2813,21 @@ int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
} }
int hostapd_reload_bss_only(struct hostapd_data *bss)
{
wpa_printf(MSG_DEBUG, "Reload BSS %s", bss->conf->iface);
hostapd_set_security_params(bss->conf, 1);
if (hostapd_config_check(bss->iconf, 1) < 0) {
wpa_printf(MSG_ERROR, "Updated BSS configuration is invalid");
return -1;
}
hostapd_clear_old_bss(bss);
hostapd_reload_bss(bss);
return 0;
}
int hostapd_disable_iface(struct hostapd_iface *hapd_iface) int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
{ {
size_t j; size_t j;

View file

@ -672,6 +672,7 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
void hostapd_interface_deinit_free(struct hostapd_iface *iface); void hostapd_interface_deinit_free(struct hostapd_iface *iface);
int hostapd_enable_iface(struct hostapd_iface *hapd_iface); int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
int hostapd_reload_iface(struct hostapd_iface *hapd_iface); int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
int hostapd_reload_bss_only(struct hostapd_data *bss);
int hostapd_disable_iface(struct hostapd_iface *hapd_iface); int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
void hostapd_bss_deinit_no_free(struct hostapd_data *hapd); void hostapd_bss_deinit_no_free(struct hostapd_data *hapd);
void hostapd_free_hapd_data(struct hostapd_data *hapd); void hostapd_free_hapd_data(struct hostapd_data *hapd);