[PATCH 31/50] AP/wpa_supplicant/driver: Add link id to send eapol callbacks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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(-)

diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 5b4b931736..29a6bdd770 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -195,13 +195,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 0e3d1772a2..c6cbf76a25 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 = -1;
+
+#ifdef CONFIG_IEEE80211BE
+		link = hapd->conf->mld_ap ? hapd->conf->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);
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index a87d2f3899..9090ba7840 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 = -1;
+
+#ifdef CONFIG_IEEE80211BE
+	link = hapd->conf->mld_ap ? hapd->conf->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);
 }
 
 
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index e838b54ae0..af59510c7b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3475,6 +3475,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
 	 *
@@ -3492,7 +3493,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)
@@ -3503,12 +3504,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_nl80211.c b/src/drivers/driver_nl80211.c
index a728799f64..112e59530e 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5999,7 +5999,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;
@@ -6018,7 +6018,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;
 	}
@@ -6076,7 +6078,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;
@@ -6091,7 +6094,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/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index f23f78064e..d6d4d5429b 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -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;
 }
 
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 5b31f7bb0e..65284ab913 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -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,
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index e5a4053c83..262147ab18 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -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) {
-- 
2.38.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux