]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Create a netlink socket handle for the Connect interface
authorSunil Dutt <usdutt@codeaurora.org>
Thu, 1 Feb 2018 11:22:57 +0000 (16:52 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 2 Feb 2018 17:02:44 +0000 (19:02 +0200)
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>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_event.c

index d6bf12160b679153aa9f68b50854c7a67092c6d8..dc453ab2771c24f0597b1cfd9397c0072d23e63f 100644 (file)
@@ -130,7 +130,7 @@ static void nl_destroy_handles(struct nl_handle **handle)
 
 static void nl80211_register_eloop_read(struct nl_handle **handle,
                                        eloop_sock_handler handler,
-                                       void *eloop_data)
+                                       void *eloop_data, int persist)
 {
 #ifdef CONFIG_LIBNL20
        /*
@@ -151,13 +151,17 @@ static void nl80211_register_eloop_read(struct nl_handle **handle,
        nl_socket_set_nonblocking(*handle);
        eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
                                 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));
        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_recv_beacons, w);
+                                           nl80211_recv_beacons, w, 0);
        }
 
        dl_list_add(&nl80211_wiphys, &w->list);
@@ -772,7 +776,7 @@ static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
                return;
 
        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);
        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,
                                    wpa_driver_nl80211_event_receive,
-                                   global->nl_cb);
+                                   global->nl_cb, 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,
                                    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)
 {
        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;
        wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
                   "(%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);
 }
@@ -2529,6 +2552,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
        if (drv->vendor_cmd_test_avail)
                qca_vendor_test(drv);
 
+       nl80211_init_connect_handle(bss);
+
        return 0;
 }
 
@@ -2642,6 +2667,9 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
                nl80211_del_p2pdev(bss);
        }
 
+       if (bss->nl_connect)
+               nl80211_destroy_eloop_handle(&bss->nl_connect, 1);
+
        nl80211_destroy_bss(drv->first_bss);
 
        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(
        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;
        enum nl80211_auth_type type;
@@ -5435,7 +5464,11 @@ skip_auth_type:
        if (ret)
                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;
        if (ret) {
                wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
@@ -5454,7 +5487,8 @@ fail:
 
 static int wpa_driver_nl80211_connect(
        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;
 
@@ -5464,7 +5498,7 @@ static int wpa_driver_nl80211_connect(
        else
                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) {
                /*
                 * cfg80211 does not currently accept new connections if
@@ -5477,7 +5511,7 @@ static int wpa_driver_nl80211_connect(
                if (wpa_driver_nl80211_disconnect(
                            drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
                        return -1;
-               ret = wpa_driver_nl80211_try_connect(drv, params);
+               ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
        }
        return ret;
 }
@@ -5502,10 +5536,13 @@ static int wpa_driver_nl80211_associate(
        if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
                enum nl80211_iftype nlmode = params->p2p ?
                        NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
+               struct nl_handle *nl_connect = NULL;
 
                if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
                        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);
@@ -7215,7 +7252,7 @@ static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
                } else if (bss->nl_preq) {
                        wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
                                   "reporting nl_preq=%p", bss->nl_preq);
-                       nl80211_destroy_eloop_handle(&bss->nl_preq);
+                       nl80211_destroy_eloop_handle(&bss->nl_preq, 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,
                                    wpa_driver_nl80211_event_receive,
-                                   bss->nl_cb);
+                                   bss->nl_cb, 0);
 
        return 0;
 
@@ -7555,7 +7592,7 @@ static void nl80211_global_deinit(void *priv)
        nl_destroy_handles(&global->nl);
 
        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);
 
index 23cf9dbeb8b36c5387c44dc3c6ae4bd39817fe01..4bdeaa066cc95a7282a840aa3cd15e52228f0356 100644 (file)
@@ -73,7 +73,7 @@ struct i802_bss {
        int if_dynamic;
 
        void *ctx;
-       struct nl_handle *nl_preq, *nl_mgmt;
+       struct nl_handle *nl_preq, *nl_mgmt, *nl_connect;
        struct nl_cb *nl_cb;
 
        struct nl80211_wiphy_data *wiphy_data;
index 5591cebe81fafb2c0ca071bcb2e788b4b96bceab..66a3667fefd6f701e0013816f913b06162ba0635 100644 (file)
@@ -2418,9 +2418,6 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
        case NL80211_CMD_NEW_PEER_CANDIDATE:
                nl80211_new_peer_candidate(drv, tb);
                break;
-       case NL80211_CMD_EXTERNAL_AUTH:
-               nl80211_external_auth(drv, tb);
-               break;
        default:
                wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
                        "(cmd=%d)", cmd);
@@ -2506,6 +2503,9 @@ int process_bss_event(struct nl_msg *msg, void *arg)
        case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
                nl80211_spurious_frame(bss, tb, 1);
                break;
+       case NL80211_CMD_EXTERNAL_AUTH:
+               nl80211_external_auth(bss->drv, tb);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
                           "(cmd=%d)", gnlh->cmd);