]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Add support for hostapd_cli to disable/enable AP MLD
authorChenming Huang <quic_chenhuan@quicinc.com>
Thu, 7 Sep 2023 04:08:00 +0000 (09:38 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 2 Feb 2024 20:47:03 +0000 (22:47 +0200)
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>
hostapd/ctrl_iface.c
hostapd/hostapd_cli.c

index 36e175bc1edbb52b0d67e5b02a874ec7a0e00c8d..015a67aea22195d142fa4e7471906b74945e8339 100644 (file)
@@ -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,
index 34aad4ef51cae6917c36b8851e166815e94b81b6..8fb6119c8382041bc81e1d72753773f7aade5a00 100644 (file)
@@ -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,