]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Allow a single BSS to be removed from an interface
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 17 Oct 2013 15:56:30 +0000 (18:56 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 31 Oct 2013 20:30:15 +0000 (22:30 +0200)
The global control interface command "REMOVE <ifname>" can now be used
to remove a single virtual interface (BSS) without affecting other
virtual interfaces on the same radio.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/ap/ap_config.c
src/ap/ap_config.h
src/ap/hostapd.c

index 29f3e7da976de94e1c2e8b669ab7f94c794c649a..65a6f12a3db1630c90bad427c36bb7de03332d8b 100644 (file)
@@ -403,7 +403,7 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
 }
 
 
-static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
+void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 {
        struct hostapd_wpa_psk *psk, *prev;
        struct hostapd_eap_user *user, *prev_user;
index c0538cfbdf06e42af8d7e3404cace91292830942..8b7372482340304ff6baae9d7f8e9d8d1f686566 100644 (file)
@@ -555,6 +555,7 @@ int hostapd_mac_comp(const void *a, const void *b);
 int hostapd_mac_comp_empty(const void *a);
 struct hostapd_config * hostapd_config_defaults(void);
 void hostapd_config_defaults_bss(struct hostapd_bss_config *bss);
+void hostapd_config_free_bss(struct hostapd_bss_config *conf);
 void hostapd_config_free(struct hostapd_config *conf);
 int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
                          const u8 *addr, int *vlan_id);
index 732d1094bd6c653d5a7536e2baac58c7818f0c0f..5d1e47f12e62a87d9ca31768ab78799244ccb88e 100644 (file)
@@ -1658,16 +1658,46 @@ fail:
 }
 
 
+static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
+{
+       struct hostapd_data *hapd;
+       size_t i;
+
+       if (idx > iface->num_bss || idx > iface->conf->num_bss)
+               return -1;
+       hapd = iface->bss[idx];
+       wpa_printf(MSG_INFO, "Remove BSS '%s'", hapd->conf->iface);
+
+       hostapd_free_stas(hapd);
+       hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
+       hostapd_clear_wep(hapd);
+       hostapd_cleanup(hapd);
+       hostapd_config_free_bss(hapd->conf);
+       os_free(hapd);
+
+       iface->num_bss--;
+       for (i = idx; i < iface->num_bss; i++)
+               iface->bss[i] = iface->bss[i + 1];
+
+       iface->conf->num_bss--;
+       for (i = idx; i < iface->num_bss; i++)
+               iface->conf->bss[i] = iface->conf->bss[i + 1];
+
+       return 0;
+}
+
+
 int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
 {
        struct hostapd_iface *hapd_iface;
-       size_t i, k = 0;
+       size_t i, j, k = 0;
 
        for (i = 0; i < interfaces->count; i++) {
                hapd_iface = interfaces->iface[i];
                if (hapd_iface == NULL)
                        return -1;
-               if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+               if (hapd_iface->conf->num_bss == 1 &&
+                   !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
                        wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
                        hostapd_interface_deinit_free(hapd_iface);
                        k = i;
@@ -1679,6 +1709,11 @@ int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
                        interfaces->count--;
                        return 0;
                }
+
+               for (j = 0; j < hapd_iface->conf->num_bss; j++) {
+                       if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf))
+                               return hostapd_remove_bss(hapd_iface, j);
+               }
        }
        return -1;
 }