AP MLD: Support link removal before removing interface
Previously, whenever if_remove() was called, the whole interface was deleted. In an AP MLD, all partner BSS use the same driver private context and hence removing the interface when only one of the links goes down should be avoided. Add a helper function to remove a link first whenever if_remove() is called. Later while handling it, if the number of active links goes to 0, if_remove() would be called to clean up the interface. This helper function will be used later when co-hosted AP MLD support is added and as well later during ML reconfiguration support. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
parent
55c30e8aba
commit
d2b62b3fe5
4 changed files with 72 additions and 0 deletions
|
@ -572,12 +572,33 @@ int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
int hostapd_if_link_remove(struct hostapd_data *hapd,
|
||||||
|
enum wpa_driver_if_type type,
|
||||||
|
const char *ifname, u8 link_id)
|
||||||
|
{
|
||||||
|
if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_remove)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return hapd->driver->link_remove(hapd->drv_priv, type, ifname,
|
||||||
|
hapd->mld_link_id);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
|
||||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
{
|
{
|
||||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||||
hapd->driver->if_remove == NULL)
|
hapd->driver->if_remove == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (hapd->conf->mld_ap)
|
||||||
|
return hostapd_if_link_remove(hapd, type, ifname,
|
||||||
|
hapd->mld_link_id);
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
|
return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||||
const char *bridge, int use_existing);
|
const char *bridge, int use_existing);
|
||||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||||
const char *ifname);
|
const char *ifname);
|
||||||
|
int hostapd_if_link_remove(struct hostapd_data *hapd,
|
||||||
|
enum wpa_driver_if_type type,
|
||||||
|
const char *ifname, u8 link_id);
|
||||||
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
||||||
struct wpa_bss_params *params);
|
struct wpa_bss_params *params);
|
||||||
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
||||||
|
|
|
@ -5153,6 +5153,18 @@ struct wpa_driver_ops {
|
||||||
*/
|
*/
|
||||||
int (*link_add)(void *priv, u8 link_id, const u8 *addr, void *bss_ctx);
|
int (*link_add)(void *priv, u8 link_id, const u8 *addr, void *bss_ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* link_remove - Remove a link from the AP MLD interface
|
||||||
|
* @priv: Private driver interface data
|
||||||
|
* @type: Interface type
|
||||||
|
* @ifname: Interface name of the virtual interface from where the link
|
||||||
|
* is to be removed.
|
||||||
|
* @link_id: Valid link ID to remove
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int (*link_remove)(void *priv, enum wpa_driver_if_type type,
|
||||||
|
const char *ifname, u8 link_id);
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
int (*register_frame)(void *priv, u16 type,
|
int (*register_frame)(void *priv, u16 type,
|
||||||
const u8 *match, size_t match_len,
|
const u8 *match, size_t match_len,
|
||||||
|
|
|
@ -10714,6 +10714,39 @@ static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
static int driver_nl80211_link_remove(void *priv, enum wpa_driver_if_type type,
|
||||||
|
const char *ifname, u8 link_id)
|
||||||
|
{
|
||||||
|
struct i802_bss *bss = priv;
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
|
||||||
|
if (type != WPA_IF_AP_BSS ||
|
||||||
|
!nl80211_link_valid(bss->valid_links, link_id))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Teardown AP(%s) link %d (type=%d ifname=%s links=0x%x)",
|
||||||
|
bss->ifname, link_id, type, ifname, bss->valid_links);
|
||||||
|
|
||||||
|
nl80211_remove_link(bss, link_id);
|
||||||
|
|
||||||
|
bss->ctx = bss->flink->ctx;
|
||||||
|
|
||||||
|
if (drv->first_bss == bss && !bss->valid_links)
|
||||||
|
drv->ctx = bss->ctx;
|
||||||
|
|
||||||
|
if (!bss->valid_links) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: No more links remaining, so remove interface");
|
||||||
|
return wpa_driver_nl80211_if_remove(bss, type, ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
|
||||||
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
|
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
|
||||||
size_t data_len, int noack,
|
size_t data_len, int noack,
|
||||||
unsigned int freq,
|
unsigned int freq,
|
||||||
|
@ -14043,6 +14076,9 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
||||||
.link_add = nl80211_link_add,
|
.link_add = nl80211_link_add,
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
.link_remove = driver_nl80211_link_remove,
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
.register_frame = testing_nl80211_register_frame,
|
.register_frame = testing_nl80211_register_frame,
|
||||||
.radio_disable = testing_nl80211_radio_disable,
|
.radio_disable = testing_nl80211_radio_disable,
|
||||||
|
|
Loading…
Reference in a new issue