From 5a61644ffff0b49294f868861660ccfb885e0985 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 22 May 2023 22:33:50 +0300 Subject: [PATCH] driver: Specify link ID for 'send_mlme' and 'sta_deauth' callbacks This is needed for the driver to know on which link it should transmit the frames in MLO cases. Signed-off-by: Ilan Peer Signed-off-by: Andrei Otcheretianski --- src/ap/ap_drv_ops.c | 19 +++++++++++++++++-- src/drivers/driver.h | 8 +++++--- src/drivers/driver_atheros.c | 8 ++++---- src/drivers/driver_bsd.c | 8 +++++--- src/drivers/driver_hostap.c | 14 ++++++++------ src/drivers/driver_nl80211.c | 28 ++++++++++++++++------------ wpa_supplicant/driver_i.h | 4 ++-- 7 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 389b35bfe..6a5734852 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -760,20 +760,35 @@ int hostapd_drv_send_mlme(struct hostapd_data *hapd, const u16 *csa_offs, size_t csa_offs_len, int no_encrypt) { + int link_id = -1; + +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) + link_id = hapd->mld_link_id; +#endif /* CONFIG_IEEE80211BE */ + if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv) return 0; return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0, - csa_offs, csa_offs_len, no_encrypt, 0); + csa_offs, csa_offs_len, no_encrypt, 0, + link_id); } int hostapd_drv_sta_deauth(struct hostapd_data *hapd, const u8 *addr, int reason) { + int link_id = -1; + +#ifdef CONFIG_IEEE80211BE + if (hapd->conf->mld_ap) + link_id = hapd->mld_link_id; +#endif /* CONFIG_IEEE80211BE */ + if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv) return 0; return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr, - reason); + reason, link_id); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6ee1932c7..10bf2d4e8 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3273,12 +3273,13 @@ struct wpa_driver_ops { * @no_encrypt: Do not encrypt frame even if appropriate key exists * (used only for testing purposes) * @wait: Time to wait off-channel for a response (in ms), or zero + * @link_id: Link ID to use for TX, or -1 if not set * Returns: 0 on success, -1 on failure */ int (*send_mlme)(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, int no_encrypt, - unsigned int wait); + unsigned int wait, int link_id); /** * update_ft_ies - Update FT (IEEE 802.11r) IEs @@ -3580,14 +3581,15 @@ struct wpa_driver_ops { * @priv: Private driver interface data * @own_addr: Source address and BSSID for the Deauthentication frame * @addr: MAC address of the station to deauthenticate - * @reason: Reason code for the Deauthentiation frame + * @reason: Reason code for the Deauthentication frame + * @link_id: Link ID to use for Deauthentication frame, or -1 if not set * Returns: 0 on success, -1 on failure * * This function requests a specific station to be deauthenticated and * a Deauthentication frame to be sent to it. */ int (*sta_deauth)(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason); + u16 reason, int link_id); /** * sta_disassoc - Disassociate a station (AP only) diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index cb66dfa9b..d8def7936 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -81,7 +81,7 @@ struct atheros_driver_data { }; static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason_code); + u16 reason_code, int link_id); static int atheros_set_privacy(void *priv, int enabled); static const char * athr_get_ioctl_name(int op) @@ -637,7 +637,7 @@ atheros_flush(void *priv) u8 allsta[IEEE80211_ADDR_LEN]; os_memset(allsta, 0xff, IEEE80211_ADDR_LEN); return atheros_sta_deauth(priv, NULL, allsta, - IEEE80211_REASON_AUTH_LEAVE); + IEEE80211_REASON_AUTH_LEAVE, -1); } @@ -756,7 +756,7 @@ atheros_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason_code) + u16 reason_code, int link_id) { struct atheros_driver_data *drv = priv; struct ieee80211req_mlme mlme; @@ -1964,7 +1964,7 @@ static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params) static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len, int noack, unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, - int no_encrypt, unsigned int wait) + int no_encrypt, unsigned int wait, int link_id) { struct atheros_driver_data *drv = priv; u8 buf[1510]; diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 00d970a6d..b64cdc3f5 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -882,7 +882,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) #undef WPA_OUI_TYPE static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason_code); + u16 reason_code, int link_id); static const char * ether_sprintf(const u8 *addr) @@ -951,7 +951,8 @@ bsd_flush(void *priv) u8 allsta[IEEE80211_ADDR_LEN]; memset(allsta, 0xff, IEEE80211_ADDR_LEN); - return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE); + return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE, + -1); } @@ -974,7 +975,8 @@ bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, } static int -bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code) +bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code, + int link_id) { return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code, addr); diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index b9c42e4db..de97037df 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -264,7 +264,7 @@ static int hostap_init_sockets(struct hostap_driver_data *drv, u8 *own_addr) static int hostap_send_mlme(void *priv, const u8 *msg, size_t len, int noack, unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, - int no_encrypt, unsigned int wait) + int no_encrypt, unsigned int wait, int link_id) { struct hostap_driver_data *drv = priv; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg; @@ -313,7 +313,7 @@ static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data, pos += 2; memcpy(pos, data, data_len); - res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0, 0, 0); + res = hostap_send_mlme(drv, (u8 *) hdr, len, 0, 0, NULL, 0, 0, 0, -1); if (res < 0) { wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - " "failed: %d (%s)", @@ -1032,7 +1032,7 @@ static void hostap_driver_deinit(void *priv) static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason) + u16 reason, int link_id) { struct hostap_driver_data *drv = priv; struct ieee80211_mgmt mgmt; @@ -1055,7 +1055,7 @@ static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, memcpy(mgmt.bssid, own_addr, ETH_ALEN); mgmt.u.deauth.reason_code = host_to_le16(reason); return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.deauth), 0, 0, NULL, 0, 0, 0); + sizeof(mgmt.u.deauth), 0, 0, NULL, 0, 0, 0, -1); } @@ -1093,7 +1093,8 @@ static int hostap_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, memcpy(mgmt.bssid, own_addr, ETH_ALEN); mgmt.u.disassoc.reason_code = host_to_le16(reason); return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.disassoc), 0, 0, NULL, 0, 0, 0); + sizeof(mgmt.u.disassoc), 0, 0, NULL, 0, 0, 0, + -1); } @@ -1173,7 +1174,8 @@ static void wpa_driver_hostap_poll_client(void *priv, const u8 *own_addr, os_memcpy(hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN); os_memcpy(hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN); - hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0, 0, NULL, 0, 0, 0); + hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0, 0, NULL, 0, 0, 0, + -1); } diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index fda215cce..8c57f6276 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4170,7 +4170,8 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data, int offchanok, unsigned int wait_time, const u16 *csa_offs, - size_t csa_offs_len, int no_encrypt) + size_t csa_offs_len, int no_encrypt, + int link_id) { struct wpa_driver_nl80211_data *drv = bss->drv; struct ieee80211_mgmt *mgmt; @@ -4178,6 +4179,7 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data, u16 fc; int use_cookie = 1; int res; + struct i802_link *link = nl80211_get_link(bss, link_id); mgmt = (struct ieee80211_mgmt *) data; fc = le_to_host16(mgmt->frame_control); @@ -4277,14 +4279,14 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data, } if (freq == 0) { wpa_printf(MSG_DEBUG, "nl80211: send_mlme - Use bss->freq=%u", - bss->flink->freq); - freq = bss->flink->freq; + link->freq); + freq = link->freq; } if (drv->use_monitor && is_ap_interface(drv->nlmode)) { wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor", - freq, bss->flink->freq); + freq, link->freq); return nl80211_send_monitor(drv, data, data_len, encrypt, noack); } @@ -8075,14 +8077,15 @@ static int i802_sta_clear_stats(void *priv, const u8 *addr) static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - u16 reason) + u16 reason, int link_id) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct ieee80211_mgmt mgmt; u8 channel; + struct i802_link *link = nl80211_get_link(bss, link_id); - if (ieee80211_freq_to_chan(bss->flink->freq, &channel) == + if (ieee80211_freq_to_chan(link->freq, &channel) == HOSTAPD_MODE_IEEE80211AD) { /* Deauthentication is not used in DMG/IEEE 802.11ad; * disassociate the STA instead. */ @@ -8105,7 +8108,7 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt, IEEE80211_HDRLEN + sizeof(mgmt.u.deauth), 0, 0, 0, 0, - 0, NULL, 0, 0); + 0, NULL, 0, 0, -1); } @@ -8132,7 +8135,7 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt, IEEE80211_HDRLEN + sizeof(mgmt.u.disassoc), 0, 0, 0, 0, - 0, NULL, 0, 0); + 0, NULL, 0, 0, -1); } @@ -9004,7 +9007,7 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, !drv->use_monitor)) ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len, 0, freq, no_cck, offchanok, - wait_time, NULL, 0, 0); + wait_time, NULL, 0, 0, -1); else ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf, 24 + data_len, @@ -10103,7 +10106,7 @@ static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr, os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN); if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0, - 0, 0, NULL, 0, 0) < 0) + 0, 0, NULL, 0, 0, -1) < 0) wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to " "send poll frame"); } @@ -10452,12 +10455,13 @@ static int driver_nl80211_send_mlme(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, - int no_encrypt, unsigned int wait) + int no_encrypt, unsigned int wait, + int link_id) { struct i802_bss *bss = priv; return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack, freq, 0, 0, wait, csa_offs, - csa_offs_len, no_encrypt); + csa_offs_len, no_encrypt, link_id); } diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index d5ec22cee..03f413c01 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -202,7 +202,7 @@ static inline int wpa_drv_sta_deauth(struct wpa_supplicant *wpa_s, if (wpa_s->driver->sta_deauth) { return wpa_s->driver->sta_deauth(wpa_s->drv_priv, wpa_s->own_addr, addr, - reason_code); + reason_code, -1); } return -1; } @@ -328,7 +328,7 @@ static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s, if (wpa_s->driver->send_mlme) return wpa_s->driver->send_mlme(wpa_s->drv_priv, data, data_len, noack, - freq, NULL, 0, 0, wait); + freq, NULL, 0, 0, wait, -1); return -1; }