]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP/driver: Add link ID to send EAPOL callbacks
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Mon, 22 May 2023 19:33:54 +0000 (22:33 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 12 Jun 2023 13:26:56 +0000 (16:26 +0300)
EAPOL frames may need to be transmitted from the link address and not
MLD address. For example, in case of authentication between AP MLD and
legacy STA. Add link_id parameter to EAPOL send APIs.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
12 files changed:
src/ap/ap_drv_ops.h
src/ap/ieee802_1x.c
src/ap/wpa_auth_glue.c
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_bsd.c
src/drivers/driver_hostap.c
src/drivers/driver_macsec_linux.c
src/drivers/driver_macsec_qca.c
src/drivers/driver_nl80211.c
src/drivers/driver_wired.c
wpa_supplicant/driver_i.h

index 971e02866152e536fde88fff34b4a0b66cb44a0d..073715178328f07cadbe26fec38871c94646c758 100644 (file)
@@ -200,13 +200,13 @@ static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
 static inline int hostapd_drv_hapd_send_eapol(struct hostapd_data *hapd,
                                              const u8 *addr, const u8 *data,
                                              size_t data_len, int encrypt,
-                                             u32 flags)
+                                             u32 flags, int link_id)
 {
        if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
                return 0;
        return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
                                             data_len, encrypt,
-                                            hapd->own_addr, flags);
+                                            hapd->own_addr, flags, link_id);
 }
 
 static inline int hostapd_drv_read_sta_data(
index bc1f47d2b86d072d340d1d4ec570504a48320fb3..5688f1a9e0bb549b481d2b606ef1b50e002cf892 100644 (file)
@@ -95,9 +95,14 @@ static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
        if (sta->flags & WLAN_STA_PREAUTH) {
                rsn_preauth_send(hapd, sta, buf, len);
        } else {
+               int link_id = -1;
+
+#ifdef CONFIG_IEEE80211BE
+               link_id = hapd->conf->mld_ap ? hapd->mld_link_id : -1;
+#endif /* CONFIG_IEEE80211BE */
                hostapd_drv_hapd_send_eapol(
                        hapd, sta->addr, buf, len,
-                       encrypt, hostapd_sta_flags_to_drv(sta->flags));
+                       encrypt, hostapd_sta_flags_to_drv(sta->flags), link_id);
        }
 
        os_free(buf);
index a87d2f38999a0a189583879472b9bfd7784201ee..14ac4e785c2bf0a139965ed5a63c5224b2ae9308 100644 (file)
@@ -522,6 +522,11 @@ int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
        struct hostapd_data *hapd = ctx;
        struct sta_info *sta;
        u32 flags = 0;
+       int link_id = -1;
+
+#ifdef CONFIG_IEEE80211BE
+       link_id = hapd->conf->mld_ap ? hapd->mld_link_id : -1;
+#endif /* CONFIG_IEEE80211BE */
 
 #ifdef CONFIG_TESTING_OPTIONS
        if (hapd->ext_eapol_frame_io) {
@@ -539,11 +544,16 @@ int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
 #endif /* CONFIG_TESTING_OPTIONS */
 
        sta = ap_get_sta(hapd, addr);
-       if (sta)
+       if (sta) {
                flags = hostapd_sta_flags_to_drv(sta->flags);
+#ifdef CONFIG_IEEE80211BE
+               if (sta->mld_info.mld_sta && (sta->flags & WLAN_STA_AUTHORIZED))
+                       link_id = -1;
+#endif /* CONFIG_IEEE80211BE */
+       }
 
        return hostapd_drv_hapd_send_eapol(hapd, addr, data, data_len,
-                                          encrypt, flags);
+                                          encrypt, flags, link_id);
 }
 
 
