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