[PATCH v2] AP: Introduce support for testing ML link enable
Lorenzo Bianconi
lorenzo at kernel.org
Thu Apr 9 01:52:05 PDT 2026
From: StanleyYP Wang <StanleyYP.Wang at mediatek.com>
Introduce LINK_ENABLE control interface command in order to enable a link
previously removed via hostapd_cli remove_link command.
The LINK_ENABLE command relies on the following syntax:
$hostapd_cli -i <interface> link_enable bss_conf=<phy>:<config-file>
Similar to ML link removal support added in commit 'd95838b7932b
("AP: Add support for testing ML link removal")', compile LINK_ENABLE
control interface command just if CONFIG_TESTING_OPTIONS is enabled
since it depends on remove_link counterpart.
Signed-off-by: StanleyYP Wang <StanleyYP.Wang at mediatek.com>
Co-developed-by: Lorenzo Bianconi <lorenzo at kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
Changes in v2:
- Fix compilation errors
- Rename the command in "link_enable" and limit it to enable link
previously removed via hostapd_cli remove_link command.
---
hostapd/ctrl_iface.c | 87 +++++++++++++++++++++++++++++++++++++++++++
hostapd/hostapd_cli.c | 10 +++++
2 files changed, 97 insertions(+)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index d14b2660f..deb91bc7f 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -3576,6 +3576,89 @@ static int hostapd_ctrl_iface_link_remove(struct hostapd_data *hapd, char *cmd,
return ret;
}
+
+
+static int hostapd_ctrl_iface_link_enable(struct hostapd_data *hapd, char *cmd,
+ char *buf, size_t buflen)
+{
+ struct hapd_interfaces *interfaces = hapd->iface->interfaces;
+ const char *conf_file, *phy, *ifname;
+ struct hostapd_iface *iface = NULL;
+ size_t len = os_strlen(cmd) + 1;
+ struct hostapd_config *conf;
+ char *pos, *cmd_buf;
+ int ret = -1;
+ size_t i;
+
+ if (!hapd || !hapd->conf->mld_ap || !hapd->mld)
+ return -1;
+
+ if (os_strncmp(cmd, "bss_config=", 11))
+ return -1;
+
+ cmd_buf = os_malloc(len);
+ if (!cmd_buf)
+ return -1;
+
+ os_snprintf(cmd_buf, len, "%s", cmd);
+ phy = cmd_buf + 11;
+ pos = os_strchr(phy, ':');
+ if (!pos)
+ goto free_cmd_buffer;
+
+ *pos++ = '\0';
+ conf_file = pos;
+ if (!os_strlen(conf_file))
+ goto free_cmd_buffer;
+
+ conf = interfaces->config_read_cb(conf_file);
+ if (!conf)
+ goto free_cmd_buffer;
+
+ if (!conf->bss[0]->mld_ap)
+ goto free_config;
+
+ ifname = conf->bss[0]->iface;
+ if (!ifname || ifname[0] == '\0')
+ goto free_config;
+
+ for (i = 0; i < interfaces->count; i++) {
+ if (!os_strcmp(interfaces->iface[i]->phy, phy)) {
+ iface = interfaces->iface[i];
+ break;
+ }
+ }
+
+ if (!iface || iface->state != HAPD_IFACE_DISABLED)
+ goto free_config;
+
+ for (i = 0; i < iface->num_bss; i++) {
+ struct hostapd_data *h = iface->bss[i];
+
+ if (os_strncmp(ifname, h->conf->iface,
+ sizeof(h->conf->iface)))
+ continue;
+
+ ret = hostapd_enable_iface(iface);
+ break;
+ }
+
+ if (ret < 0)
+ goto free_config;
+
+ ret = os_snprintf(buf, buflen, "%s\n", "OK");
+ if (os_snprintf_error(buflen, ret))
+ ret = -1;
+ else
+ ret = 0;
+
+free_config:
+ hostapd_config_free(conf);
+free_cmd_buffer:
+ os_free(cmd_buf);
+
+ return ret;
+}
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_IEEE80211BE */
@@ -4566,6 +4649,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
if (hostapd_ctrl_iface_link_remove(hapd, buf + 12,
reply, reply_size))
reply_len = -1;
+ } else if (os_strncmp(buf, "LINK_ENABLE ", 12) == 0) {
+ if (hostapd_ctrl_iface_link_enable(hapd, buf + 12, reply,
+ reply_size))
+ reply_len = -1;
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_SAE
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index cb42f3052..16f70fa23 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1293,6 +1293,13 @@ static int hostapd_cli_cmd_remove_link(struct wpa_ctrl *ctrl, int argc,
return wpa_ctrl_command(ctrl, buf);
}
+
+
+static int hostapd_cli_cmd_link_enable(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return hostapd_cli_cmd(ctrl, "LINK_ENABLE", 1, argc, argv);
+}
#endif /* CONFIG_TESTING_OPTIONS */
@@ -1821,6 +1828,9 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
#ifdef CONFIG_TESTING_OPTIONS
{ "remove_link", hostapd_cli_cmd_remove_link, NULL,
"<count> = remove MLO link and send Reconfiguration MLE" },
+ { "link_enable", hostapd_cli_cmd_link_enable, NULL,
+ " bss_config=<phy>:<config file>\n"
+ " = Enable a link previously removed from the MLD AP" },
#endif /* CONFIG_TESTING_OPTIONS */
{ "disable_mld", hostapd_cli_cmd_disable_mld, NULL,
"= disable AP MLD to which the interface is affiliated" },
--
2.53.0
More information about the Hostap
mailing list