]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
driver: Specify link ID for 'send_mlme' and 'sta_deauth' callbacks
authorIlan Peer <ilan.peer@intel.com>
Mon, 22 May 2023 19:33:50 +0000 (22:33 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 12 Jun 2023 13:26:49 +0000 (16:26 +0300)
This is needed for the driver to know on which link it should transmit
the frames in MLO cases.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/ap/ap_drv_ops.c
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_bsd.c
src/drivers/driver_hostap.c
src/drivers/driver_nl80211.c
wpa_supplicant/driver_i.h

index 389b35bfe2c77cc4d9630204b8d56a6ef5fa2b71..6a5734852d93d5f851e2726b21300e497f02ee58 100644 (file)
@@ -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);
 }
 
 
index 6ee1932c7cabe857555e8a4f3f53372048d46899..10bf2d4e85ab06c3e9d9ae2ea964f317c7e60ec2 100644 (file)
@@ -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)
index cb66dfa9bd5fb89775601317870432463323cc33..d8def79369b688b21e09910b1d5aa66b06efc79e 100644 (file)
@@ -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];
index 00d970a6dc3ba0593e164a62357cb247684ff5f2..b64cdc3f517779aa10ce5b8e31f3af5ea3e3e58d 100644 (file)
@@ -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);
index b9c42e4db48da734333d0e0b9943ffd87edc5f4f..de97037df07ab27f3d28438021c8d5c6321e242b 100644 (file)
@@ -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);
 }
 
 
index fda215cce08ec66d1c51eff3b4fde00df3a67e1b..8c57f6276c26ac0925db2fe7fc5fab334002acf8 100644 (file)
@@ -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);
 }
 
 
index d5ec22cee10a6a90b2e8c8e56167795c205387f9..03f413c014fcd8c3f5d97f3469fe83fd780d7f02 100644 (file)
@@ -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;
 }