}
+#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,
const char *ifname)
{
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
hapd->driver->if_remove == NULL)
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);
}
const char *bridge, int use_existing);
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
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,
struct wpa_bss_params *params);
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
*/
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
int (*register_frame)(void *priv, u16 type,
const u8 *match, size_t match_len,
}
+#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,
size_t data_len, int noack,
unsigned int freq,
#endif /* CONFIG_DPP */
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
.link_add = nl80211_link_add,
+#ifdef CONFIG_IEEE80211BE
+ .link_remove = driver_nl80211_link_remove,
+#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_TESTING_OPTIONS
.register_frame = testing_nl80211_register_frame,
.radio_disable = testing_nl80211_radio_disable,