index 10bf2d4e85ab06c3e9d9ae2ea964f317c7e60ec2..52b14fe80b76ebf51463730ec9788e62da1fb20f 100644 (file)
@@ -3541,6 +3541,7 @@ struct wpa_driver_ops {
         * @buf: Frame payload starting from IEEE 802.1X header
         * @len: Frame payload length
         * @no_encrypt: Do not encrypt frame
+        * @link_id: Link ID to use for TX, or -1 if not set
         *
         * Returns 0 on success, else an error
         *
@@ -3558,7 +3559,7 @@ struct wpa_driver_ops {
         */
        int (*tx_control_port)(void *priv, const u8 *dest,
                               u16 proto, const u8 *buf, size_t len,
-                              int no_encrypt);
+                              int no_encrypt, int link_id);
 
        /**
         * hapd_send_eapol - Send an EAPOL packet (AP only)
@@ -3569,12 +3570,13 @@ struct wpa_driver_ops {
         * @encrypt: Whether the frame should be encrypted
         * @own_addr: Source MAC address
         * @flags: WPA_STA_* flags for the destination station
+        * @link_id: Link ID to use for TX, or -1 if not set
         *
         * Returns: 0 on success, -1 on failure
         */
        int (*hapd_send_eapol)(void *priv, const u8 *addr, const u8 *data,
                               size_t data_len, int encrypt,
-                              const u8 *own_addr, u32 flags);
+                              const u8 *own_addr, u32 flags, int link_id);
 
        /**
         * sta_deauth - Deauthenticate a station (AP only)
index d8def79369b688b21e09910b1d5aa66b06efc79e..22c8ff30c8907e0fedbc0dd5307204a4883be83e 100644 (file)
@@ -1644,7 +1644,7 @@ atheros_wireless_event_init(struct atheros_driver_data *drv)
 
 static int
 atheros_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
-                  int encrypt, const u8 *own_addr, u32 flags)
+                  int encrypt, const u8 *own_addr, u32 flags, int link_id)
 {
        struct atheros_driver_data *drv = priv;
        unsigned char buf[3000];
index b64cdc3f517779aa10ce5b8e31f3af5ea3e3e58d..13fcab5a155c794bc10113ad7e67925730afb983 100644 (file)
@@ -558,7 +558,7 @@ no_ie:
 
 static int
 bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
-              int encrypt, const u8 *own_addr, u32 flags)
+              int encrypt, const u8 *own_addr, u32 flags, int link_id)
 {
        struct bsd_driver_data *drv = priv;
 
index de97037df07ab27f3d28438021c8d5c6321e242b..cf3b01e51b889c361fd7e7ca56deded48e71cae2 100644 (file)
@@ -281,7 +281,7 @@ static int hostap_send_mlme(void *priv, const u8 *msg, size_t len, int noack,
 
 static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data,
                             size_t data_len, int encrypt, const u8 *own_addr,
-                            u32 flags)
+                            u32 flags, int link_id)
 {
        struct hostap_driver_data *drv = priv;
        struct ieee80211_hdr *hdr;
index c79e8733a94e5c0bea81ed478733d7572a371254..c867154981e936f34996a4dc0b0376d45bafb824 100644 (file)
@@ -1640,7 +1640,7 @@ static void macsec_drv_hapd_deinit(void *priv)
 
 static int macsec_drv_send_eapol(void *priv, const u8 *addr,
                                 const u8 *data, size_t data_len, int encrypt,
-                                const u8 *own_addr, u32 flags)
+                                const u8 *own_addr, u32 flags, int link_id)
 {
        struct macsec_drv_data *drv = priv;
        struct ieee8023_hdr *hdr;
index eccaf6375e3e6f19128d2ef05f5173760ec30cf9..58c48c2f5e0d3bbf9cc6975ccc3aa6ffedf43976 100644 (file)
@@ -366,7 +366,7 @@ static void macsec_qca_hapd_deinit(void *priv)
 
 static int macsec_qca_send_eapol(void *priv, const u8 *addr,
                                 const u8 *data, size_t data_len, int encrypt,
-                                const u8 *own_addr, u32 flags)
+                                const u8 *own_addr, u32 flags, int link_id)
 {
        struct macsec_qca_data *drv = priv;
        struct ieee8023_hdr *hdr;
index 8c57f6276c26ac0925db2fe7fc5fab334002acf8..2222fb5ddd023987092658acc21cdac57d98753f 100644 (file)
@@ -6104,7 +6104,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
 
 static int nl80211_tx_control_port(void *priv, const u8 *dest,
                                   u16 proto, const u8 *buf, size_t len,
-                                  int no_encrypt)
+                                  int no_encrypt, int link_id)
 {
        struct nl80211_ack_ext_arg ext_arg;
        struct i802_bss *bss = priv;
@@ -6123,7 +6123,9 @@ static int nl80211_tx_control_port(void *priv, const u8 *dest,
            nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dest) ||
            nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
            (no_encrypt &&
-            nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) {
+            nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)) ||
+           (link_id != NL80211_DRV_LINK_ID_NA &&
+            nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
@@ -6181,7 +6183,8 @@ static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
 
 static int wpa_driver_nl80211_hapd_send_eapol(
        void *priv, const u8 *addr, const u8 *data,
-       size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
+       size_t data_len, int encrypt, const u8 *own_addr, u32 flags,
+       int link_id)
 {
        struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -6196,7 +6199,8 @@ static int wpa_driver_nl80211_hapd_send_eapol(
        if (drv->control_port_ap &&
            (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT))
                return nl80211_tx_control_port(bss, addr, ETH_P_EAPOL,
-                                              data, data_len, !encrypt);
+                                              data, data_len, !encrypt,
+                                              link_id);
 
        if (drv->device_ap_sme || !drv->use_monitor)
                return nl80211_send_eapol_data(bss, addr, data, data_len);
index c7537b7c35eb5b2f8f5db2de0d7ce2b89c42f751..03366b8e4b07700f092aab7bc0542c4945e5e4c8 100644 (file)
@@ -285,7 +285,7 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
 
 static int wired_send_eapol(void *priv, const u8 *addr,
                            const u8 *data, size_t data_len, int encrypt,
-                           const u8 *own_addr, u32 flags)
+                           const u8 *own_addr, u32 flags, int link_id)
 {
        struct wpa_driver_wired_data *drv = priv;
        struct ieee8023_hdr *hdr;
index 03f413c014fcd8c3f5d97f3469fe83fd780d7f02..459a8e4ffc95327f061a7dc639bc3eca584f1319 100644 (file)
@@ -377,7 +377,7 @@ static inline int wpa_drv_tx_control_port(struct wpa_supplicant *wpa_s,
        if (!wpa_s->driver->tx_control_port)
                return -1;
        return wpa_s->driver->tx_control_port(wpa_s->drv_priv, dest, proto,
-                                             buf, len, no_encrypt);
+                                             buf, len, no_encrypt, -1);
 }
 
 static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
@@ -388,7 +388,7 @@ static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
        if (wpa_s->driver->hapd_send_eapol)
                return wpa_s->driver->hapd_send_eapol(wpa_s->drv_priv, addr,
                                                      data, data_len, encrypt,
-                                                     own_addr, flags);
+                                                     own_addr, flags, -1);
        return -1;
 }