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 <andrei.otcheretianski@intel.com>
This commit is contained in:
Andrei Otcheretianski 2023-05-22 22:33:54 +03:00 committed by Jouni Malinen
parent c5271faf55
commit 172b0a9a2b
12 changed files with 40 additions and 19 deletions

View 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(

View 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);

View 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);
}

View 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)

View 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];

View 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;

View 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;

View 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;

View 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;

View 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);

View 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;

View 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;
}