From nobody Fri Jul 24 23:30:09 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42F543BD22F for ; Wed, 22 Jul 2026 07:07:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704065; cv=none; b=bgqeLF2XtuL1aesRrniGtZ3IIX22NT5g7ER4cdbUWwJz3ljbtUu2ueYltE7UDHNNObIQco2egxjdz57Z/Qi26BBn2hUVZwkeU1YR09QrwKTZzts/b5Rm2RWxRT/7xFKfSJcHc2WGhNqE0gHs/ReVr2sbvwsTeMPxMwCfGxtSoh8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704065; c=relaxed/simple; bh=MgByV0Tlub9VinUkUuHNK72OBiVzMw/nFbBw/Dd/bYc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pn4gQzdyE3wH3iC/vhn1V+K+w4InDjoB8DKb5UzZuGPv3aobwjnRwd7WMA+RSQwFitC/8LG3hSAD2v4RiE1VgVIHvSndazfjl+sS2L0yG8yjI/uvYzmWU4MOuXOZyx5rIuff+FjgJGlNx06J/LHCHu3HPNORj7icBWpv8u3ims4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=k3ePY9Wc; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k3ePY9Wc" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-490cf322ed0so88171355e9.1 for ; Wed, 22 Jul 2026 00:07:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784704061; x=1785308861; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=k69g0iM0Xhrh1qoTi7U6OlgKbSMioEAgJAhLpRRzuDw=; b=k3ePY9Wcn8d8rb02rKkeP3RHYzE/cgAQyicXARuhA9VQ6eaVa7lth5ev9e0vbh2XZ1 E8jv0fRBKWF0JWSJU2lxg4vO5u8a5ilTlv7TAAKXFoMfq07w2gaL9VU3OT8+8EDGH0TI ZxWx7TjSTL6A6mX3RGRdjlaBie7ASj7tYDzfBuc5gLF2DGoDg8HaCSy3EFMRGBRBJt45 0Ouo/skqUkjXEYP4hwjsjS51NxW9U6a6qQ9rPYzQfNqoUU7DB1tjcD5PygXtSGMNqIgL JHXK8q5hGsMimyfe2c/e9f+wOKBmf32utwBLz95EM0MSBSTcKWPRRIFwdgcKAVEEEmtu hO9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784704061; x=1785308861; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=k69g0iM0Xhrh1qoTi7U6OlgKbSMioEAgJAhLpRRzuDw=; b=jDdg5RjgKg6mHG5yGfUmURjeZqzwoBJgAihiXQCEJ2mk7cDf2+VUSIKIjRI+Z6QSXu Rx+Ha0gK9WjbEgm8D6ZDAnC2VUVeGaMFqmWZ46qi0k5CjNXv/7BPFeuEL4u/6l1zMTtN OLY/vBKumwkBz3jMOBzv9MlTmQ84qmzqzqF8NQCfi2Q3ih268qgvLFb5HHyycWb5xVMI w2SW78d9CrVhhyCt7GgTURhe7y9rAYPtSoAc8lJbWFL0bAvqcILuCI2ASn0qy77W3KZm jikW5BY1LbW7qCdmoSFie3pBvb2MzecbgHClVTZ2V/xXcbYxT2bI3QblgiV+nOxGUBwo IToA== X-Forwarded-Encrypted: i=1; AHgh+RpgdzDU5STx8LombyR3MzzKzNvbrBMnz8abXhVGJqhm6+qxv4iPAqKdmoqnpVBnN6ItA1+lpGKhJP0fIUc=@vger.kernel.org X-Gm-Message-State: AOJu0YxOfrHnjbm2yoQmV1scXOVj2nXFlmYJvZfF0XfBOEz9OG+QQ3e0 XKa+cq9ZBal57R6Adttmw+4C5+KVDDTXJSThovWYo3d+AN+IhOa9Jx24qjqrCCUxeaM= X-Gm-Gg: AR+sD13et4FDxvctGKL8HaV9qWn3xiTp7eP1ojoY0LVrfKgV9WIie80fD5CeYbSlSiw Vilz3TJncQtNDDzeYBWzzUKgXSuo6FFfAuTXOswUJ8qaa+WW8r/25+bsUcKDViKgUDEWNX8v+l6 a6Cym47/mlY8brJlJK549Huzii6qQJ9ivrIsQYryCUnmmNz8aGnWZi2EQRJdSEOdGhjvx5GOCCE zQvS5l+03rTonyrU79YqDiFaeJD46XbSsVDFXgFgIXaGMWPrW5aHU7Bsp9B8vfU95RZzphmGjVW qcY1XXVGCTXRM/dZJcyOwpm9c88eMbq4Xn/iahSsvRJQV1o90K3WC8FQpD0TTEhXAjc8Vly0t5r BBY3n2BjHSw047Ht0rfqpSvcenKIAUOSia0yggRa1H1Zkh0uasQDq0G5AcgAu2d7AaNuQ9/KjLt eibAC/F5eICojBNPup3c/RBChQDgvTubc5p7bY X-Received: by 2002:a05:600c:4512:b0:493:bc4a:fb56 with SMTP id 5b1f17b1804b1-4954a50e92bmr242989165e9.39.1784704061349; Wed, 22 Jul 2026 00:07:41 -0700 (PDT) Received: from localhost ([102.128.173.0]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-495653c9d99sm127305425e9.12.2026.07.22.00.07.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 00:07:41 -0700 (PDT) From: Louis Kotze To: Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, loukot@gmail.com Subject: [PATCH v3 1/2] wifi: cfg80211: say why the auth/assoc BSS lookup failed Date: Wed, 22 Jul 2026 09:07:33 +0200 Message-ID: <20260722070734.3612581-2-loukot@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260722070734.3612581-1-loukot@gmail.com> References: <20260722070734.3612581-1-loukot@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The BSS lookup for an authentication or association request can fail for three distinct reasons: cfg80211 has no scan entry at all for the BSSID/channel, an entry exists but is older than IEEE80211_SCAN_RESULT_EXPIRE (and not held), or a fresh entry exists but its use_for flags do not allow this use. All three currently surface as the same generic extack message "Error fetching BSS for link" on the MLO association path, and as a bare -ENOENT with no message at all on the authentication and non-MLO association paths. Since wpa_supplicant logs the extack message verbatim ("nl80211: kernel reports: ..."), that message is often the only diagnostic a user sees when an MLO association degrades to fewer links, and it does not say whether a fresh scan could have helped. In practice the expired case is common for MLO partner links: 6 GHz is passive-scan in many regulatory domains, so the partner-link entry is routinely stale by the time userspace requests the association even though the link is perfectly usable. Let __cfg80211_get_bss() take an optional extack and record, during the same bss_lock walk that fails the lookup, whether any matching entry was rejected for being expired or for not being usable for the requested use, and set a distinct message for each case (and a combined one when different entries were rejected for different reasons). Reorder the checks in the walk so that an entry's identity (type, privacy, channel, BSSID/SSID) is established before the usability checks; this doesn't change which entry is returned since an entry is only used when all checks pass. Also give the -EINVAL paths in nl80211_assoc_bss() proper messages while at it, and keep pointing the bad_attr at the failing link on the MLO path there; the message for that case is already set by the lookup itself. Signed-off-by: Louis Kotze --- v3: use GENL_SET_ERR_MSG for the -EINVAL messages; comment the bare NL_SET_BAD_ATTR (the lookup already set the specific message); comment the check ordering in the walk; combined message when matching entries were rejected for different reasons; drop the "scan again" instruction; minimal diff at the nl80211_associate() call site. v2: capture the reason inside __cfg80211_get_bss() during the single bss_lock walk (per Johannes' feedback on v1); cover the auth path; KUnit test added as patch 2. include/net/cfg80211.h | 7 +++++-- net/wireless/nl80211.c | 27 +++++++++++++++--------- net/wireless/scan.c | 44 ++++++++++++++++++++++++++++++++------- net/wireless/tests/scan.c | 2 +- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b8e9fbb89e69..15c08b24502f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -8424,6 +8424,8 @@ cfg80211_inform_bss(struct wiphy *wiphy, * @bss_type: type of BSS, see &enum ieee80211_bss_type * @privacy: privacy filter, see &enum ieee80211_privacy * @use_for: indicates which use is intended + * @extack: (optional) extack that is filled with the reason when no + * usable entry was found; may be %NULL * * Return: Reference-counted BSS on success. %NULL on error. */ @@ -8433,7 +8435,8 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiphy = *wiphy, const u8 *ssid, size_t ssid_len, enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy, - u32 use_for); + u32 use_for, + struct netlink_ext_ack *extack); =20 /** * cfg80211_get_bss - get a BSS reference @@ -8457,7 +8460,7 @@ cfg80211_get_bss(struct wiphy *wiphy, struct ieee8021= 1_channel *channel, { return __cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type, privacy, - NL80211_BSS_USE_FOR_NORMAL); + NL80211_BSS_USE_FOR_NORMAL, NULL); } =20 static inline struct cfg80211_bss * diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d962b5944533..ac0c0da45241 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12890,9 +12890,11 @@ static int nl80211_authenticate(struct sk_buff *sk= b, struct genl_info *info) return -EINVAL; } =20 - req.bss =3D cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, - IEEE80211_BSS_TYPE_ESS, - IEEE80211_PRIVACY_ANY); + req.bss =3D __cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, + info->extack); if (!req.bss) return -ENOENT; =20 @@ -13037,6 +13039,7 @@ static int nl80211_crypto_settings(struct cfg80211_= registered_device *rdev, } =20 static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_d= evice *rdev, + struct genl_info *info, const u8 *ssid, int ssid_len, struct nlattr **attrs, int assoc_link_id, int link_id) @@ -13046,8 +13049,10 @@ static struct cfg80211_bss *nl80211_assoc_bss(stru= ct cfg80211_registered_device const u8 *bssid; u32 freq, use_for =3D 0; =20 - if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_WIPHY_FREQ]) + if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_WIPHY_FREQ]) { + GENL_SET_ERR_MSG(info, "BSSID or frequency missing"); return ERR_PTR(-EINVAL); + } =20 bssid =3D nla_data(attrs[NL80211_ATTR_MAC]); =20 @@ -13056,8 +13061,10 @@ static struct cfg80211_bss *nl80211_assoc_bss(stru= ct cfg80211_registered_device freq +=3D nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); =20 chan =3D nl80211_get_valid_chan(&rdev->wiphy, freq); - if (!chan) + if (!chan) { + GENL_SET_ERR_MSG(info, "invalid or disabled channel"); return ERR_PTR(-EINVAL); + } =20 if (assoc_link_id >=3D 0) use_for =3D NL80211_BSS_USE_FOR_MLD_LINK; @@ -13068,7 +13075,7 @@ static struct cfg80211_bss *nl80211_assoc_bss(struc= t cfg80211_registered_device ssid, ssid_len, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY, - use_for); + use_for, info->extack); if (!bss) return ERR_PTR(-ENOENT); =20 @@ -13107,13 +13114,13 @@ static int nl80211_process_links(struct cfg80211_= registered_device *rdev, return -EINVAL; } links[link_id].bss =3D - nl80211_assoc_bss(rdev, ssid, ssid_len, attrs, + nl80211_assoc_bss(rdev, info, ssid, ssid_len, attrs, assoc_link_id, link_id); if (IS_ERR(links[link_id].bss)) { err =3D PTR_ERR(links[link_id].bss); links[link_id].bss =3D NULL; - NL_SET_ERR_MSG_ATTR(info->extack, link, - "Error fetching BSS for link"); + /* the BSS lookup set the specific message already */ + NL_SET_BAD_ATTR(info->extack, link); return err; } =20 @@ -13329,7 +13336,7 @@ static int nl80211_associate(struct sk_buff *skb, s= truct genl_info *info) if (req.link_id >=3D 0) return -EINVAL; =20 - req.bss =3D nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs, + req.bss =3D nl80211_assoc_bss(rdev, info, ssid, ssid_len, info->attrs, -1, -1); if (IS_ERR(req.bss)) return PTR_ERR(req.bss); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index e62b7dd2b7c2..90a4f285654f 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1609,10 +1609,12 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiph= y *wiphy, const u8 *ssid, size_t ssid_len, enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy, - u32 use_for) + u32 use_for, + struct netlink_ext_ack *extack) { struct cfg80211_registered_device *rdev =3D wiphy_to_rdev(wiphy); struct cfg80211_internal_bss *bss, *res =3D NULL; + bool expired =3D false, unusable =3D false; unsigned long now =3D jiffies; int bss_privacy; =20 @@ -1634,22 +1636,48 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiph= y *wiphy, continue; if (!is_valid_ether_addr(bss->pub.bssid)) continue; - if ((bss->pub.use_for & use_for) !=3D use_for) + if (!is_bss(&bss->pub, bssid, ssid, ssid_len)) continue; + + /* + * The identity checks above must all come first so that + * the expired/unusable classification below only ever + * applies to entries that actually match the request. + */ + /* Don't get expired BSS structs */ if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && - !atomic_read(&bss->hold)) + !atomic_read(&bss->hold)) { + expired =3D true; + continue; + } + + if ((bss->pub.use_for & use_for) !=3D use_for) { + unusable =3D true; continue; - if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { - res =3D bss; - bss_ref_get(rdev, res); - break; } + + res =3D bss; + bss_ref_get(rdev, res); + break; } =20 spin_unlock_bh(&rdev->bss_lock); - if (!res) + if (!res) { + if (expired && unusable) + NL_SET_ERR_MSG(extack, + "BSS entries are expired or cannot be used for the requested op= eration"); + else if (unusable) + NL_SET_ERR_MSG(extack, + "BSS cannot be used for the requested operation"); + else if (expired) + NL_SET_ERR_MSG(extack, + "BSS entry in scan results is expired"); + else + NL_SET_ERR_MSG(extack, + "BSS not found in scan results"); return NULL; + } trace_cfg80211_return_bss(&res->pub); return &res->pub; } diff --git a/net/wireless/tests/scan.c b/net/wireless/tests/scan.c index b1a9c1466d6c..2fc717317ac3 100644 --- a/net/wireless/tests/scan.c +++ b/net/wireless/tests/scan.c @@ -617,7 +617,7 @@ static void test_inform_bss_ml_sta(struct kunit *test) link_bss =3D __cfg80211_get_bss(wiphy, NULL, sta_prof.bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY, - 0); + 0, NULL); KUNIT_ASSERT_NOT_NULL(test, link_bss); KUNIT_EXPECT_EQ(test, link_bss->signal, 0); KUNIT_EXPECT_EQ(test, link_bss->beacon_interval, --=20 2.55.0 From nobody Fri Jul 24 23:30:09 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED034374186 for ; Wed, 22 Jul 2026 07:07:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704068; cv=none; b=IwJhXZ9tTDPMhovolwkd4OpwxYGA7zlAFHLSReZGhfFqbJN5d/zZMyq3fMytACsT4pBlOCITc8WfqgT8GYa0rfEPtu2xucPcibM3CngyxXxqlbP66nzWLADXpefG9lUvGTW59sTX5LTI6b5hXjsILFa4Z4JdHOEuQoOo1NCUBLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784704068; c=relaxed/simple; bh=+X2E/22QaYLRENUgNqGRydH/mkfev9mfmAWEy06FM60=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gb2pJ4Pzt9TCdXTploQK89zQZWXtQ4jI5KTOeuCL+JxyBJapnKGLL368iyZrMPBloRusbtfDh2UMZkILbbJocxpEuUayaPzA6AYEi+SIcNJiSsrJXVEfl4uVqMwqt2/qgoP6sSWXtFyhXszBMKV6IkGt2SWZrEjngbeCudVueSg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=empDKopO; arc=none smtp.client-ip=209.85.128.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="empDKopO" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4953e04ef16so62525395e9.2 for ; Wed, 22 Jul 2026 00:07:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784704065; x=1785308865; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rzOcSgcI8Ri1oJDweL+5pSLHXb3yiUThMbTxJzoHi0U=; b=empDKopO3dMAdZ4wE3tWvA5T6y04qrL9dLaiTPlDgkrX7hDkXAnbIwl7T1/PPRvwtV 7NvNpgadWSMSkOQnZLXBvZJsZWP1PHonUSCOcXxw9I6mJRw/ngpFYPdg61/I4+oHykIw jQrDc3ppaEgpDs2nR2JDpzMEO++DWkLcQ9IZsZd7MlQhasa7EdLou1ThG4kdZQRaNgK4 TxxYU72qphFyus5jC0nzJ/Bahm7rEbK6UlfRSDXI0jFFGim4LnYEk+PbWoStN80AX3ju lelCV/iMaO/3i1yWR1ppaLuPRx2l3rOPYRRWc2H0TVUFNgf/mML4hn9slFbgufCcmNFi 5UUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784704065; x=1785308865; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rzOcSgcI8Ri1oJDweL+5pSLHXb3yiUThMbTxJzoHi0U=; b=VZvDHQ8BaOaVkqBtrYU2HI9LpgbbVq6axjHaEigw4HWkS3IQXe43bYwVqlw9jUaAHz HZjXKl4KzJk5Eny8ZR+vdHO86PTM1rzzXDVHZrCb61Fo76BQSnjfh0yRmLHH+tFG3+6f Lm9HXwid0N+IPgDxs+ekD8TfYRUA/7Xi6P4GvLfaIUSAFKIMKmkoMR5XfJ0wapb/UIsg GpGR9Hz48aoeFqnkcCE1CXgnzH3llU9OMIrrWE+7KtRe5N3KXyEieSjG0u1AmuzGEnMa c2D4Whh4swuYO4VG1o+LKXSUgevniAt30R37Gke3VPtgHgj3maheEsHmhBosZ2o6fXQu g4iA== X-Forwarded-Encrypted: i=1; AHgh+RpEtZeRR8OXR19zFUC7lcPHeDoiIR3koamwtD2M1orYsF4A9RWO63meR/28WZTPZQ8wFFE3bmQH56P83W4=@vger.kernel.org X-Gm-Message-State: AOJu0YyC13wgRJIGQf8WIE047EJakyLgVveYfiHRZlXI52s7XKEu2/5G eTe3012I4j7RcAdardsLSdCv73Czv25U+6QmDOdUoqr4XOqFywwZcAVy X-Gm-Gg: AR+sD10/dLL+YK77+R4YR7NwceorXrKq2cWGygx/G/PvibFsBs+IDH/XY46APv+5Ir9 gpxwTpfLKnpiy1Ul+b0zI7gPEYwuc6eDD6BUtdAf5oV7EraC2qZ4ySNlHFjIJGHRqnNRC07hnge FB5kfUoA6qjz0R4N8lhscmL6xdSBzzrL/UnUgYC5W6UrJOMeA0sehxIEzDm3J+kpP/kRmIPiEU5 w0KEgRB03HdI0dlFvgplE1AHAa+kHriq4cNux3aN1klyFsGptjQ00ejXqPzYEdxNtf+cdQgzOEM tQL4avOw9DS31hyfmFxS+ve3lYNQ0w6XlW2r6/QYDl3m4rvt2NuleoXHUCea6sH0MjARJ1pP21F bUqgr5wPfAKqG7h9OzhsnXRr8/NstFcEe2xxz9jgJ3eUFbfVHGJC6sCuJnD13XD1d9Zi5M7/j5p sgPeQYIe44RT2fxBRcIk//b3H8tQ== X-Received: by 2002:a05:600c:4505:b0:493:f176:dc69 with SMTP id 5b1f17b1804b1-4954a413087mr230313795e9.37.1784704064934; Wed, 22 Jul 2026 00:07:44 -0700 (PDT) Received: from localhost ([102.128.173.0]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956bc68d4esm18301485e9.0.2026.07.22.00.07.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 00:07:44 -0700 (PDT) From: Louis Kotze To: Johannes Berg Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, loukot@gmail.com Subject: [PATCH v3 2/2] wifi: cfg80211: tests: check BSS lookup failure reasons Date: Wed, 22 Jul 2026 09:07:34 +0200 Message-ID: <20260722070734.3612581-3-loukot@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260722070734.3612581-1-loukot@gmail.com> References: <20260722070734.3612581-1-loukot@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a KUnit test for the extack failure reasons that __cfg80211_get_bss() now reports: no matching scan entry at all, a matching entry that is expired, and a matching entry whose use_for flags do not allow the requested use. Also cover the cases that must not report a failure (a fresh entry, and an expired-but-held entry), an entry that is both expired and unusable, and the combined message when one matching entry is expired while another is current but unusable. Signed-off-by: Louis Kotze --- v3: message strings updated to match patch 1; the cross-entry case now checks the combined message. net/wireless/tests/scan.c | 119 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/net/wireless/tests/scan.c b/net/wireless/tests/scan.c index 2fc717317ac3..8c20278b5d3a 100644 --- a/net/wireless/tests/scan.c +++ b/net/wireless/tests/scan.c @@ -402,6 +402,124 @@ static void test_inform_bss_ssid_only(struct kunit *t= est) cfg80211_put_bss(wiphy, bss); } =20 +static void test_get_bss_miss_reason(struct kunit *test) +{ + struct inform_bss ctx =3D { + .test =3D test, + }; + struct wiphy *wiphy =3D T_WIPHY(test, ctx); + struct cfg80211_inform_bss inform_bss =3D { + .signal =3D 50, + .drv_data =3D &ctx, + }; + const u8 bssid[ETH_ALEN] =3D { 0x10, 0x22, 0x33, 0x44, 0x55, 0x66 }; + const u8 other_bssid[ETH_ALEN] =3D { 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; + static const u8 ies[] =3D { + [0] =3D WLAN_EID_SSID, + [1] =3D 4, + [2] =3D 'T', 'E', 'S', 'T' + }; + struct cfg80211_internal_bss *ibss; + struct netlink_ext_ack extack =3D {}; + struct cfg80211_bss *bss, *bss2, *found; + + inform_bss.chan =3D ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(2412)); + KUNIT_ASSERT_NOT_NULL(test, inform_bss.chan); + + bss =3D cfg80211_inform_bss_data(wiphy, &inform_bss, + CFG80211_BSS_FTYPE_PRESP, bssid, 0, + 0x1234, 100, ies, sizeof(ies), + GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, bss); + ibss =3D container_of(bss, struct cfg80211_internal_bss, pub); + + /* Fresh usable entry: found, no message is set */ + found =3D __cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_ASSERT_PTR_EQ(test, found, bss); + KUNIT_EXPECT_NULL(test, extack._msg); + cfg80211_put_bss(wiphy, found); + + /* No entry at all for this BSSID */ + found =3D __cfg80211_get_bss(wiphy, NULL, other_bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_EXPECT_NULL(test, found); + KUNIT_EXPECT_STREQ(test, extack._msg, "BSS not found in scan results"); + + /* Fresh entry that is not usable for the requested use */ + extack._msg =3D NULL; + bss->use_for =3D 0; + found =3D __cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_EXPECT_NULL(test, found); + KUNIT_EXPECT_STREQ(test, extack._msg, + "BSS cannot be used for the requested operation"); + bss->use_for =3D NL80211_BSS_USE_FOR_ALL; + + /* Expired entry, > IEEE80211_SCAN_RESULT_EXPIRE (30s) old */ + extack._msg =3D NULL; + ibss->ts =3D jiffies - 60 * HZ; + found =3D __cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_EXPECT_NULL(test, found); + KUNIT_EXPECT_STREQ(test, extack._msg, + "BSS entry in scan results is expired"); + + /* An entry both expired and unusable reports expired */ + extack._msg =3D NULL; + bss->use_for =3D 0; + found =3D __cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_EXPECT_NULL(test, found); + KUNIT_EXPECT_STREQ(test, extack._msg, + "BSS entry in scan results is expired"); + bss->use_for =3D NL80211_BSS_USE_FOR_ALL; + + /* Expired but held entries are still usable, no message is set */ + extack._msg =3D NULL; + atomic_set(&ibss->hold, 1); + found =3D __cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_ASSERT_PTR_EQ(test, found, bss); + KUNIT_EXPECT_NULL(test, extack._msg); + cfg80211_put_bss(wiphy, found); + atomic_set(&ibss->hold, 0); + + /* + * With one matching entry expired and another current but + * unusable, both reasons are reported. + */ + bss2 =3D cfg80211_inform_bss_data(wiphy, &inform_bss, + CFG80211_BSS_FTYPE_PRESP, other_bssid, + 0, 0x1234, 100, ies, sizeof(ies), + GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, bss2); + bss2->use_for =3D 0; + extack._msg =3D NULL; + found =3D __cfg80211_get_bss(wiphy, NULL, NULL, "TEST", 4, + IEEE80211_BSS_TYPE_ANY, + IEEE80211_PRIVACY_ANY, + NL80211_BSS_USE_FOR_NORMAL, &extack); + KUNIT_EXPECT_NULL(test, found); + KUNIT_EXPECT_STREQ(test, extack._msg, + "BSS entries are expired or cannot be used for the requested operati= on"); + + cfg80211_put_bss(wiphy, bss2); + cfg80211_put_bss(wiphy, bss); +} + static struct inform_bss_ml_sta_case { const char *desc; int mld_id; @@ -855,6 +973,7 @@ kunit_test_suite(gen_new_ie); =20 static struct kunit_case inform_bss_test_cases[] =3D { KUNIT_CASE(test_inform_bss_ssid_only), + KUNIT_CASE(test_get_bss_miss_reason), KUNIT_CASE_PARAM(test_inform_bss_ml_sta, inform_bss_ml_sta_gen_params), {} }; --=20 2.55.0