From: Andrei Otcheretianski Date: Mon, 22 May 2023 19:33:54 +0000 (+0300) Subject: AP/driver: Add link ID to send EAPOL callbacks X-Git-Tag: hostap_2_11~1128 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=172b0a9a2b51d54c4127ad4e99faf97d2aab729c;p=thirdparty%2Fhostap.git AP/driver: Add link ID to send EAPOL callbacks 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 --- diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 971e02866..073715178 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -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( diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index bc1f47d2b..5688f1a9e 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -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); diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index a87d2f389..14ac4e785 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -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); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 10bf2d4e8..52b14fe80 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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) diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index d8def7936..22c8ff30c 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -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]; diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index b64cdc3f5..13fcab5a1 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -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; diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index de97037df..cf3b01e51 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -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; diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c index c79e8733a..c86715498 100644 --- a/src/drivers/driver_macsec_linux.c +++ b/src/drivers/driver_macsec_linux.c @@ -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; diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c index eccaf6375..58c48c2f5 100644 --- a/src/drivers/driver_macsec_qca.c +++ b/src/drivers/driver_macsec_qca.c @@ -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; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 8c57f6276..2222fb5dd 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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); diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c index c7537b7c3..03366b8e4 100644 --- a/src/drivers/driver_wired.c +++ b/src/drivers/driver_wired.c @@ -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; diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 03f413c01..459a8e4ff 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -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; }