From nobody Sat Jul 25 00:10:55 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 21A67386571 for ; Tue, 21 Jul 2026 18:12:06 +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=1784657528; cv=none; b=ZEVEFeKbmyZz9sjpraKrtxRcuZPzC1A/IwlU9ALnsBgT0hsxr6MCx7vvRfZ6U/F36csPvuJlN88C+lEzpz0wzwWQ9XcBinJwDNoybMpKMfphjp5EnvlcsO9uh3SKhRl1KqDapKJyg6ibbStZp0z/hLiHtaFoqI6v6CzcmIoCiII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784657528; c=relaxed/simple; bh=81oFB8MOTqw4lWLzFAy4xrARRFsjTVGVFlQ7iOCKMJg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=orRlC15DsGt0J7QEEFAxKrbFz0WHn4/BLL62oyjFOeLjp95alu0wnmnqLKYhDcFeeC4B2CS0cbYdRmhgrcdXmiitMc+bKdjjJa8Qx3JwUPCPkWsvRVVvuJ+cszm1XfwSCEAvOzlBvNUXT2tXY87CmvU43CE6qO8oxTJ0FB4gY4Y= 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=ICJ8DY8y; 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="ICJ8DY8y" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4954d383e64so24809395e9.1 for ; Tue, 21 Jul 2026 11:12:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784657525; x=1785262325; 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=AL61nYl2zovT6RprywQrFjf39hMsz8k4qeU+GbUkx68=; b=ICJ8DY8yGLCXfpxEvpOpfN6FUgMhbtdrCsPm0IxMwn1x5Y7sQOmXwr+BeD/I81hahA 4ePO0mLN9aZjUMSaXffCXcpiasVB1w9ggTod3dVPC4Zruv6M6cehDY2/sGtPy62Ck//U 0vhsKYDnHI438dJ8RVLejxZOgEFVu/4bDbXVVdyXewSx9GgA7veUgljx5pz80aAW30yt cvlVsezYYjNjn5irjzk/7EWeBoc+RPn8XqBWv2b5/Gp99GJdQURQkaC+o3PwVj4hjbKC pcxLo4cFmKMdnfrkLduZ08i9Wu5G+Az9EAjJYfhrg7HfZuM56FCTiRIUMv7YvWgrq+t6 +uHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784657525; x=1785262325; 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=AL61nYl2zovT6RprywQrFjf39hMsz8k4qeU+GbUkx68=; b=r1/yLpKmwFF3vrU+y3nmP0J4SU6Q9PYaoKrAy6cRU9fL6V2p/zdUBnxFQwACJ+nvX+ S99HDMBD/RrS1x65pyJKFmmIw6WeKA/6bR6NvAWQ5f/hdyVbiZMcoE3QJsLzMHzDAy3L 1jB8nIeE/7hkXzBdALZ9B5JIgZp0WoMA12Q6AjLJHpgEjU3w4iHj1NLpCgwQKNI3A7Lw 9G2dNKvaVbWThiAIQlBVtFIPzNPhYzaaG3kN6PCARP5XXfANqt1I3Jsb7koStbTSwQke Z32udyHm0B6kgVBStH3VRjSwx4uVAEErmnfgE4XUOL7a6rz1OGe1STKXt4Za+gQ8e+hd jyRA== X-Forwarded-Encrypted: i=1; AHgh+RqUtayciALnScAyWF2AAS6kGaUQALcHH0BwN/Dq/7bfrseLGqtYPiHTQpX/QSvM20pCVDT3exMSdggKIqU=@vger.kernel.org X-Gm-Message-State: AOJu0YyX+OnfQprPUWrRUHONpJMtncXAY712xXot7KBG8dt0WUrvdDkX Y9tJ5Zvm1YCIT0pfMOJLffezETHKCdkXBu6HD64eq619syS5dnSzsUiZfcjMyrPb6bA= X-Gm-Gg: AfdE7cnvyGCJSQ6DJa6mI6s3FVjmXfpmOWzSU/BusLAz0ZJ2+zpy4fiPR+X6KXcXs2t lGOSqL7UAM+9TjT2PzdKUF22Ur42I2vatULzwiOnDK8B93oQn+6oyYRFKgKbcsGp97DNFHNQYIk xSi1OrVXOLcDP6Nrt3Rn0UnF468ZkdR4hI71Wo27C6Snj8bDzOQKOxFYYvjnZU7yk93+JptwoiY +2fBaSQpNdh6dQHkuRSG+5nyusKdLGgcO550/VlVZDbZPsLg45NBqqtYxZqnvWJp3np3o72a+T1 dBhFK14H1GuzTwY8+12XfVLyhPT85+KAldueyf5oNajDYWFTo6c1IdMKOU7l7pbcxonB7Ijvht9 7exfe3MhYm3iDbnkf6tPmg4B1NdOk0fW6KqRnSrXTLhgpcQ8dOkqfpKRGL/1L7C2mUgX5eFD0VQ XMHW69UP5nCfmDURWQN4iK5IS5uhNhY7q538sP X-Received: by 2002:a05:600c:e549:20b0:493:b4cf:d37f with SMTP id 5b1f17b1804b1-4954a3f0e58mr155945995e9.16.1784657525048; Tue, 21 Jul 2026 11:12:05 -0700 (PDT) Received: from localhost ([102.128.173.0]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a64d4b6sm8780595e9.15.2026.07.21.11.12.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 11:12:04 -0700 (PDT) From: Louis Kotze To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, loukot@gmail.com Subject: [PATCH v2 1/2] wifi: cfg80211: say why the auth/assoc BSS lookup failed Date: Tue, 21 Jul 2026 20:11:57 +0200 Message-ID: <20260721181158.3004022-2-loukot@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260721181158.3004022-1-loukot@gmail.com> References: <2629d83dd460f3d9a60566f3fad975db13b045c3.camel@sipsolutions.net> <20260721181158.3004022-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 rescanning would help. 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 only for being expired or only for not being usable for the requested use, and set a distinct message for each case. 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. When matching entries were rejected for both reasons, the use_for message wins: it is only set for a current (non-expired) entry, so suggesting a rescan would be misleading. 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. Signed-off-by: Louis Kotze --- v2: reworked per Johannes' feedback: the reason is captured inside __cfg80211_get_bss() during the single bss_lock walk (no separate re-walk helper, no race), reported via a new optional extack parameter. The authentication path is now covered too, and the patch grew a KUnit companion (patch 2). Retitled nl80211 -> cfg80211. include/net/cfg80211.h | 7 +++++-- net/wireless/nl80211.c | 28 +++++++++++++++++----------- net/wireless/scan.c | 35 +++++++++++++++++++++++++++-------- net/wireless/tests/scan.c | 2 +- 4 files changed, 50 insertions(+), 22 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 242071ad10d6..7fb6786a5e8e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12889,9 +12889,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 @@ -13036,6 +13038,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) @@ -13045,8 +13048,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]) { + NL_SET_ERR_MSG(info->extack, "BSSID or frequency missing"); return ERR_PTR(-EINVAL); + } =20 bssid =3D nla_data(attrs[NL80211_ATTR_MAC]); =20 @@ -13055,8 +13060,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) { + NL_SET_ERR_MSG(info->extack, "invalid or disabled channel"); return ERR_PTR(-EINVAL); + } =20 if (assoc_link_id >=3D 0) use_for =3D NL80211_BSS_USE_FOR_MLD_LINK; @@ -13067,7 +13074,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 @@ -13106,13 +13113,12 @@ 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"); + NL_SET_BAD_ATTR(info->extack, link); return err; } =20 @@ -13328,8 +13334,8 @@ 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, - -1, -1); + 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); ap_addr =3D req.bss->bssid; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 05b7dc6b766c..f26e8436dbc1 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,39 @@ 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; + /* 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 (unusable) + NL_SET_ERR_MSG(extack, + "BSS cannot be used for the requested operation"); + else if (expired) + NL_SET_ERR_MSG(extack, + "BSS entry is expired, scan again"); + 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 Sat Jul 25 00:10:55 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (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 67EE63B6352 for ; Tue, 21 Jul 2026 18:12:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784657532; cv=none; b=kQJwGhVTSnS+D1cWw9E1Wguzb4P7V6RVM53pHXUtYWy0CwmWA1+jsccvSUlWVBnse5X/4/PbAzz9mFjf3QvdoAc0mhdiDddtDoMzhtA3AR3GFLYA6hoLi3lxeYIyLHOogm0SkRBgy9b59bYs7Wli1+KWW3s+DOiBVu9tgGT/afk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784657532; c=relaxed/simple; bh=VyqPry+Jyk41bywcDDOHwgp5gnyvxXMNoSPQu15XKTY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RYh9HWJEs1pvWoC73HWawS+LElQklmLwCqOhq31/+bXlRx+xAm+IY2CygyXiXYkw0GoQgPzDIGCvDFS6kf90SpGfZcbPR0DhYzALSebTv3R34R8yjPtaWRoS5Iey2DXSJQBfY69vAvCJU3rTAaUNijfJD/DO8goFsrY4kiPlNac= 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=Alfm1z8f; arc=none smtp.client-ip=209.85.128.41 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="Alfm1z8f" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-4954afac04bso40094755e9.0 for ; Tue, 21 Jul 2026 11:12:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784657529; x=1785262329; 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=dG/aaTVPvOTLfx14gUE4MGd7dHHYsJQKyX614HPG0BE=; b=Alfm1z8f2u3cuWUvppni7iyvCoqFYXj+qYediXokVDF4iv2NWn2PjN7t6Bo//tzQaQ YgumjOTkLMnfcokv2AGOhqI3NgTQueDKsVJrLeSZfwCqfqx51jLu5s8xpL8cFJw4WxkO Bkj3wVnCNCctiILTGlkl6dQUN7kM4G1L0+zmp3SpQKlqeZl3WQJaLJA2AL8YEQZC04fN JehXxABmxDiv78lmz3nRdSbzBEXCXomj+eH+Xlum46r1oQSN/fcq23GEPlPaHylpIV03 /ihMs7SSfxwQTdDVv6zVziX+IlE1RdHxAS5/MNDCiWpIOqfDNaXpZfjZA123cO6SvOPK jYhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784657529; x=1785262329; 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=dG/aaTVPvOTLfx14gUE4MGd7dHHYsJQKyX614HPG0BE=; b=M9W766CUVX6n/8qHDtrNHl8W0ZQ27XaWODKWT4hi+qLx4qF9DQmctcCAG8LObityHY BeriwU+XCd7l3cj3dwXV4BqkZVjaVKQsBtOX/zbsLh8jnU5QX55JKFEOUlVmm28k0sw3 YR2mM5DvpiYuO7jmGPc5uQgRsJF1S2v6jLjfdhvy4wshNuqBHJeYT4ulWWSnvTFx/QxG WA1IZj/P77ZaxxzhcQ8Nm31qV2F7tbQILMlEtjSTuNIssBRBpIvMQt9A3hoO0Q14N7gb Q/2STzQOZV8NxcaUsTrdgrj3FunGg1Kco8Et+C3D5nQHvDnz3aFgY50TU9vzyS6kRq/W cqGA== X-Forwarded-Encrypted: i=1; AHgh+Rpouioi0MdiOseW2MV1iS9KMt2WfS9mRPUzVe+QKET5IW0e+EvNccMdp3zsLHI5Wy89k3x8dQrxKzSviKI=@vger.kernel.org X-Gm-Message-State: AOJu0YzHDc0Fn/K2688DjzA6rkaLOhFLYXYbDANjNoYG1cLYtndeJKQ9 iIJRlnGGGZnLRI/7vVxNGOsfn6bFaGKRLxCn8FwQ8FXOyh9eWVNKBthe X-Gm-Gg: AfdE7cl9iO3cWHyXQJt9qr0IxrMo3QTTAcrpOyB0BXyqDpbZOXs0IsT3kdOIy1bd9/S RUy83eM1ly/zgkhrFx6/7pqBte6D+fyTgl3Yr9o34guVbgvIJ/mouaWR6G8LmT2Ou/2Rtps8itc leqlaLpvnyMw9xWnEDChV06MUj2RImboygvbT0WxrSKuDO0W6GC8SJNV1kvZ18H5dSuCeUXt6dC DOecuToPUkAVgsM1g8Lib07L/ArEalHnpzDN/SjWlrPRoHUm4Wa16SK5I70xM01nNCTKlNavFrp bpxjbR6NBAjsY6G1EVb/yONh3G/FW7tNyYCgCNd70izByK8TaFEvyf2HPrpvVypMnP+1dwQAn4r h4EKC8TtVielQc0gpEDUGescd6uIwoS3SG01FIi+QeEMsemF9x4H/MoHOshR1gli40XVmrH7Edq /R7Vbr83wPIqY3zqFN/XXXG7DDCQ== X-Received: by 2002:a05:600c:4584:b0:493:f5bf:4da4 with SMTP id 5b1f17b1804b1-4954a50e970mr222206645e9.28.1784657528424; Tue, 21 Jul 2026 11:12:08 -0700 (PDT) Received: from localhost ([102.128.173.0]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a6354a3sm15632125e9.10.2026.07.21.11.12.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 11:12:08 -0700 (PDT) From: Louis Kotze To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, loukot@gmail.com Subject: [PATCH v2 2/2] wifi: cfg80211: tests: check BSS lookup failure reasons Date: Tue, 21 Jul 2026 20:11:58 +0200 Message-ID: <20260721181158.3004022-3-loukot@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260721181158.3004022-1-loukot@gmail.com> References: <2629d83dd460f3d9a60566f3fad975db13b045c3.camel@sipsolutions.net> <20260721181158.3004022-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), the precedence for an entry that is both expired and unusable, and the cross-entry precedence when one matching entry is expired and another is current but unusable. Signed-off-by: Louis Kotze --- net/wireless/tests/scan.c | 120 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/net/wireless/tests/scan.c b/net/wireless/tests/scan.c index 2fc717317ac3..e62b01f8cbe5 100644 --- a/net/wireless/tests/scan.c +++ b/net/wireless/tests/scan.c @@ -402,6 +402,125 @@ 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 is expired, scan again"); + + /* 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 is expired, scan again"); + 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 both an expired entry and a fresh-but-unusable entry + * matching, the unusable one determines the message: a current + * entry exists, so suggesting a rescan would be misleading. + */ + 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 cannot be used for the requested operation"); + + 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 +974,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