On Fri, Jan 03, 2020 at 04:17:42PM +0100, Markus Theil wrote: > This patch is based on the previous patch from Brendan Jackman > and adds rx support over nl80211. In order to receive frames > over the event nl socket, assoc/connect/beacon setting has to be > performed over the same socket, which should later receive the events. Thanks, I cleaned this up and split the changes into easier to understand smaller commits. I applied the parts that I understood and that did not break hwsim test cases. However, this change to use event nl socket broke large number of test cases, so I could not apply it (i.e., this is enabled only for TX for now). I'm not sure what exactly goes wrong with the RX changes, but it looks like cfg80211 state is somewhat strange when trying to disconnect and try to connect again with a new network (NL80211_CMD_AUTHENTICATE fails). I didn't fully understand what the changes were doing with nl_event and why the changes looked so inconsistent on using send_and_recv_msgs_event() vs. send_and_recv_msmgs(). I tried to fix those, but that did not remove the issues (but probably fixed some other cases that I did not hit yet due to those other problems preventing full testing). Anyway, the change itself did allow a simple test sequence like the ap_wpa2_psk test case to complete full connection on both the AP and station side using the nl80211 control port, so most of the functionality is working, but something is just messing up what happens for following operations. I'm attaching the remaining patches that I could not apply. These include all the cleanup and fixes I did when trying to figure out what is happening. > With this patch ctrl port tx supports the no_encrypt flag. This was fine, but I moved from encrypt to no_encrypt in the driver ops API since this is really a special case requesting frames not to be encrypted when keys are set rather than something that is needed for the normal case where the EAPOL frames should be encrypted if PTK is set. > wpa supplicant now uses the l2 socket only to obtain the device mac > address, future patches may split this out. I could not apply this one because it depends on the nl80211 control port RX path working. > Sending frames over the nl80211 event socket should may be made harder > again, by xor-ing the socket handle outside of send_and_recv_msgs_event. I'm not sure how to interpret this.. Are you noting that something additional should be done in the future or are you commenting that that is already done here? > In order to correctly encrypt rekeying frames, wpa_supplicant now checks > if a PTK is currently installed and sets the corresponding encrypt > option for tx_control_port. I'm not completely confident on this being accurate for all cases, but I applied these as well. Especially PTK rekeying part is unclear since the EAPOL frames need to be encrypted, but with the old key, not the new one. Anyway, all test cases seemed to be passing fine with the changes on the TX path. -- Jouni Malinen PGP id EFC895FA
>From 28f95c6a862341adcf0fb0ab617f6b36c0cc1b61 Mon Sep 17 00:00:00 2001 From: Markus Theil <markus.theil@xxxxxxxxxxxxx> Date: Fri, 3 Jan 2020 16:17:42 +0100 Subject: [PATCH 1/2] FIX: Use control port over nl80211 also for rx path FIX: This seems to break hwsim test cases, e.g., ap_wpa2_psk_file This patch is based on the previous patch from Brendan Jackman and adds rx support over nl80211. In order to receive frames over the event nl socket, assoc/connect/beacon setting has to be performed over the same socket, which should later receive the events. Sending frames over the nl80211 event socket should may be made harder again, by xor-ing the socket handle outside of send_and_recv_msgs_event. Signed-off-by: Markus Theil <markus.theil@xxxxxxxxxxxxx> --- src/drivers/driver_nl80211.c | 56 ++++++++++++++++++++++++++++++------ src/drivers/driver_nl80211.h | 4 +++ 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index ddbd4b4bfec9..cc138aa40112 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -438,6 +438,21 @@ int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, } +int send_and_recv_msgs_event(struct wpa_driver_nl80211_data *drv, + struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + struct nl_sock *handle; + + handle = (void *) (((intptr_t) drv->global->nl_event) ^ + ELOOP_SOCKET_INVALID); + + return send_and_recv(drv->global, handle, msg, + valid_handler, valid_data); +} + + struct family_data { const char *group; int id; @@ -2042,11 +2057,14 @@ 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->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT)) { + drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0); + if (drv->eapol_tx_sock < 0) + goto failed; + } - if (drv->data_tx_status) { + if (!(drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) && + drv->data_tx_status) { int enabled = 1; if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS, @@ -4315,7 +4333,17 @@ static int wpa_driver_nl80211_set_ap(void *priv, } #endif /* CONFIG_IEEE80211AX */ - ret = send_and_recv_msgs(drv, msg, NULL, NULL); + if (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) { + if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_OVER_NL80211) || + nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER) || + nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + ETH_P_PAE)) + goto fail; + ret = send_and_recv_msgs_event(drv, msg, NULL, NULL); + } else { + ret = send_and_recv_msgs(drv, msg, NULL, NULL); + } + if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", ret, strerror(-ret)); @@ -4938,7 +4966,8 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv, * Tell cfg80211 that the interface belongs to the socket that created * it, and the interface should be deleted when the socket is closed. */ - if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER)) + if (!(drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) && + nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER)) goto fail; ret = send_and_recv_msgs(drv, msg, handler, arg); @@ -5796,6 +5825,11 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv, nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT)) return -1; + if ((drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) && + (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_OVER_NL80211) || + nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, ETH_P_PAE))) + return -1; + return 0; } @@ -5989,7 +6023,10 @@ static int wpa_driver_nl80211_associate( goto fail; } - ret = send_and_recv_msgs(drv, msg, NULL, NULL); + if (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) + ret = send_and_recv_msgs_event(drv, msg, NULL, NULL); + else + ret = send_and_recv_msgs(drv, msg, NULL, NULL); msg = NULL; if (ret) { wpa_dbg(drv->ctx, MSG_DEBUG, @@ -9830,7 +9867,10 @@ static int nl80211_join_mesh(struct i802_bss *bss, if (nl80211_put_mesh_config(msg, ¶ms->conf) < 0) goto fail; - ret = send_and_recv_msgs(drv, msg, NULL, NULL); + if (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT) + ret = send_and_recv_msgs_event(drv, msg, NULL, NULL); + else + ret = send_and_recv_msgs(drv, msg, NULL, NULL); msg = NULL; if (ret) { wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)", diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index e4d81b12503a..98ace7d1d44c 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -224,6 +224,10 @@ struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd); int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data); +int send_and_recv_msgs_event(struct wpa_driver_nl80211_data *drv, + struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data); int nl80211_create_iface(struct wpa_driver_nl80211_data *drv, const char *ifname, enum nl80211_iftype iftype, const u8 *addr, int wds, -- 2.20.1
>From d6efd84962b0190f3aba9af097811a2251ffb404 Mon Sep 17 00:00:00 2001 From: Markus Theil <markus.theil@xxxxxxxxxxxxx> Date: Fri, 3 Jan 2020 16:17:42 +0100 Subject: [PATCH 2/2] FIX: Close l2_packet socket after getting own MAC address FIX: Cannot apply this without the currently broken nl80211-RX-related patch. wpa_supplicant now uses the l2_packet socket only to obtain the local device MAC address. Future patches may split this out. Signed-off-by: Markus Theil <markus.theil@xxxxxxxxxxxxx> --- wpa_supplicant/wpa_supplicant.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 0a9e37c3b01c..18e5dadcc9a6 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4685,6 +4685,12 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr); wpas_wps_update_mac_addr(wpa_s); + /* use l2 socket only to get local MAC address */ + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT) { + l2_packet_deinit(wpa_s->l2); + wpa_s->l2 = NULL; + } + #ifdef CONFIG_FST if (wpa_s->fst) fst_update_mac_addr(wpa_s->fst, wpa_s->own_addr); -- 2.20.1
_______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap