@@ -201,13 +201,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(
@@ -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 = -1;
+
+#ifdef CONFIG_IEEE80211BE
+ link = 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);
}
os_free(buf);
@@ -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 = -1;
+
+#ifdef CONFIG_IEEE80211BE
+ link = hapd->conf->mld_ap ? hapd->mld_link_id : -1;
+#endif
#ifdef CONFIG_TESTING_OPTIONS
if (hapd->ext_eapol_frame_io) {
@@ -539,11 +544,17 @@ 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 = -1;
+#endif
+ }
return hostapd_drv_hapd_send_eapol(hapd, addr, data, data_len,
- encrypt, flags);
+ encrypt, flags, link);
}
@@ -3528,6 +3528,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
*
@@ -3545,7 +3546,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)
@@ -3556,12 +3557,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)
@@ -6097,7 +6097,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;
@@ -6116,7 +6116,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;
}
@@ -6174,7 +6176,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;
@@ -6189,7 +6192,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);
@@ -372,23 +372,24 @@ static inline int wpa_drv_sta_remove(struct wpa_supplicant *wpa_s,
static inline int wpa_drv_tx_control_port(struct wpa_supplicant *wpa_s,
const u8 *dest, u16 proto,
const u8 *buf, size_t len,
- int no_encrypt)
+ int no_encrypt, int link_id)
{
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, link_id);
}
static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
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)
{
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, link_id);
return -1;
}
@@ -73,7 +73,7 @@ static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
- !encrypt);
+ !encrypt, -1);
if (wpa_s->l2)
return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
@@ -303,7 +303,7 @@ static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
return wpa_drv_tx_control_port(wpa_s, addr, ETH_P_EAPOL,
- data, data_len, !encrypt);
+ data, data_len, !encrypt, -1);
if (wpa_s->l2)
return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data,
@@ -118,7 +118,7 @@ int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
wpa_sm_has_ptk_installed(wpa_s->wpa);
return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
- !encrypt);
+ !encrypt, -1);
}
if (wpa_s->l2) {
EAPOL frames may need to be transmitted from the link address and not MLD address. For example, in case of authentication between MLD AP and legacy STA. Add link_id parameter to eapol send API's. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> --- src/ap/ap_drv_ops.h | 4 ++-- src/ap/ieee802_1x.c | 7 ++++++- src/ap/wpa_auth_glue.c | 15 +++++++++++++-- src/drivers/driver.h | 6 ++++-- src/drivers/driver_nl80211.c | 12 ++++++++---- wpa_supplicant/driver_i.h | 9 +++++---- wpa_supplicant/ibss_rsn.c | 4 ++-- wpa_supplicant/wpas_glue.c | 2 +- 8 files changed, 41 insertions(+), 18 deletions(-)