[PATCH 7/7] Hostapd: Add support for eapol tx/rx handling with vendor cmd

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

 



Implement sending and receiving eapol frames via nl80211 vendor
command.

Signed-off-by: Sarada Prasanna Garnayak <sarada.prasanna.garnayak@xxxxxxxxx>
---
 src/drivers/driver.h               | 13 +++++++++++++
 src/drivers/driver_nl80211.c       | 31 ++++++++++++++++++++++++++-----
 src/drivers/driver_nl80211.h       |  1 +
 src/drivers/driver_nl80211_capa.c  |  3 +++
 src/drivers/driver_nl80211_event.c | 19 +++++++++++++++++++
 wpa_supplicant/wpas_glue.c         |  5 +++++
 6 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 671585e47..7f20d616c 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2730,6 +2730,19 @@ struct wpa_driver_ops {
 	int (*hapd_send_eapol)(void *priv, const u8 *addr, const u8 *data,
 			       size_t data_len, int encrypt,
 			       const u8 *own_addr, u32 flags);
+	/**
+	 * vendor_send_eapol_data - Vendor send an EAPOL packet (AP only)
+	 * @priv: private driver interface data
+	 * @addr: Destination MAC address
+	 * @data: EAPOL packet starting with IEEE 802.1X header
+	 * @data_len: Length of the EAPOL packet in octets
+	 * @own_addr: Source MAC address
+	 *
+	 * Returns: 0 on success, -1 on failure
+	 */
+	int (*vendor_send_eapol_data)(void *priv, const u8 *addr,
+				      const u8 *own_addr, const u8 *data,
+				      size_t data_len);
 
 	/**
 	 * sta_deauth - Deauthenticate a station (AP only)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 403c38f6c..02b8543c9 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1962,12 +1962,19 @@ static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
 	if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params))
 		goto failed;
 
-	drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
-	if (drv->eapol_tx_sock < 0)
-		goto failed;
+	if (drv->data_tx_status && drv->eapol_tx_vendor_cmd_avail) {
+		drv->data_tx_status = 0;
+		if (!drv->use_monitor)
+			drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
+	}
 
 	if (drv->data_tx_status) {
 		int enabled = 1;
+		drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
+		if (drv->eapol_tx_sock < 0) {
+			drv->data_tx_status = 0;
+			goto failed;
+		}
 
 		if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
 			       &enabled, sizeof(enabled)) < 0) {
@@ -4948,14 +4955,23 @@ static int wpa_driver_nl80211_hapd_send_eapol(
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct hostapd_data *hapd = drv->ctx;
 	struct ieee80211_hdr *hdr;
 	size_t len;
 	u8 *pos;
 	int res;
 	int qos = flags & WPA_STA_WMM;
 
-	if (drv->device_ap_sme || !drv->use_monitor)
-		return nl80211_send_eapol_data(bss, addr, data, data_len);
+	if (drv->device_ap_sme || !drv->use_monitor) {
+		if (drv->eapol_tx_vendor_cmd_avail &&
+			hapd->driver->vendor_send_eapol_data) {
+			return hapd->driver->vendor_send_eapol_data(priv, addr,
+								    own_addr, data,
+								    data_len);
+		} else {
+			return nl80211_send_eapol_data(bss, addr, data, data_len);
+		}
+	}
 
 	len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
 		data_len;
@@ -6804,6 +6820,9 @@ static void *i802_init(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_LIBNL3_ROUTE */
 
+	if (drv->eapol_tx_vendor_cmd_avail)
+		goto skip_handle_eapol;
+
 	drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
 	if (drv->eapol_sock < 0) {
 		wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
@@ -6817,6 +6836,7 @@ static void *i802_init(struct hostapd_data *hapd,
 		goto failed;
 	}
 
+skip_handle_eapol:
 	if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
 			       params->own_addr))
 		goto failed;
@@ -10684,6 +10704,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 #ifdef CONFIG_DRIVER_NL80211_INTEL_LTQ
 	.get_aid = nl80211_get_aid,
 	.free_aid = nl80211_free_aid,
+	.vendor_send_eapol_data = nl80211_vendor_send_eapol_data,
 #endif /* CONFIG_DRIVER_NL80211_INTEL_LTQ */
 	.get_seqnum = i802_get_seqnum,
 	.flush = i802_flush,
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index f4cefc54f..040c66f33 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -167,6 +167,7 @@ struct wpa_driver_nl80211_data {
 	unsigned int roam_vendor_cmd_avail:1;
 	unsigned int get_aid_vendor_cmd_avail:1;
 	unsigned int free_aid_vendor_cmd_avail:1;
+	unsigned int eapol_tx_vendor_cmd_avail:1;
 
 	u64 vendor_scan_cookie;
 	u64 remain_on_chan_cookie;
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 59c992368..302c933c3 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -796,6 +796,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
 				case INTEL_LTQ_NL80211_VENDOR_SUBCMD_FREE_AID:
 					drv->free_aid_vendor_cmd_avail = 1;
 					break;
+				case INTEL_LTQ_NL80211_VENDOR_SUBCMD_TX_EAPOL:
+					drv->eapol_tx_vendor_cmd_avail = 1;
+					break;
 #endif /* CONFIG_DRIVER_NL80211_INTEL_LTQ */
 				}
 			}
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index bac83898d..04292766f 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -14,6 +14,7 @@
 #include "utils/common.h"
 #include "utils/eloop.h"
 #include "common/qca-vendor.h"
+#include "common/intel-ltq-vendor.h"
 #include "common/qca-vendor-attr.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
@@ -2074,6 +2075,21 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
 	}
 }
 
+static void nl80211_vendor_event_intel_ltq(struct wpa_driver_nl80211_data *drv,
+					   u32 subcmd, u8 *data, size_t len)
+{
+	switch (subcmd) {
+#ifdef CONFIG_DRIVER_NL80211_INTEL_LTQ
+	case INTEL_LTQ_NL80211_VENDOR_EVENT_RX_EAPOL:
+		intel_ltq_nl80211_handle_eapol(drv, data, len);
+		break;
+#endif /* CONFIG_DRIVER_NL80211_INTEL_LTQ */
+	default:
+		wpa_printf(MSG_DEBUG, "nl80211:Ignore unsupported Intel LTQ"
+			   " vendor event %u", subcmd);
+		break;
+	}
+}
 
 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
 				 struct nlattr **tb)
@@ -2113,6 +2129,9 @@ static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
 	case OUI_QCA:
 		nl80211_vendor_event_qca(drv, subcmd, data, len);
 		break;
+	case OUI_INTEL_LTQ:
+		nl80211_vendor_event_intel_ltq(drv, subcmd, data, len);
+		break;
 	default:
 		wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
 		break;
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 4634ed7fc..f22ee83b4 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -112,6 +112,11 @@ static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
+#ifdef CONFIG_DRIVER_NL80211_INTEL_LTQ
+	return wpa_drv_hapd_send_eapol(wpa_s, dest, buf, len,
+				       0, wpa_s->own_addr, 0);
+#endif /* CONFIG_DRIVER_NL80211_INTEL_LTQ */
+
 	if (wpa_s->l2) {
 		return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
 	}
-- 
2.11.0


_______________________________________________
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