nl80211: Replace hostapd WEXT events with nl80211 events
This shares the nl80211 event processing with wpa_supplicant and removes the old WEXT code from driver_nl80211.c.
This commit is contained in:
parent
35583f3fa6
commit
5b7b85f669
1 changed files with 46 additions and 266 deletions
|
@ -119,7 +119,6 @@ struct wpa_driver_nl80211_data {
|
||||||
#ifdef HOSTAPD
|
#ifdef HOSTAPD
|
||||||
struct hostapd_data *hapd;
|
struct hostapd_data *hapd;
|
||||||
|
|
||||||
int wext_sock; /* socket for wireless events */
|
|
||||||
int eapol_sock; /* socket for EAPOL frames */
|
int eapol_sock; /* socket for EAPOL frames */
|
||||||
int monitor_sock; /* socket for monitor */
|
int monitor_sock; /* socket for monitor */
|
||||||
int monitor_ifidx;
|
int monitor_ifidx;
|
||||||
|
@ -128,7 +127,6 @@ struct wpa_driver_nl80211_data {
|
||||||
int *if_indices;
|
int *if_indices;
|
||||||
int num_if_indices;
|
int num_if_indices;
|
||||||
|
|
||||||
int we_version;
|
|
||||||
int beacon_int;
|
int beacon_int;
|
||||||
struct i802_bss bss;
|
struct i802_bss bss;
|
||||||
unsigned int ht_40mhz_scan:1;
|
unsigned int ht_40mhz_scan:1;
|
||||||
|
@ -154,10 +152,6 @@ static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HOSTAPD
|
|
||||||
#define wpa_supplicant_event(c, e, d) do { } while (0)
|
|
||||||
#endif /* HOSTAPD */
|
|
||||||
|
|
||||||
/* nl80211 code */
|
/* nl80211 code */
|
||||||
static int ack_handler(struct nl_msg *msg, void *arg)
|
static int ack_handler(struct nl_msg *msg, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -181,6 +175,13 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int no_seq_check(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
|
static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
|
||||||
struct nl_msg *msg,
|
struct nl_msg *msg,
|
||||||
int (*valid_handler)(struct nl_msg *, void *),
|
int (*valid_handler)(struct nl_msg *, void *),
|
||||||
|
@ -382,6 +383,7 @@ static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HOSTAPD
|
||||||
static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
|
static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
|
||||||
void *ctx, char *buf, size_t len,
|
void *ctx, char *buf, size_t len,
|
||||||
int del)
|
int del)
|
||||||
|
@ -621,12 +623,6 @@ try_again:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int no_seq_check(struct nl_msg *msg, void *arg)
|
|
||||||
{
|
|
||||||
return NL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
|
static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
|
||||||
const u8 *frame, size_t len)
|
const u8 *frame, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -729,10 +725,17 @@ static void mlme_event(struct wpa_driver_nl80211_data *drv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* HOSTAPD */
|
||||||
|
|
||||||
|
|
||||||
static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
|
static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
|
||||||
struct nlattr *tb[])
|
struct nlattr *tb[])
|
||||||
{
|
{
|
||||||
|
#ifdef HOSTAPD
|
||||||
|
if (tb[NL80211_ATTR_MAC])
|
||||||
|
hostapd_michael_mic_failure(drv->hapd,
|
||||||
|
nla_data(tb[NL80211_ATTR_MAC]));
|
||||||
|
#else /* HOSTAPD */
|
||||||
union wpa_event_data data;
|
union wpa_event_data data;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
|
wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
|
||||||
|
@ -762,6 +765,7 @@ static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
|
wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
|
||||||
|
#endif /* HOSTAPD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -785,6 +789,7 @@ static int process_event(struct nl_msg *msg, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (gnlh->cmd) {
|
switch (gnlh->cmd) {
|
||||||
|
#ifndef HOSTAPD
|
||||||
case NL80211_CMD_NEW_SCAN_RESULTS:
|
case NL80211_CMD_NEW_SCAN_RESULTS:
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
|
wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
|
||||||
drv->scan_complete_events = 1;
|
drv->scan_complete_events = 1;
|
||||||
|
@ -808,6 +813,7 @@ static int process_event(struct nl_msg *msg, void *arg)
|
||||||
case NL80211_CMD_DISASSOCIATE:
|
case NL80211_CMD_DISASSOCIATE:
|
||||||
mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
|
mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
|
||||||
break;
|
break;
|
||||||
|
#endif /* HOSTAPD */
|
||||||
case NL80211_CMD_MICHAEL_MIC_FAILURE:
|
case NL80211_CMD_MICHAEL_MIC_FAILURE:
|
||||||
mlme_event_michael_mic_failure(drv, tb);
|
mlme_event_michael_mic_failure(drv, tb);
|
||||||
break;
|
break;
|
||||||
|
@ -1116,8 +1122,10 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
|
||||||
goto err6;
|
goto err6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HOSTAPD
|
||||||
eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv,
|
eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv,
|
||||||
ctx);
|
ctx);
|
||||||
|
#endif /* HOSTAPD */
|
||||||
drv->link_event_sock = s;
|
drv->link_event_sock = s;
|
||||||
|
|
||||||
if (wpa_driver_nl80211_finish_drv_init(drv))
|
if (wpa_driver_nl80211_finish_drv_init(drv))
|
||||||
|
@ -1234,7 +1242,9 @@ static void wpa_driver_nl80211_deinit(void *priv)
|
||||||
static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
|
static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
|
wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
|
||||||
|
#ifndef HOSTAPD
|
||||||
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
|
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
|
||||||
|
#endif /* HOSTAPD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4757,6 +4767,7 @@ static int i802_ht_scan(struct wpa_driver_nl80211_data *drv)
|
||||||
static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssid)
|
static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssid)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (drv->ioctl_sock < 0) {
|
if (drv->ioctl_sock < 0) {
|
||||||
|
@ -4820,6 +4831,28 @@ static int i802_init_sockets(struct wpa_driver_nl80211_data *drv, const u8 *bssi
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = nl_get_multicast_id(drv, "nl80211", "scan");
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = nl_socket_add_membership(drv->nl_handle, ret);
|
||||||
|
if (ret < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
|
||||||
|
"membership for scan events: %d (%s)",
|
||||||
|
ret, strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nl_get_multicast_id(drv, "nl80211", "mlme");
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = nl_socket_add_membership(drv->nl_handle, ret);
|
||||||
|
if (ret < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
|
||||||
|
"membership for mlme events: %d (%s)",
|
||||||
|
ret, strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle),
|
||||||
|
wpa_driver_nl80211_event_receive, drv,
|
||||||
|
drv->hapd);
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211N
|
#ifdef CONFIG_IEEE80211N
|
||||||
if (drv->ht_40mhz_scan) {
|
if (drv->ht_40mhz_scan) {
|
||||||
if (nl80211_set_mode(drv, drv->ifname, NL80211_IFTYPE_STATION)
|
if (nl80211_set_mode(drv, drv->ifname, NL80211_IFTYPE_STATION)
|
||||||
|
@ -4899,255 +4932,6 @@ static int i802_sta_clear_stats(void *priv, const u8 *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
hostapd_wireless_event_wireless_custom(struct wpa_driver_nl80211_data *drv,
|
|
||||||
char *custom)
|
|
||||||
{
|
|
||||||
wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
|
|
||||||
|
|
||||||
if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
|
|
||||||
char *pos;
|
|
||||||
u8 addr[ETH_ALEN];
|
|
||||||
pos = strstr(custom, "addr=");
|
|
||||||
if (pos == NULL) {
|
|
||||||
wpa_printf(MSG_DEBUG,
|
|
||||||
"MLME-MICHAELMICFAILURE.indication "
|
|
||||||
"without sender address ignored");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pos += 5;
|
|
||||||
if (hwaddr_aton(pos, addr) == 0) {
|
|
||||||
hostapd_michael_mic_failure(drv->hapd, addr);
|
|
||||||
} else {
|
|
||||||
wpa_printf(MSG_DEBUG,
|
|
||||||
"MLME-MICHAELMICFAILURE.indication "
|
|
||||||
"with invalid MAC address");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_wireless_event_wireless(struct wpa_driver_nl80211_data *drv,
|
|
||||||
char *data, int len)
|
|
||||||
{
|
|
||||||
struct iw_event iwe_buf, *iwe = &iwe_buf;
|
|
||||||
char *pos, *end, *custom, *buf;
|
|
||||||
|
|
||||||
pos = data;
|
|
||||||
end = data + len;
|
|
||||||
|
|
||||||
while (pos + IW_EV_LCP_LEN <= end) {
|
|
||||||
/* Event data may be unaligned, so make a local, aligned copy
|
|
||||||
* before processing. */
|
|
||||||
memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
|
|
||||||
wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
|
|
||||||
iwe->cmd, iwe->len);
|
|
||||||
if (iwe->len <= IW_EV_LCP_LEN)
|
|
||||||
return;
|
|
||||||
|
|
||||||
custom = pos + IW_EV_POINT_LEN;
|
|
||||||
if (drv->we_version > 18 &&
|
|
||||||
(iwe->cmd == IWEVMICHAELMICFAILURE ||
|
|
||||||
iwe->cmd == IWEVCUSTOM)) {
|
|
||||||
/* WE-19 removed the pointer from struct iw_point */
|
|
||||||
char *dpos = (char *) &iwe_buf.u.data.length;
|
|
||||||
int dlen = dpos - (char *) &iwe_buf;
|
|
||||||
memcpy(dpos, pos + IW_EV_LCP_LEN,
|
|
||||||
sizeof(struct iw_event) - dlen);
|
|
||||||
} else {
|
|
||||||
memcpy(&iwe_buf, pos, sizeof(struct iw_event));
|
|
||||||
custom += IW_EV_POINT_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (iwe->cmd) {
|
|
||||||
case IWEVCUSTOM:
|
|
||||||
if (custom + iwe->u.data.length > end)
|
|
||||||
return;
|
|
||||||
buf = malloc(iwe->u.data.length + 1);
|
|
||||||
if (buf == NULL)
|
|
||||||
return;
|
|
||||||
memcpy(buf, custom, iwe->u.data.length);
|
|
||||||
buf[iwe->u.data.length] = '\0';
|
|
||||||
hostapd_wireless_event_wireless_custom(drv, buf);
|
|
||||||
free(buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += iwe->len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_wireless_event_rtm_newlink(struct wpa_driver_nl80211_data *drv,
|
|
||||||
struct nlmsghdr *h, int len)
|
|
||||||
{
|
|
||||||
struct ifinfomsg *ifi;
|
|
||||||
int attrlen, _nlmsg_len, rta_len;
|
|
||||||
struct rtattr *attr;
|
|
||||||
|
|
||||||
if (len < (int) sizeof(*ifi))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ifi = NLMSG_DATA(h);
|
|
||||||
|
|
||||||
/* TODO: use ifi->ifi_index to filter out wireless events from other
|
|
||||||
* interfaces */
|
|
||||||
|
|
||||||
_nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
|
|
||||||
|
|
||||||
attrlen = h->nlmsg_len - _nlmsg_len;
|
|
||||||
if (attrlen < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
|
|
||||||
|
|
||||||
rta_len = RTA_ALIGN(sizeof(struct rtattr));
|
|
||||||
while (RTA_OK(attr, attrlen)) {
|
|
||||||
if (attr->rta_type == IFLA_WIRELESS) {
|
|
||||||
hostapd_wireless_event_wireless(
|
|
||||||
drv, ((char *) attr) + rta_len,
|
|
||||||
attr->rta_len - rta_len);
|
|
||||||
}
|
|
||||||
attr = RTA_NEXT(attr, attrlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_wireless_event_receive(int sock, void *eloop_ctx,
|
|
||||||
void *sock_ctx)
|
|
||||||
{
|
|
||||||
char buf[256];
|
|
||||||
int left;
|
|
||||||
struct sockaddr_nl from;
|
|
||||||
socklen_t fromlen;
|
|
||||||
struct nlmsghdr *h;
|
|
||||||
struct wpa_driver_nl80211_data *drv = eloop_ctx;
|
|
||||||
|
|
||||||
fromlen = sizeof(from);
|
|
||||||
left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
|
|
||||||
(struct sockaddr *) &from, &fromlen);
|
|
||||||
if (left < 0) {
|
|
||||||
if (errno != EINTR && errno != EAGAIN)
|
|
||||||
perror("recvfrom(netlink)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
h = (struct nlmsghdr *) buf;
|
|
||||||
while (left >= (int) sizeof(*h)) {
|
|
||||||
int len, plen;
|
|
||||||
|
|
||||||
len = h->nlmsg_len;
|
|
||||||
plen = len - sizeof(*h);
|
|
||||||
if (len > left || plen < 0) {
|
|
||||||
printf("Malformed netlink message: "
|
|
||||||
"len=%d left=%d plen=%d\n",
|
|
||||||
len, left, plen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (h->nlmsg_type) {
|
|
||||||
case RTM_NEWLINK:
|
|
||||||
hostapd_wireless_event_rtm_newlink(drv, h, plen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = NLMSG_ALIGN(len);
|
|
||||||
left -= len;
|
|
||||||
h = (struct nlmsghdr *) ((char *) h + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left > 0) {
|
|
||||||
printf("%d extra bytes in the end of netlink message\n", left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int hostap_get_we_version(struct wpa_driver_nl80211_data *drv)
|
|
||||||
{
|
|
||||||
struct iw_range *range;
|
|
||||||
struct iwreq iwr;
|
|
||||||
int minlen;
|
|
||||||
size_t buflen;
|
|
||||||
|
|
||||||
drv->we_version = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use larger buffer than struct iw_range in order to allow the
|
|
||||||
* structure to grow in the future.
|
|
||||||
*/
|
|
||||||
buflen = sizeof(struct iw_range) + 500;
|
|
||||||
range = os_zalloc(buflen);
|
|
||||||
if (range == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(&iwr, 0, sizeof(iwr));
|
|
||||||
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
|
|
||||||
iwr.u.data.pointer = (caddr_t) range;
|
|
||||||
iwr.u.data.length = buflen;
|
|
||||||
|
|
||||||
minlen = ((char *) &range->enc_capa) - (char *) range +
|
|
||||||
sizeof(range->enc_capa);
|
|
||||||
|
|
||||||
if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
|
|
||||||
perror("ioctl[SIOCGIWRANGE]");
|
|
||||||
free(range);
|
|
||||||
return -1;
|
|
||||||
} else if (iwr.u.data.length >= minlen &&
|
|
||||||
range->we_version_compiled >= 18) {
|
|
||||||
wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
|
|
||||||
"WE(source)=%d enc_capa=0x%x",
|
|
||||||
range->we_version_compiled,
|
|
||||||
range->we_version_source,
|
|
||||||
range->enc_capa);
|
|
||||||
drv->we_version = range->we_version_compiled;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(range);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int i802_wireless_event_init(struct wpa_driver_nl80211_data *drv)
|
|
||||||
{
|
|
||||||
int s;
|
|
||||||
struct sockaddr_nl local;
|
|
||||||
|
|
||||||
hostap_get_we_version(drv);
|
|
||||||
|
|
||||||
drv->wext_sock = -1;
|
|
||||||
|
|
||||||
s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
||||||
if (s < 0) {
|
|
||||||
perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&local, 0, sizeof(local));
|
|
||||||
local.nl_family = AF_NETLINK;
|
|
||||||
local.nl_groups = RTMGRP_LINK;
|
|
||||||
if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
|
|
||||||
perror("bind(netlink)");
|
|
||||||
close(s);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
eloop_register_read_sock(s, hostapd_wireless_event_receive, drv,
|
|
||||||
NULL);
|
|
||||||
drv->wext_sock = s;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void i802_wireless_event_deinit(struct wpa_driver_nl80211_data *drv)
|
|
||||||
{
|
|
||||||
if (drv->wext_sock < 0)
|
|
||||||
return;
|
|
||||||
eloop_unregister_read_sock(drv->wext_sock);
|
|
||||||
close(drv->wext_sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int i802_sta_deauth(void *priv, const u8 *addr, int reason)
|
static int i802_sta_deauth(void *priv, const u8 *addr, int reason)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = priv;
|
struct wpa_driver_nl80211_data *drv = priv;
|
||||||
|
@ -5219,9 +5003,6 @@ static void *i802_init_bssid(struct hostapd_data *hapd, const u8 *bssid)
|
||||||
if (i802_init_sockets(drv, bssid))
|
if (i802_init_sockets(drv, bssid))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (i802_wireless_event_init(drv))
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
return drv;
|
return drv;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
@ -5241,8 +5022,6 @@ static void i802_deinit(void *priv)
|
||||||
struct wpa_driver_nl80211_data *drv = priv;
|
struct wpa_driver_nl80211_data *drv = priv;
|
||||||
struct i802_bss *bss, *prev;
|
struct i802_bss *bss, *prev;
|
||||||
|
|
||||||
i802_wireless_event_deinit(drv);
|
|
||||||
|
|
||||||
if (drv->last_freq_ht) {
|
if (drv->last_freq_ht) {
|
||||||
/* Clear HT flags from the driver */
|
/* Clear HT flags from the driver */
|
||||||
struct hostapd_freq_params freq;
|
struct hostapd_freq_params freq;
|
||||||
|
@ -5269,6 +5048,7 @@ static void i802_deinit(void *priv)
|
||||||
close(drv->eapol_sock);
|
close(drv->eapol_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle));
|
||||||
genl_family_put(drv->nl80211);
|
genl_family_put(drv->nl80211);
|
||||||
nl_cache_free(drv->nl_cache);
|
nl_cache_free(drv->nl_cache);
|
||||||
nl_handle_destroy(drv->nl_handle);
|
nl_handle_destroy(drv->nl_handle);
|
||||||
|
|
Loading…
Reference in a new issue