diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 48cf5a093..be1577921 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -257,8 +257,7 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) authsrv_deinit(hapd); - if (hapd->interface_added && - hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { + if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s", hapd->conf->iface); } @@ -644,7 +643,6 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) } } - hapd->interface_added = 1; if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, hapd->conf->iface, hapd->own_addr, hapd, &hapd->drv_priv, force_ifname, if_addr, @@ -1128,13 +1126,13 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, void hostapd_interface_deinit(struct hostapd_iface *iface) { - size_t j; + int j; if (iface == NULL) return; hostapd_cleanup_iface_pre(iface); - for (j = 0; j < iface->num_bss; j++) { + for (j = iface->num_bss - 1; j >= 0; j--) { struct hostapd_data *hapd = iface->bss[j]; hostapd_free_stas(hapd); hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 1afe327f2..f167a02dc 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -99,7 +99,6 @@ struct hostapd_data { struct hostapd_iface *iface; struct hostapd_config *iconf; struct hostapd_bss_config *conf; - int interface_added; /* virtual interface added for this BSS */ u8 own_addr[ETH_ALEN]; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 99351d95c..e8c140e48 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -218,6 +218,7 @@ struct i802_bss { unsigned int added_bridge:1; unsigned int in_deinit:1; unsigned int wdev_id_set:1; + unsigned int added_if:1; u8 addr[ETH_ALEN]; @@ -9383,6 +9384,7 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type, new_bss->next = drv->first_bss->next; new_bss->freq = drv->first_bss->freq; new_bss->ctx = bss_ctx; + new_bss->added_if = 1; drv->first_bss->next = new_bss; if (drv_priv) *drv_priv = new_bss; @@ -9410,7 +9412,7 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d", __func__, type, ifname, ifindex); - if (ifindex > 0) + if (ifindex > 0 && bss->added_if) nl80211_remove_iface(drv, ifindex); #ifdef HOSTAPD @@ -9448,6 +9450,18 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, if (bss) wpa_printf(MSG_INFO, "nl80211: %s - could not find " "BSS %p in the list", __func__, bss); + } else { + nl80211_teardown_ap(bss); + wpa_driver_nl80211_del_beacon(drv); + nl80211_destroy_bss(bss); + i802_set_iface_flags(bss, 0); + if (drv->first_bss->next) { + drv->first_bss = drv->first_bss->next; + drv->ctx = drv->first_bss->ctx; + os_free(bss); + } else { + wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to"); + } } #endif /* HOSTAPD */