AP MLD: Add support for hostapd_cli to disable/enable AP MLD
Existing commands ENABLE/DISABLE only enable/disable the corresponding link. To disable all links, multiple calls from different control interfaces would be needed. Add new commands "disable_mld" and "enable_mld" for hostapd_cli to support disabling/enabling AP MLD for convenience. Signed-off-by: Chenming Huang <quic_chenhuan@quicinc.com>
This commit is contained in:
parent
0102c5c606
commit
9a47ede871
2 changed files with 122 additions and 0 deletions
|
@ -3457,6 +3457,104 @@ static int hostapd_ctrl_iface_driver_cmd(struct hostapd_data *hapd, char *cmd,
|
|||
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
|
||||
static int hostapd_ctrl_iface_enable_mld(struct hostapd_iface *iface)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!iface || !iface->bss[0]->conf->mld_ap) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Trying to enable AP MLD on an interface that is not affiliated with an AP MLD");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < iface->interfaces->count; ++i) {
|
||||
struct hostapd_iface *h_iface = iface->interfaces->iface[i];
|
||||
struct hostapd_data *h_hapd = h_iface->bss[0];
|
||||
struct hostapd_bss_config *h_conf = h_hapd->conf;
|
||||
|
||||
if (!h_conf->mld_ap ||
|
||||
h_conf->mld_id != iface->bss[0]->conf->mld_id)
|
||||
continue;
|
||||
|
||||
if (hostapd_enable_iface(h_iface)) {
|
||||
wpa_printf(MSG_ERROR, "Enabling of AP MLD failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_disable_iface_bss(struct hostapd_iface *iface)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < iface->num_bss; i++)
|
||||
hostapd_bss_deinit_no_free(iface->bss[i]);
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
|
||||
{
|
||||
unsigned int i;
|
||||
struct hostapd_iface *first_iface = NULL;
|
||||
|
||||
if (!iface || !iface->bss[0]->conf->mld_ap) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Trying to disable AP MLD on an interface that is not affiliated with an AP MLD.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* First, disable BSSs before stopping beaconing and doing driver
|
||||
* deinit so that the broadcast Deauthentication frames go out. */
|
||||
|
||||
for (i = 0; i < iface->interfaces->count; ++i) {
|
||||
struct hostapd_iface *h_iface = iface->interfaces->iface[i];
|
||||
struct hostapd_data *h_hapd = h_iface->bss[0];
|
||||
struct hostapd_bss_config *h_conf = h_hapd->conf;
|
||||
|
||||
if (!h_conf->mld_ap ||
|
||||
h_conf->mld_id != iface->bss[0]->conf->mld_id)
|
||||
continue;
|
||||
|
||||
if (!h_hapd->mld_first_bss) {
|
||||
first_iface = h_iface;
|
||||
continue;
|
||||
}
|
||||
hostapd_disable_iface_bss(iface);
|
||||
}
|
||||
|
||||
if (first_iface)
|
||||
hostapd_disable_iface_bss(first_iface);
|
||||
|
||||
/* Then, fully disable interfaces */
|
||||
|
||||
for (i = 0; i < iface->interfaces->count; ++i) {
|
||||
struct hostapd_iface *h_iface = iface->interfaces->iface[i];
|
||||
struct hostapd_data *h_hapd = h_iface->bss[0];
|
||||
struct hostapd_bss_config *h_conf = h_hapd->conf;
|
||||
|
||||
if (!h_conf->mld_ap ||
|
||||
h_conf->mld_id != iface->bss[0]->conf->mld_id ||
|
||||
!h_hapd->mld_first_bss)
|
||||
continue;
|
||||
|
||||
if (hostapd_disable_iface(h_iface)) {
|
||||
wpa_printf(MSG_ERROR, "Disabling AP MLD failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_iface && hostapd_disable_iface(first_iface)) {
|
||||
wpa_printf(MSG_ERROR, "Disabling AP MLD failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
static int hostapd_ctrl_iface_link_remove(struct hostapd_data *hapd, char *cmd,
|
||||
char *buf, size_t buflen)
|
||||
|
@ -4044,6 +4142,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
|
|||
reply_size);
|
||||
#endif /* ANDROID */
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
} else if (os_strcmp(buf, "ENABLE_MLD") == 0) {
|
||||
if (hostapd_ctrl_iface_enable_mld(hapd->iface))
|
||||
reply_len = -1;
|
||||
} else if (os_strcmp(buf, "DISABLE_MLD") == 0) {
|
||||
if (hostapd_ctrl_iface_disable_mld(hapd->iface))
|
||||
reply_len = -1;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
} else if (os_strncmp(buf, "LINK_REMOVE ", 12) == 0) {
|
||||
if (hostapd_ctrl_iface_link_remove(hapd, buf + 12,
|
||||
|
|
|
@ -1249,6 +1249,20 @@ static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
|
|||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_enable_mld(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
return wpa_ctrl_command(ctrl, "ENABLE_MLD");
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_disable_mld(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
return wpa_ctrl_command(ctrl, "DISABLE_MLD");
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
|
@ -1739,6 +1753,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
|||
"= reload configuration for current interface" },
|
||||
{ "disable", hostapd_cli_cmd_disable, NULL,
|
||||
"= disable hostapd on current interface" },
|
||||
{ "enable_mld", hostapd_cli_cmd_enable_mld, NULL,
|
||||
"= enable AP MLD to which the interface is affiliated" },
|
||||
{ "disable_mld", hostapd_cli_cmd_disable_mld, NULL,
|
||||
"= disable AP MLD to which the interface is affiliated" },
|
||||
{ "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
|
||||
"= update Beacon frame contents\n"},
|
||||
{ "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
|
||||
|
|
Loading…
Reference in a new issue