nl80211: Create a netlink socket handle for the Connect interface
This netlink socket handle owns the connect request and is further used by the host driver/kernel to request for the external authentication. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
ba71cb821a
commit
40a68f3384
3 changed files with 59 additions and 22 deletions
|
@ -130,7 +130,7 @@ static void nl_destroy_handles(struct nl_handle **handle)
|
||||||
|
|
||||||
static void nl80211_register_eloop_read(struct nl_handle **handle,
|
static void nl80211_register_eloop_read(struct nl_handle **handle,
|
||||||
eloop_sock_handler handler,
|
eloop_sock_handler handler,
|
||||||
void *eloop_data)
|
void *eloop_data, int persist)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LIBNL20
|
#ifdef CONFIG_LIBNL20
|
||||||
/*
|
/*
|
||||||
|
@ -151,13 +151,17 @@ static void nl80211_register_eloop_read(struct nl_handle **handle,
|
||||||
nl_socket_set_nonblocking(*handle);
|
nl_socket_set_nonblocking(*handle);
|
||||||
eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
|
eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
|
||||||
eloop_data, *handle);
|
eloop_data, *handle);
|
||||||
*handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
|
if (!persist)
|
||||||
|
*handle = (void *) (((intptr_t) *handle) ^
|
||||||
|
ELOOP_SOCKET_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
|
static void nl80211_destroy_eloop_handle(struct nl_handle **handle, int persist)
|
||||||
{
|
{
|
||||||
*handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
|
if (!persist)
|
||||||
|
*handle = (void *) (((intptr_t) *handle) ^
|
||||||
|
ELOOP_SOCKET_INVALID);
|
||||||
eloop_unregister_read_sock(nl_socket_get_fd(*handle));
|
eloop_unregister_read_sock(nl_socket_get_fd(*handle));
|
||||||
nl_destroy_handles(handle);
|
nl_destroy_handles(handle);
|
||||||
}
|
}
|
||||||
|
@ -723,7 +727,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
nl80211_register_eloop_read(&w->nl_beacons,
|
nl80211_register_eloop_read(&w->nl_beacons,
|
||||||
nl80211_recv_beacons, w);
|
nl80211_recv_beacons, w, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dl_list_add(&nl80211_wiphys, &w->list);
|
dl_list_add(&nl80211_wiphys, &w->list);
|
||||||
|
@ -772,7 +776,7 @@ static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (w->nl_beacons)
|
if (w->nl_beacons)
|
||||||
nl80211_destroy_eloop_handle(&w->nl_beacons);
|
nl80211_destroy_eloop_handle(&w->nl_beacons, 0);
|
||||||
|
|
||||||
nl_cb_put(w->nl_cb);
|
nl_cb_put(w->nl_cb);
|
||||||
dl_list_del(&w->list);
|
dl_list_del(&w->list);
|
||||||
|
@ -1631,7 +1635,7 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
|
||||||
|
|
||||||
nl80211_register_eloop_read(&global->nl_event,
|
nl80211_register_eloop_read(&global->nl_event,
|
||||||
wpa_driver_nl80211_event_receive,
|
wpa_driver_nl80211_event_receive,
|
||||||
global->nl_cb);
|
global->nl_cb, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1997,7 +2001,7 @@ static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
|
||||||
{
|
{
|
||||||
nl80211_register_eloop_read(&bss->nl_mgmt,
|
nl80211_register_eloop_read(&bss->nl_mgmt,
|
||||||
wpa_driver_nl80211_event_receive,
|
wpa_driver_nl80211_event_receive,
|
||||||
bss->nl_cb);
|
bss->nl_cb, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2010,6 +2014,25 @@ static int nl80211_register_action_frame(struct i802_bss *bss,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int nl80211_init_connect_handle(struct i802_bss *bss)
|
||||||
|
{
|
||||||
|
if (bss->nl_connect) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Connect handle already created (nl_connect=%p)",
|
||||||
|
bss->nl_connect);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bss->nl_connect = nl_create_handle(bss->nl_cb, "connect");
|
||||||
|
if (!bss->nl_connect)
|
||||||
|
return -1;
|
||||||
|
nl80211_register_eloop_read(&bss->nl_connect,
|
||||||
|
wpa_driver_nl80211_event_receive,
|
||||||
|
bss->nl_cb, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
@ -2313,7 +2336,7 @@ static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
|
||||||
return;
|
return;
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
|
wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
|
||||||
"(%s)", bss->nl_mgmt, reason);
|
"(%s)", bss->nl_mgmt, reason);
|
||||||
nl80211_destroy_eloop_handle(&bss->nl_mgmt);
|
nl80211_destroy_eloop_handle(&bss->nl_mgmt, 0);
|
||||||
|
|
||||||
nl80211_put_wiphy_data_ap(bss);
|
nl80211_put_wiphy_data_ap(bss);
|
||||||
}
|
}
|
||||||
|
@ -2529,6 +2552,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
|
||||||
if (drv->vendor_cmd_test_avail)
|
if (drv->vendor_cmd_test_avail)
|
||||||
qca_vendor_test(drv);
|
qca_vendor_test(drv);
|
||||||
|
|
||||||
|
nl80211_init_connect_handle(bss);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2642,6 +2667,9 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
|
||||||
nl80211_del_p2pdev(bss);
|
nl80211_del_p2pdev(bss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bss->nl_connect)
|
||||||
|
nl80211_destroy_eloop_handle(&bss->nl_connect, 1);
|
||||||
|
|
||||||
nl80211_destroy_bss(drv->first_bss);
|
nl80211_destroy_bss(drv->first_bss);
|
||||||
|
|
||||||
os_free(drv->filter_ssids);
|
os_free(drv->filter_ssids);
|
||||||
|
@ -5381,7 +5409,8 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
|
||||||
|
|
||||||
static int wpa_driver_nl80211_try_connect(
|
static int wpa_driver_nl80211_try_connect(
|
||||||
struct wpa_driver_nl80211_data *drv,
|
struct wpa_driver_nl80211_data *drv,
|
||||||
struct wpa_driver_associate_params *params)
|
struct wpa_driver_associate_params *params,
|
||||||
|
struct nl_handle *nl_connect)
|
||||||
{
|
{
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
enum nl80211_auth_type type;
|
enum nl80211_auth_type type;
|
||||||
|
@ -5435,7 +5464,11 @@ skip_auth_type:
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
if (nl_connect)
|
||||||
|
ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL);
|
||||||
|
else
|
||||||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
|
|
||||||
msg = NULL;
|
msg = NULL;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
|
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
|
||||||
|
@ -5454,7 +5487,8 @@ fail:
|
||||||
|
|
||||||
static int wpa_driver_nl80211_connect(
|
static int wpa_driver_nl80211_connect(
|
||||||
struct wpa_driver_nl80211_data *drv,
|
struct wpa_driver_nl80211_data *drv,
|
||||||
struct wpa_driver_associate_params *params)
|
struct wpa_driver_associate_params *params,
|
||||||
|
struct nl_handle *nl_connect)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -5464,7 +5498,7 @@ static int wpa_driver_nl80211_connect(
|
||||||
else
|
else
|
||||||
os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
|
os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
|
||||||
|
|
||||||
ret = wpa_driver_nl80211_try_connect(drv, params);
|
ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
|
||||||
if (ret == -EALREADY) {
|
if (ret == -EALREADY) {
|
||||||
/*
|
/*
|
||||||
* cfg80211 does not currently accept new connections if
|
* cfg80211 does not currently accept new connections if
|
||||||
|
@ -5477,7 +5511,7 @@ static int wpa_driver_nl80211_connect(
|
||||||
if (wpa_driver_nl80211_disconnect(
|
if (wpa_driver_nl80211_disconnect(
|
||||||
drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
|
drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
|
||||||
return -1;
|
return -1;
|
||||||
ret = wpa_driver_nl80211_try_connect(drv, params);
|
ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -5502,10 +5536,13 @@ static int wpa_driver_nl80211_associate(
|
||||||
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
|
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
|
||||||
enum nl80211_iftype nlmode = params->p2p ?
|
enum nl80211_iftype nlmode = params->p2p ?
|
||||||
NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
|
NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
|
||||||
|
struct nl_handle *nl_connect = NULL;
|
||||||
|
|
||||||
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
|
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return wpa_driver_nl80211_connect(drv, params);
|
if (params->auth_alg & WPA_AUTH_ALG_SAE)
|
||||||
|
nl_connect = bss->nl_connect;
|
||||||
|
return wpa_driver_nl80211_connect(drv, params, nl_connect);
|
||||||
}
|
}
|
||||||
|
|
||||||
nl80211_mark_disconnected(drv);
|
nl80211_mark_disconnected(drv);
|
||||||
|
@ -7215,7 +7252,7 @@ static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
|
||||||
} else if (bss->nl_preq) {
|
} else if (bss->nl_preq) {
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
|
wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
|
||||||
"reporting nl_preq=%p", bss->nl_preq);
|
"reporting nl_preq=%p", bss->nl_preq);
|
||||||
nl80211_destroy_eloop_handle(&bss->nl_preq);
|
nl80211_destroy_eloop_handle(&bss->nl_preq, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7240,7 +7277,7 @@ static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
|
||||||
|
|
||||||
nl80211_register_eloop_read(&bss->nl_preq,
|
nl80211_register_eloop_read(&bss->nl_preq,
|
||||||
wpa_driver_nl80211_event_receive,
|
wpa_driver_nl80211_event_receive,
|
||||||
bss->nl_cb);
|
bss->nl_cb, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -7555,7 +7592,7 @@ static void nl80211_global_deinit(void *priv)
|
||||||
nl_destroy_handles(&global->nl);
|
nl_destroy_handles(&global->nl);
|
||||||
|
|
||||||
if (global->nl_event)
|
if (global->nl_event)
|
||||||
nl80211_destroy_eloop_handle(&global->nl_event);
|
nl80211_destroy_eloop_handle(&global->nl_event, 0);
|
||||||
|
|
||||||
nl_cb_put(global->nl_cb);
|
nl_cb_put(global->nl_cb);
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct i802_bss {
|
||||||
int if_dynamic;
|
int if_dynamic;
|
||||||
|
|
||||||
void *ctx;
|
void *ctx;
|
||||||
struct nl_handle *nl_preq, *nl_mgmt;
|
struct nl_handle *nl_preq, *nl_mgmt, *nl_connect;
|
||||||
struct nl_cb *nl_cb;
|
struct nl_cb *nl_cb;
|
||||||
|
|
||||||
struct nl80211_wiphy_data *wiphy_data;
|
struct nl80211_wiphy_data *wiphy_data;
|
||||||
|
|
|
@ -2418,9 +2418,6 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
||||||
case NL80211_CMD_NEW_PEER_CANDIDATE:
|
case NL80211_CMD_NEW_PEER_CANDIDATE:
|
||||||
nl80211_new_peer_candidate(drv, tb);
|
nl80211_new_peer_candidate(drv, tb);
|
||||||
break;
|
break;
|
||||||
case NL80211_CMD_EXTERNAL_AUTH:
|
|
||||||
nl80211_external_auth(drv, tb);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||||
"(cmd=%d)", cmd);
|
"(cmd=%d)", cmd);
|
||||||
|
@ -2506,6 +2503,9 @@ int process_bss_event(struct nl_msg *msg, void *arg)
|
||||||
case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
|
case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
|
||||||
nl80211_spurious_frame(bss, tb, 1);
|
nl80211_spurious_frame(bss, tb, 1);
|
||||||
break;
|
break;
|
||||||
|
case NL80211_CMD_EXTERNAL_AUTH:
|
||||||
|
nl80211_external_auth(bss->drv, tb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
|
wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||||
"(cmd=%d)", gnlh->cmd);
|
"(cmd=%d)", gnlh->cmd);
|
||||||
|
|
Loading…
Reference in a new issue