From nobody Sun Feb 18 21:11:14 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TdJHl2tLPz5Bm3d; Sun, 18 Feb 2024 21:11:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TdJHl0Spfz42GY; Sun, 18 Feb 2024 21:11:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708290675; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rhGkhLGcIzzKHnmU+z5lqhzacpaJqSxFdZJ9HzCRhHY=; b=kS6AZIyEiPXhD9OJBYfrnvQScC6rSg+Gnrt1ROrWc9kIZPBb1X2EZHDrVxqUtNHXuPPmqt /dFAzwM0+disGqdIdDqV1z2JNn5hK445EqmJsj3H6PNH+baknCRogQhBKhb8HgpbA5vLd7 +GErbTJ/Od5NmCRxFfG5K4bFcwOUkUWLek85EOTbv5zhZsj/0aZUpSbVO+Kpu5HwN/1Z2/ b50ovjm7hi7X/NTjS9ukIZUzL8TSXV2lbiEqw9kGJt6Mmq77NI66gal38Ew7l7XBKWYDvv U617Z1yRg0fQrqVPwKJdR+D6kIGAI0He5JPts/B9vxhaeZR7E+sNeXl8iAzrwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708290675; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rhGkhLGcIzzKHnmU+z5lqhzacpaJqSxFdZJ9HzCRhHY=; b=r6XwgYuhipW8iZ7kiPhBVOtvmTTVDilp6qkPUWoGR5EQTHQWWHbUIE/RkS30XEhl0++ymF 0yzbSb9dPtl7wn74MtNMmF6ee13sOd4CwW8wNzPKx0s8bbW112QnoSEpPLB5UVbwcZgH5e 03bKllnT2sBcRzctL7OERmCSUMDk9EST1Wk/qG0tZHTUX6NTU3SpZhCjGgNEWk1OLD7XhU 27HZFHUQE62HtBv7BYXm0o/Z/HaKJ+iBJ5nHujQXOBTeCli8gviugmyGluFA7ZVtIcO1qZ zKQNU6bmarg45mMNTZrrt55FcXorWd30c8/peTJ7dX3IMjV8Ln70lnzu6mFtxQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1708290675; a=rsa-sha256; cv=none; b=Y3ovH/Wf1o/nA4B2V+Ubm3pxjjuKRXqaVhgSdy1A8EythgSm3mcQWpG6CTluEv1YzsrwvY FHDVY5kc22tWqH/KBhYWuBY+wpb5Xcm6H8W+u4DhFREhiSYD1fanrbn9I5Mmd1XsTShk+o RMojw1Ee+evE+XU+a/hssum+baCarma+oMWmGBnjjpY5d8cceHVbLngiCZOTg1juVvvwq9 cmCSZsgkzQVXlXvrznDgftYGB6tjKZuWGbAEO0KUMlTaQRMirxyqTZ7zINgP1y2GvszrsU 00DETAWFpw+/sxFc+hgVc1suTZVfd+RDZKCPY7XM3jceL7KjDHMi02fh4PNwIg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TdJHk6hNsz16WL; Sun, 18 Feb 2024 21:11:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 41ILBEd4013666; Sun, 18 Feb 2024 21:11:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41ILBElJ013652; Sun, 18 Feb 2024 21:11:14 GMT (envelope-from git) Date: Sun, 18 Feb 2024 21:11:14 GMT Message-Id: <202402182111.41ILBElJ013652@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: e1d739471efd - stable/14 - tools/net80211: add mlme_assoc List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: e1d739471efdc6fe32af570e4bd07875a7e502ff Auto-Submitted: auto-generated The branch stable/14 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=e1d739471efdc6fe32af570e4bd07875a7e502ff commit e1d739471efdc6fe32af570e4bd07875a7e502ff Author: Bjoern A. Zeeb AuthorDate: 2023-12-01 01:37:25 +0000 Commit: Bjoern A. Zeeb CommitDate: 2024-02-18 18:31:13 +0000 tools/net80211: add mlme_assoc mlme_assoc is a tool to trigger net80211::ieee80211_sta_join1() calls which in certain conditions cause problems to the LinuxKPI 802.11 compat code (but also believed to possibly cause problems in case of race to other firmware based drivers). This has proven to be a good reproducer for the problem even on setups which otherwise could run for days without hitting it. Sponsored by: The FreeBSD Foundation PR: 271979 (cherry picked from commit 643d6dce6c1e39f067f8d0feea8615913b324891) --- tools/tools/net80211/mlme_assoc/Makefile | 7 + tools/tools/net80211/mlme_assoc/README | 51 +++++++ tools/tools/net80211/mlme_assoc/mlme_assoc.c | 200 +++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) diff --git a/tools/tools/net80211/mlme_assoc/Makefile b/tools/tools/net80211/mlme_assoc/Makefile new file mode 100644 index 000000000000..580fb045ac52 --- /dev/null +++ b/tools/tools/net80211/mlme_assoc/Makefile @@ -0,0 +1,7 @@ +PROG= mlme_assoc +BINDIR= /usr/bin +MAN= + +SRCS= mlme_assoc.c + +.include diff --git a/tools/tools/net80211/mlme_assoc/README b/tools/tools/net80211/mlme_assoc/README new file mode 100644 index 000000000000..fc5e754a58d6 --- /dev/null +++ b/tools/tools/net80211/mlme_assoc/README @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2023 The FreeBSD Foundation +# +# This documentation was written by Björn Zeeb under sponsorship from +# the FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +This is a simple program to drive net80211::ieee80211_sta_join1() calls from +user space. + +The program optionally accepts an interface name (e.g., wlan42), or an +interface name, an SSID and a BSSID. + +In the former case of no SSID/BSSID passed it will query the scan results and +then try to join each entry from the scan with a short delay. + +In the lastter case giving the SSID/BSSID one can trigger the "canreassoc" case +in ieee80211_sta_join1() or not depending on whether one passes the currently +associated SSID/BSSID or not. + +The tool is useful to trigger net80211::newstate() changes while other +newstate() changes are pending or being executed. + +I was specifically developed to show a problem with the LinuxKPI 802.11 compat +code. The reason is that ieee80211_sta_join1() also calls in (*iv_update_bss)() +swapping nodes before initiating the state changes and in LinuxKPI state is on +the sta and not the vif causing all kinds of troubles, especially if we lose +a state transition before the taskq is run or if the iv_bss node gets swapped +before a task is executed. diff --git a/tools/tools/net80211/mlme_assoc/mlme_assoc.c b/tools/tools/net80211/mlme_assoc/mlme_assoc.c new file mode 100644 index 000000000000..c26aaa03fe87 --- /dev/null +++ b/tools/tools/net80211/mlme_assoc/mlme_assoc.c @@ -0,0 +1,200 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Björn Zeeb under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * First get scan results in a hurry. + * Pick a random BSSID and try to assoc. + * Hopefully this is enough to trigger the newstate race along with the + * (*iv_update_bss)() logic. + * + * Alternatively pass IF SSID BSSID in and just try that. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +static int +if_up(int sd, const char *ifnam) +{ + struct ifreq ifr; + int error; + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name)); + + error = ioctl(sd, SIOCGIFFLAGS, &ifr); + if (error == -1) { + warn("SIOCGIFFLAGS"); + return (error); + } + + if (ifr.ifr_flags & IFF_UP) + return (0); + + ifr.ifr_flags |= IFF_UP; + + error = ioctl(sd, SIOCSIFFLAGS, &ifr); + if (error == -1) { + warn("SIOCSIFFLAGS"); + return (error); + } + + return (0); +} + +static int +try_mlme_assoc(int sd, const char *ifnam, uint8_t *ssid, uint8_t ssid_len, uint8_t *bssid) +{ + struct ieee80211req ireq; + struct ieee80211req_mlme mlme; + int error; + + memset(&mlme, 0, sizeof(mlme)); + mlme.im_op = IEEE80211_MLME_ASSOC; + if (ssid != NULL) + memcpy(mlme.im_ssid, ssid, ssid_len); + mlme.im_ssid_len = ssid_len; + if (bssid != NULL) + memcpy(mlme.im_macaddr, bssid, IEEE80211_ADDR_LEN); + + memset(&ireq, 0, sizeof(ireq)); + strlcpy(ireq.i_name, ifnam, sizeof(ireq.i_name)); + ireq.i_type = IEEE80211_IOC_MLME; + ireq.i_val = 0; + ireq.i_data = (void *)&mlme; + ireq.i_len = sizeof(mlme); + + error = ioctl(sd, SIOCS80211, &ireq); + if (error == -1) { + warn("SIOCS80211, %#x", ireq.i_type); + return (error); + } + + return (0); +} + +static int +mlme_assoc_scan_results(int sd, const char *ifnam) +{ + struct ieee80211req ireq; + struct ieee80211req_scan_result *sr; + uint8_t buf[32 * 1024], *p; + ssize_t len; + int error; + + memset(&ireq, 0, sizeof(ireq)); + strlcpy(ireq.i_name, ifnam, sizeof(ireq.i_name)); + ireq.i_type = IEEE80211_IOC_SCAN_RESULTS; + ireq.i_data = (void *)buf; + ireq.i_len = sizeof(buf); + + error = ioctl(sd, SIOCG80211, &ireq); + if (error == -1 || ireq.i_len < 0) { + warn("SIOCG80211, %#x", ireq.i_type); + return (error); + } + + p = buf; + len = ireq.i_len; + while (len > (ssize_t)sizeof(*sr)) { + sr = (struct ieee80211req_scan_result *)(void *)p; + p += sr->isr_len; + len -= sr->isr_len; + + error = try_mlme_assoc(sd, ifnam, (void *)(sr + 1), sr->isr_ssid_len, + sr->isr_bssid); + if (error != 0) { + warnx("try_mlme_assoc"); + return (error); + } + + usleep(100000); + } + + return (0); +} + +int +main(int argc, char *argv[]) +{ + const char *ifnam; + uint8_t *ssid, *bssid; + struct ether_addr ea; + int error, sd; + + ifnam = "wlan0"; + ssid = NULL; + bssid = NULL; + + if (argc == 4) { + ifnam = argv[1]; + ssid = (uint8_t *)argv[2]; + bssid = (uint8_t *)ether_aton_r(argv[3], &ea); + if (bssid == NULL) + warnx("ether_aton_r, ignoring BSSID"); + } else if (argc == 2) { + ifnam = argv[1]; + } + + sd = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (sd == -1) + errx(EX_UNAVAILABLE, "socket"); + + error = if_up(sd, ifnam); + if (error != 0) + errx(EX_UNAVAILABLE, "if_up"); + + if (argc == 4) { + error = try_mlme_assoc(sd, ifnam, ssid, strlen((const char *)ssid), bssid); + if (error != 0) + errx(EX_UNAVAILABLE, "try_mlme_assoc"); + + } else { + error = mlme_assoc_scan_results(sd, ifnam); + if (error != 0) + errx(EX_UNAVAILABLE, "mlme_assoc_scan_results"); + } + + close(sd); + + return (0); +}