From patchwork Thu Dec 20 23:13:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 10739675 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9CD43746 for ; Thu, 20 Dec 2018 23:14:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B2E428434 for ; Thu, 20 Dec 2018 23:14:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7EBFB2843C; Thu, 20 Dec 2018 23:14:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4180028434 for ; Thu, 20 Dec 2018 23:14:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390294AbeLTXOK (ORCPT ); Thu, 20 Dec 2018 18:14:10 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37486 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390272AbeLTXOK (ORCPT ); Thu, 20 Dec 2018 18:14:10 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 85D2B608CD; Thu, 20 Dec 2018 23:14:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347648; bh=wEjhGCPOcJ6ZiRojHlYc4ErfcYbUjy80ZGlfyDLFNDQ=; h=From:To:Cc:Subject:Date:From; b=JwEKJc5BhVCETTCLj8JG9q5sK3+Vsqr0sDFr9sqAqigd2ITJ2wcGgs6XK2G41Y+bl jOjxUYC0TraHw44Y32gizSkLxAxrJx6q2rRe+momWcVCeUX6QahtG9eM6PR1vKkrXo G+OHP5SBOD1qqj8+cc2fCMUWe6vDQdHyinJr6eEQ= Received: from jouni.codeaurora.org (87-95-219-4.bb.dnainternet.fi [87.95.219.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id D28476074E; Thu, 20 Dec 2018 23:14:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347647; bh=wEjhGCPOcJ6ZiRojHlYc4ErfcYbUjy80ZGlfyDLFNDQ=; h=From:To:Cc:Subject:Date:From; b=NS74GG0PT+v7G3WkjMvXBb+Dv0unWHNQRJQ4zc10zIr2F4Ce6k/9Etpkk4YvzzMF7 LzfAz29pKt8KocQxGlZnMHMpGq/jaa4/y/f9TLioGVYBzOk5dROIEn7o/3jE5yXZQ7 sbJk/LUO5InOpN4AxIclQQ0heu9f6typQ0qh0R/I= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org D28476074E Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Peng Xu , Sara Sharon , Johannes Berg , Jouni Malinen Subject: [PATCH v2 1/5] cfg80211: Parsing of Multiple BSSID information in scanning Date: Fri, 21 Dec 2018 01:13:52 +0200 Message-Id: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Peng Xu This extends cfg80211 BSS table processing to be able to parse Multiple BSSID element from Beacon and Probe Response frames and to update the BSS profiles in internal database for non-transmitted BSSs. Signed-off-by: Peng Xu Signed-off-by: Sara Sharon Signed-off-by: Johannes Berg Signed-off-by: Jouni Malinen --- net/wireless/core.h | 1 + net/wireless/scan.c | 508 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 470 insertions(+), 39 deletions(-) v2: - add missing rcu_read_unlock() calls to address kbuild report diff --git a/net/wireless/core.h b/net/wireless/core.h index c5d6f34..d58c56a 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -152,6 +152,7 @@ extern int cfg80211_rdev_list_generation; struct cfg80211_internal_bss { struct list_head list; struct list_head hidden_list; + struct list_head nontrans_list; struct rb_node rbn; u64 ts_boottime; unsigned long ts; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 5123667..b192388 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -4,7 +4,7 @@ * * Copyright 2008 Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright 2016 Intel Deutschland GmbH + * Copyright 2016-2017 Intel Deutschland GmbH */ #include #include @@ -150,6 +150,7 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, } list_del_init(&bss->list); + list_del_init(&bss->nontrans_list); rb_erase(&bss->rbn, &rdev->bss_tree); rdev->bss_entries--; WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), @@ -159,6 +160,172 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, return true; } +static void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid, + u8 mbssid_index, u8 *new_bssid_addr) +{ + u64 bssid_tmp, new_bssid = 0; + u64 lsb_n; + + bssid_tmp = ether_addr_to_u64(bssid); + + lsb_n = bssid_tmp & ((1 << max_bssid) - 1); + new_bssid = bssid_tmp; + new_bssid &= ~((1 << max_bssid) - 1); + new_bssid |= (lsb_n + mbssid_index) % (1 << max_bssid); + + u64_to_ether_addr(new_bssid, new_bssid_addr); +} + +static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + const u8 *subelement, size_t subie_len, + u8 *new_ie, gfp_t gfp) +{ + u8 *pos, *tmp; + const u8 *tmp_old, *tmp_new; + u8 *sub_copy; + + /* copy subelement as we need to change its content to + * mark an ie after it is processed. + */ + sub_copy = kmalloc(subie_len, gfp); + if (!sub_copy) + return 0; + memcpy(sub_copy, subelement, subie_len); + + pos = &new_ie[0]; + + /* set new ssid */ + tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len); + if (tmp_new) { + memcpy(pos, tmp_new, tmp_new[1] + 2); + pos += (tmp_new[1] + 2); + } + + /* go through IEs in ie (skip SSID) and subelement, + * merge them into new_ie + */ + tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; + + while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { + if (tmp_old[0] == 0) { + tmp_old++; + continue; + } + + tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, subie_len); + if (!tmp) { + /* ie in old ie but not in subelement */ + if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) { + memcpy(pos, tmp_old, tmp_old[1] + 2); + pos += tmp_old[1] + 2; + } + } else { + /* ie in transmitting ie also in subelement, + * copy from subelement and flag the ie in subelement + * as copied (by setting eid field to 0xff). For + * vendor ie, compare OUI + type + subType to + * determine if they are the same ie. + */ + if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { + if (!memcmp(tmp_old + 2, tmp + 2, 5)) { + /* same vendor ie, copy from + * subelement + */ + memcpy(pos, tmp, tmp[1] + 2); + pos += tmp[1] + 2; + tmp[0] = 0xff; + } else { + memcpy(pos, tmp_old, tmp_old[1] + 2); + pos += tmp_old[1] + 2; + } + } else { + /* copy ie from subelement into new ie */ + memcpy(pos, tmp, tmp[1] + 2); + pos += tmp[1] + 2; + tmp[0] = 0xff; + } + } + + if (tmp_old + tmp_old[1] + 2 - ie == ielen) + break; + + tmp_old += tmp_old[1] + 2; + } + + /* go through subelement again to check if there is any ie not + * copied to new ie, skip ssid, capability, bssid-index ie + */ + tmp_new = sub_copy; + while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { + if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || + tmp_new[0] == WLAN_EID_SSID || + tmp_new[0] == WLAN_EID_MULTI_BSSID_IDX || + tmp_new[0] == 0xff)) { + memcpy(pos, tmp_new, tmp_new[1] + 2); + pos += tmp_new[1] + 2; + } + if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) + break; + tmp_new += tmp_new[1] + 2; + } + + kfree(sub_copy); + return pos - new_ie; +} + +static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, + const u8 *ssid, size_t ssid_len) +{ + const struct cfg80211_bss_ies *ies; + const u8 *ssidie; + + if (bssid && !ether_addr_equal(a->bssid, bssid)) + return false; + + if (!ssid) + return true; + + ies = rcu_access_pointer(a->ies); + if (!ies) + return false; + ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); + if (!ssidie) + return false; + if (ssidie[1] != ssid_len) + return false; + return memcmp(ssidie + 2, ssid, ssid_len) == 0; +} + +static int +cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss, + struct cfg80211_internal_bss *nontrans_bss) +{ + const u8 *ssid; + size_t ssid_len; + struct cfg80211_internal_bss *bss = NULL; + + rcu_read_lock(); + ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); + if (!ssid) { + rcu_read_unlock(); + return -EINVAL; + } + ssid_len = ssid[1]; + ssid = ssid + 2; + rcu_read_unlock(); + + /* check if nontrans_bss is in the list */ + list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) { + if (is_bss(&bss->pub, nontrans_bss->pub.bssid, ssid, ssid_len)) + return 0; + } + + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; +} + static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev, unsigned long expire_time) { @@ -525,29 +692,6 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type, } EXPORT_SYMBOL(cfg80211_find_vendor_ie); -static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, - const u8 *ssid, size_t ssid_len) -{ - const struct cfg80211_bss_ies *ies; - const u8 *ssidie; - - if (bssid && !ether_addr_equal(a->bssid, bssid)) - return false; - - if (!ssid) - return true; - - ies = rcu_access_pointer(a->ies); - if (!ies) - return false; - ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); - if (!ssidie) - return false; - if (ssidie[1] != ssid_len) - return false; - return memcmp(ssidie + 2, ssid, ssid_len) == 0; -} - /** * enum bss_compare_mode - BSS compare mode * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find) @@ -1130,17 +1274,19 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, } /* Returned bss is reference counted and must be cleaned up appropriately. */ -struct cfg80211_bss * -cfg80211_inform_bss_data(struct wiphy *wiphy, - struct cfg80211_inform_bss *data, - enum cfg80211_bss_frame_type ftype, - const u8 *bssid, u64 tsf, u16 capability, - u16 beacon_interval, const u8 *ie, size_t ielen, - gfp_t gfp) +static struct cfg80211_bss * +cfg80211_inform_single_bss_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + enum cfg80211_bss_frame_type ftype, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, + struct cfg80211_bss *trans_bss, + gfp_t gfp) { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_bss_ies *ies; struct ieee80211_channel *channel; - struct cfg80211_internal_bss tmp = {}, *res; + struct cfg80211_internal_bss tmp = {}, *res, *trans_internal; int bss_type; bool signal_valid; @@ -1209,19 +1355,252 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, regulatory_hint_found_beacon(wiphy, channel, gfp); } + if (trans_bss) { + /* this is a nontransmitting bss, we need to add it to + * transmitting bss' list if it is not there + */ + trans_internal = container_of(trans_bss, + struct cfg80211_internal_bss, + pub); + if (cfg80211_add_nontrans_list(trans_internal, res)) { + if (__cfg80211_unlink_bss(rdev, res)) + rdev->bss_generation++; + } + } + trace_cfg80211_return_bss(&res->pub); /* cfg80211_bss_update gives us a referenced result */ return &res->pub; } -EXPORT_SYMBOL(cfg80211_inform_bss_data); -/* cfg80211_inform_bss_width_frame helper */ +static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + enum cfg80211_bss_frame_type ftype, + const u8 *bssid, u64 tsf, + u16 beacon_interval, const u8 *ie, + size_t ielen, + struct cfg80211_bss *trans_bss, + gfp_t gfp) +{ + const u8 *pos, *subelement, *mbssid_end_pos; + const u8 *tmp, *mbssid_index_ie; + size_t subie_len, new_ie_len; + u8 new_bssid[ETH_ALEN]; + u8 *new_ie; + u16 capability; + struct cfg80211_bss *bss; + + if (!trans_bss) + return; + if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) + return; + + pos = ie; + + new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp); + if (!new_ie) + return; + + while (pos < ie + ielen + 2) { + tmp = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, pos, + ielen - (pos - ie)); + if (!tmp) + break; + + mbssid_end_pos = tmp + tmp[1] + 2; + /* Skip Element ID, Len, MaxBSSID Indicator */ + if (tmp[1] < 4) + break; + for (subelement = tmp + 3; subelement < mbssid_end_pos - 1; + subelement += 2 + subelement[1]) { + subie_len = subelement[1]; + if (mbssid_end_pos - subelement < 2 + subie_len) + break; + if (subelement[0] != 0 || subelement[1] < 4) { + /* not a valid BSS profile */ + continue; + } + + if (subelement[2] != WLAN_EID_NON_TX_BSSID_CAP || + subelement[3] != 2) { + /* The first element within the Nontransmitted + * BSSID Profile is not the Nontransmitted + * BSSID Capability element. + */ + continue; + } + + /* found a Nontransmitted BSSID Profile */ + mbssid_index_ie = cfg80211_find_ie + (WLAN_EID_MULTI_BSSID_IDX, + subelement + 2, subie_len); + if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || + mbssid_index_ie[2] == 0) { + /* No valid Multiple BSSID-Index element */ + continue; + } + + cfg80211_gen_new_bssid(bssid, tmp[2], + mbssid_index_ie[2], + new_bssid); + memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); + new_ie_len = cfg80211_gen_new_ie(ie, ielen, + subelement + 2, + subie_len, new_ie, + gfp); + if (!new_ie_len) + continue; + + capability = le16_to_cpup((const __le16 *) + &subelement[4]); + bss = cfg80211_inform_single_bss_data(wiphy, data, + ftype, + new_bssid, tsf, + capability, + beacon_interval, + new_ie, + new_ie_len, + trans_bss, gfp); + if (!bss) + break; + cfg80211_put_bss(wiphy, bss); + } + + pos = mbssid_end_pos; + } + + kfree(new_ie); +} + struct cfg80211_bss * -cfg80211_inform_bss_frame_data(struct wiphy *wiphy, - struct cfg80211_inform_bss *data, - struct ieee80211_mgmt *mgmt, size_t len, - gfp_t gfp) +cfg80211_inform_bss_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + enum cfg80211_bss_frame_type ftype, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, + gfp_t gfp) +{ + struct cfg80211_bss *res; + + res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf, + capability, beacon_interval, ie, + ielen, NULL, gfp); + cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf, + beacon_interval, ie, ielen, res, gfp); + return res; +} +EXPORT_SYMBOL(cfg80211_inform_bss_data); +static void +cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + struct ieee80211_mgmt *mgmt, size_t len, + struct cfg80211_bss *trans_bss, + gfp_t gfp) +{ + enum cfg80211_bss_frame_type ftype; + const u8 *ie = mgmt->u.probe_resp.variable; + size_t ielen = len - offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + + ftype = ieee80211_is_beacon(mgmt->frame_control) ? + CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP; + + cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid, + le64_to_cpu(mgmt->u.probe_resp.timestamp), + le16_to_cpu(mgmt->u.probe_resp.beacon_int), + ie, ielen, trans_bss, gfp); +} + +static void +cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + struct cfg80211_internal_bss *nontrans_bss, + struct ieee80211_mgmt *mgmt, size_t len, + gfp_t gfp) +{ + u8 *ie, *new_ie, *pos; + const u8 *nontrans_ssid, *trans_ssid, *mbssid; + size_t ielen = len - offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; + u8 cpy_len; + + ie = mgmt->u.probe_resp.variable; + + new_ie_len = ielen; + trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + if (!trans_ssid) + return; + new_ie_len -= trans_ssid[1]; + mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen); + if (!mbssid) + return; + new_ie_len -= mbssid[1]; + rcu_read_lock(); + nontrans_ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); + if (!nontrans_ssid) { + rcu_read_unlock(); + return; + } + new_ie_len += nontrans_ssid[1]; + rcu_read_unlock(); + + /* generate new ie for nontrans BSS + * 1. replace SSID with nontrans BSS' SSID + * 2. skip MBSSID IE + */ + new_ie = kzalloc(new_ie_len, gfp); + if (!new_ie) + return; + new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, gfp); + if (!new_ies) { + kfree(new_ie); + return; + } + + pos = new_ie; + + /* copy the nontransmitted SSID */ + cpy_len = nontrans_ssid[1] + 2; + memcpy(pos, nontrans_ssid, cpy_len); + pos += cpy_len; + /* copy the IEs between SSID and MBSSID */ + cpy_len = trans_ssid[1] + 2; + memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len))); + pos += (mbssid - (trans_ssid + cpy_len)); + /* copy the IEs after MBSSID */ + cpy_len = mbssid[1] + 2; + memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len))); + + /* update ie */ + new_ies->len = new_ie_len; + new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); + new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); + memcpy(new_ies->data, new_ie, new_ie_len); + if (ieee80211_is_probe_resp(mgmt->frame_control)) { + old = rcu_access_pointer(nontrans_bss->pub.proberesp_ies); + rcu_assign_pointer(nontrans_bss->pub.proberesp_ies, new_ies); + rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } else { + old = rcu_access_pointer(nontrans_bss->pub.beacon_ies); + rcu_assign_pointer(nontrans_bss->pub.beacon_ies, new_ies); + rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } +} + +/* cfg80211_inform_bss_width_frame helper */ +static struct cfg80211_bss * +cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + struct ieee80211_mgmt *mgmt, size_t len, + struct cfg80211_bss *trans_bss, + gfp_t gfp) { struct cfg80211_internal_bss tmp = {}, *res; struct cfg80211_bss_ies *ies; @@ -1300,6 +1679,50 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, /* cfg80211_bss_update gives us a referenced result */ return &res->pub; } + +struct cfg80211_bss * +cfg80211_inform_bss_frame_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + struct ieee80211_mgmt *mgmt, size_t len, + gfp_t gfp) +{ + struct cfg80211_bss *res; + struct cfg80211_internal_bss *trans_bss, *tmp_bss; + const u8 *ie = mgmt->u.probe_resp.variable; + const struct cfg80211_bss_ies *ies1, *ies2; + size_t ielen = len - offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + + res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, + len, NULL, gfp); + if (!res || !cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) + return res; + + /* process each non-transmitting bss */ + cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, res, gfp); + + /* check if the res has other nontransmitting bss which is not + * in MBSSID IE + */ + ies1 = rcu_access_pointer(res->ies); + trans_bss = container_of(res, struct cfg80211_internal_bss, pub); + if (!trans_bss) + return res; + + /* go through nontrans_list, if the timestamp of the BSS is + * earlier than the timestamp of the transmitting BSS then + * update it + */ + list_for_each_entry(tmp_bss, &trans_bss->nontrans_list, + nontrans_list) { + ies2 = rcu_access_pointer(tmp_bss->pub.ies); + if (ies2->tsf < ies1->tsf) + cfg80211_update_notlisted_nontrans(wiphy, tmp_bss, + mgmt, len, gfp); + } + + return res; +} EXPORT_SYMBOL(cfg80211_inform_bss_frame_data); void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) @@ -1337,7 +1760,7 @@ EXPORT_SYMBOL(cfg80211_put_bss); void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct cfg80211_internal_bss *bss; + struct cfg80211_internal_bss *bss, *nontrans_bss, *tmp; if (WARN_ON(!pub)) return; @@ -1346,6 +1769,13 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) spin_lock_bh(&rdev->bss_lock); if (!list_empty(&bss->list)) { + list_for_each_entry_safe(nontrans_bss, tmp, + &bss->nontrans_list, + nontrans_list) { + if (__cfg80211_unlink_bss(rdev, nontrans_bss)) + rdev->bss_generation++; + } + if (__cfg80211_unlink_bss(rdev, bss)) rdev->bss_generation++; } From patchwork Thu Dec 20 23:13:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 10739677 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 68CC5746 for ; Thu, 20 Dec 2018 23:14:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5960928434 for ; Thu, 20 Dec 2018 23:14:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D5B12843C; Thu, 20 Dec 2018 23:14:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0D2528434 for ; Thu, 20 Dec 2018 23:14:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390295AbeLTXOM (ORCPT ); Thu, 20 Dec 2018 18:14:12 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37550 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390271AbeLTXOL (ORCPT ); Thu, 20 Dec 2018 18:14:11 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 47762608FC; Thu, 20 Dec 2018 23:14:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347650; bh=AjBC5nhJsUoGQyMgFqwUX9ah5MWyc1+V4DaV+YIBh+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fy9ITICZqwFfT4IWrLWMcHHrKESWNUPA3QhIyOV9krP4N73/l5P+1wjJbKlME6In9 8zya7TTdTEuxKV0SuYBUx1wgaxxOOx0ywXz8hrePk3mDWO3ON7PocgdLK969Jbl7AJ fej2A4/Au0FhK6FbRN8IetfqiGSeQ8WbdnXj3Mlk= Received: from jouni.codeaurora.org (87-95-219-4.bb.dnainternet.fi [87.95.219.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 194C460867; Thu, 20 Dec 2018 23:14:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347649; bh=AjBC5nhJsUoGQyMgFqwUX9ah5MWyc1+V4DaV+YIBh+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TmQL7ZFO45Z5H2xvEH6UNErKFgfxVjJJM+4YryUJLJkLVD5jYplI1qub5qbL8ZqN4 0ReGqYGq3WtKulAwGihCIWycJT6qlX1qdPsNWYPBmW4erUz36QH7ywGvzGPiYjI723 fZ59voVOGcnITBIBpRwzrFFigDx4NLxlN915NB6E= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 194C460867 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Sara Sharon , Johannes Berg , Jouni Malinen Subject: [PATCH v2 2/5] cfg80211: Properly track transmitting and non-transmitting BSS Date: Fri, 21 Dec 2018 01:13:53 +0200 Message-Id: <1545347636-5076-2-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> References: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sara Sharon When holding data of the non-transmitting BSS, we need to keep the transmitting BSS data on. Otherwise it will be released, and release the non-transmitting BSS with it. Signed-off-by: Sara Sharon Signed-off-by: Johannes Berg Signed-off-by: Jouni Malinen --- net/wireless/core.h | 12 ++++++++++++ net/wireless/scan.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) v2: - avoid recursive calls within inline functions to address kbuild warnings diff --git a/net/wireless/core.h b/net/wireless/core.h index d58c56a..eb8e90b 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -153,6 +153,7 @@ struct cfg80211_internal_bss { struct list_head list; struct list_head hidden_list; struct list_head nontrans_list; + struct cfg80211_bss *transmitted_bss; struct rb_node rbn; u64 ts_boottime; unsigned long ts; @@ -183,12 +184,23 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) { atomic_inc(&bss->hold); + if (bss->transmitted_bss) { + bss = container_of(bss->transmitted_bss, + struct cfg80211_internal_bss, pub); + atomic_inc(&bss->hold); + } } static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) { int r = atomic_dec_return(&bss->hold); WARN_ON(r < 0); + if (bss->transmitted_bss) { + bss = container_of(bss->transmitted_bss, + struct cfg80211_internal_bss, pub); + r = atomic_dec_return(&bss->hold); + WARN_ON(r < 0); + } } diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b192388..aa102c8 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -109,6 +109,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, pub); bss->refcount++; } + if (bss->transmitted_bss) { + bss = container_of(bss->transmitted_bss, + struct cfg80211_internal_bss, + pub); + bss->refcount++; + } } static inline void bss_ref_put(struct cfg80211_registered_device *rdev, @@ -125,6 +131,18 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev, if (hbss->refcount == 0) bss_free(hbss); } + + if (bss->transmitted_bss) { + struct cfg80211_internal_bss *tbss; + + tbss = container_of(bss->transmitted_bss, + struct cfg80211_internal_bss, + pub); + tbss->refcount--; + if (tbss->refcount == 0) + bss_free(tbss); + } + bss->refcount--; if (bss->refcount == 0) bss_free(bss); @@ -1030,6 +1048,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, static struct cfg80211_internal_bss * cfg80211_bss_update(struct cfg80211_registered_device *rdev, struct cfg80211_internal_bss *tmp, + struct cfg80211_bss *trans_bss, bool signal_valid) { struct cfg80211_internal_bss *found = NULL; @@ -1186,6 +1205,17 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, goto drop; } + /* This must be before the call to bss_ref_get */ + if (trans_bss) { + struct cfg80211_internal_bss *pbss = + container_of(trans_bss, + struct cfg80211_internal_bss, + pub); + + new->transmitted_bss = trans_bss; + bss_ref_get(rdev, pbss); + } + list_add_tail(&new->list, &rdev->bss_list); rdev->bss_entries++; rb_insert_bss(rdev, new); @@ -1341,7 +1371,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, signal_valid = abs(data->chan->center_freq - channel->center_freq) <= wiphy->max_adj_channel_rssi_comp; - res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); + res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss, + signal_valid); if (!res) return NULL; @@ -1661,7 +1692,8 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, signal_valid = abs(data->chan->center_freq - channel->center_freq) <= wiphy->max_adj_channel_rssi_comp; - res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid); + res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, trans_bss, + signal_valid); if (!res) return NULL; From patchwork Thu Dec 20 23:13:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 10739679 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4540713BF for ; Thu, 20 Dec 2018 23:14:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3441A28434 for ; Thu, 20 Dec 2018 23:14:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 28AB32843C; Thu, 20 Dec 2018 23:14:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADACE28434 for ; Thu, 20 Dec 2018 23:14:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390298AbeLTXOO (ORCPT ); Thu, 20 Dec 2018 18:14:14 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37616 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390296AbeLTXON (ORCPT ); Thu, 20 Dec 2018 18:14:13 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id EC933608D4; Thu, 20 Dec 2018 23:14:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347651; bh=T0Im4VcrfrGBFFOYAthweJtImYZpT9nQ7748RPfIiow=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a3JEIcDHOOtjHtHi2v0SeOkWdqOeLfns1hLAhyaIbE0Zh3WIBc3LfjaTBH09q9kTc DZvAvpC+mSZkvrF9acCrFaCvO7P8h/hdZOpfuPtJLXP66dubgsaSNny2OICR72d9T+ at+JI0TIoUxpuIumEFimTLSjFFNn4VFhVBeU+XIY= Received: from jouni.codeaurora.org (87-95-219-4.bb.dnainternet.fi [87.95.219.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id DF14D60886; Thu, 20 Dec 2018 23:14:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347651; bh=T0Im4VcrfrGBFFOYAthweJtImYZpT9nQ7748RPfIiow=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a3JEIcDHOOtjHtHi2v0SeOkWdqOeLfns1hLAhyaIbE0Zh3WIBc3LfjaTBH09q9kTc DZvAvpC+mSZkvrF9acCrFaCvO7P8h/hdZOpfuPtJLXP66dubgsaSNny2OICR72d9T+ at+JI0TIoUxpuIumEFimTLSjFFNn4VFhVBeU+XIY= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org DF14D60886 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Sara Sharon , Johannes Berg , Jouni Malinen Subject: [PATCH v2 3/5] cfg80211: Move Multiple BSS info to struct cfg80211_bss to be visible Date: Fri, 21 Dec 2018 01:13:54 +0200 Message-Id: <1545347636-5076-3-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> References: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sara Sharon Previously the transmitted BSS and the non-trasmitted BSS list were defined in struct cfg80211_internal_bss. Move them to struct cfg80211_bss since mac80211 needs this info. Signed-off-by: Sara Sharon Signed-off-by: Johannes Berg Signed-off-by: Jouni Malinen --- include/net/cfg80211.h | 2 ++ net/wireless/core.h | 10 +++---- net/wireless/scan.c | 79 +++++++++++++++++++++++++------------------------- 3 files changed, 45 insertions(+), 46 deletions(-) v2: - rebased on top of changes in previous patches diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e0c41eb..17cfc33 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2021,6 +2021,8 @@ struct cfg80211_bss { const struct cfg80211_bss_ies __rcu *proberesp_ies; struct cfg80211_bss *hidden_beacon_bss; + struct cfg80211_bss *transmitted_bss; + struct list_head nontrans_list; s32 signal; diff --git a/net/wireless/core.h b/net/wireless/core.h index eb8e90b..236b676 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -152,8 +152,6 @@ extern int cfg80211_rdev_list_generation; struct cfg80211_internal_bss { struct list_head list; struct list_head hidden_list; - struct list_head nontrans_list; - struct cfg80211_bss *transmitted_bss; struct rb_node rbn; u64 ts_boottime; unsigned long ts; @@ -184,8 +182,8 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) { atomic_inc(&bss->hold); - if (bss->transmitted_bss) { - bss = container_of(bss->transmitted_bss, + if (bss->pub.transmitted_bss) { + bss = container_of(bss->pub.transmitted_bss, struct cfg80211_internal_bss, pub); atomic_inc(&bss->hold); } @@ -195,8 +193,8 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) { int r = atomic_dec_return(&bss->hold); WARN_ON(r < 0); - if (bss->transmitted_bss) { - bss = container_of(bss->transmitted_bss, + if (bss->pub.transmitted_bss) { + bss = container_of(bss->pub.transmitted_bss, struct cfg80211_internal_bss, pub); r = atomic_dec_return(&bss->hold); WARN_ON(r < 0); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index aa102c8..4c8b12c 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -109,8 +109,8 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, pub); bss->refcount++; } - if (bss->transmitted_bss) { - bss = container_of(bss->transmitted_bss, + if (bss->pub.transmitted_bss) { + bss = container_of(bss->pub.transmitted_bss, struct cfg80211_internal_bss, pub); bss->refcount++; @@ -132,10 +132,10 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev, bss_free(hbss); } - if (bss->transmitted_bss) { + if (bss->pub.transmitted_bss) { struct cfg80211_internal_bss *tbss; - tbss = container_of(bss->transmitted_bss, + tbss = container_of(bss->pub.transmitted_bss, struct cfg80211_internal_bss, pub); tbss->refcount--; @@ -168,7 +168,7 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, } list_del_init(&bss->list); - list_del_init(&bss->nontrans_list); + list_del_init(&bss->pub.nontrans_list); rb_erase(&bss->rbn, &rdev->bss_tree); rdev->bss_entries--; WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), @@ -316,15 +316,15 @@ static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, } static int -cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss, - struct cfg80211_internal_bss *nontrans_bss) +cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss, + struct cfg80211_bss *nontrans_bss) { const u8 *ssid; size_t ssid_len; - struct cfg80211_internal_bss *bss = NULL; + struct cfg80211_bss *bss = NULL; rcu_read_lock(); - ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); + ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID); if (!ssid) { rcu_read_unlock(); return -EINVAL; @@ -335,7 +335,7 @@ cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss, /* check if nontrans_bss is in the list */ list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) { - if (is_bss(&bss->pub, nontrans_bss->pub.bssid, ssid, ssid_len)) + if (is_bss(bss, nontrans_bss->bssid, ssid, ssid_len)) return 0; } @@ -1172,6 +1172,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, memcpy(new, tmp, sizeof(*new)); new->refcount = 1; INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); if (rcu_access_pointer(tmp->pub.proberesp_ies)) { hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); @@ -1212,7 +1213,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, struct cfg80211_internal_bss, pub); - new->transmitted_bss = trans_bss; + new->pub.transmitted_bss = trans_bss; bss_ref_get(rdev, pbss); } @@ -1316,7 +1317,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_bss_ies *ies; struct ieee80211_channel *channel; - struct cfg80211_internal_bss tmp = {}, *res, *trans_internal; + struct cfg80211_internal_bss tmp = {}, *res; int bss_type; bool signal_valid; @@ -1390,10 +1391,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, /* this is a nontransmitting bss, we need to add it to * transmitting bss' list if it is not there */ - trans_internal = container_of(trans_bss, - struct cfg80211_internal_bss, - pub); - if (cfg80211_add_nontrans_list(trans_internal, res)) { + if (cfg80211_add_nontrans_list(trans_bss, &res->pub)) { if (__cfg80211_unlink_bss(rdev, res)) rdev->bss_generation++; } @@ -1545,7 +1543,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, static void cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, - struct cfg80211_internal_bss *nontrans_bss, + struct cfg80211_bss *nontrans_bss, struct ieee80211_mgmt *mgmt, size_t len, gfp_t gfp) { @@ -1570,7 +1568,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, return; new_ie_len -= mbssid[1]; rcu_read_lock(); - nontrans_ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); + nontrans_ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID); if (!nontrans_ssid) { rcu_read_unlock(); return; @@ -1611,15 +1609,15 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); memcpy(new_ies->data, new_ie, new_ie_len); if (ieee80211_is_probe_resp(mgmt->frame_control)) { - old = rcu_access_pointer(nontrans_bss->pub.proberesp_ies); - rcu_assign_pointer(nontrans_bss->pub.proberesp_ies, new_ies); - rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); + old = rcu_access_pointer(nontrans_bss->proberesp_ies); + rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies); + rcu_assign_pointer(nontrans_bss->ies, new_ies); if (old) kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); } else { - old = rcu_access_pointer(nontrans_bss->pub.beacon_ies); - rcu_assign_pointer(nontrans_bss->pub.beacon_ies, new_ies); - rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); + old = rcu_access_pointer(nontrans_bss->beacon_ies); + rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); + rcu_assign_pointer(nontrans_bss->ies, new_ies); if (old) kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); } @@ -1718,8 +1716,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, gfp_t gfp) { - struct cfg80211_bss *res; - struct cfg80211_internal_bss *trans_bss, *tmp_bss; + struct cfg80211_bss *res, *tmp_bss; const u8 *ie = mgmt->u.probe_resp.variable; const struct cfg80211_bss_ies *ies1, *ies2; size_t ielen = len - offsetof(struct ieee80211_mgmt, @@ -1737,17 +1734,14 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, * in MBSSID IE */ ies1 = rcu_access_pointer(res->ies); - trans_bss = container_of(res, struct cfg80211_internal_bss, pub); - if (!trans_bss) - return res; /* go through nontrans_list, if the timestamp of the BSS is * earlier than the timestamp of the transmitting BSS then * update it */ - list_for_each_entry(tmp_bss, &trans_bss->nontrans_list, + list_for_each_entry(tmp_bss, &res->nontrans_list, nontrans_list) { - ies2 = rcu_access_pointer(tmp_bss->pub.ies); + ies2 = rcu_access_pointer(tmp_bss->ies); if (ies2->tsf < ies1->tsf) cfg80211_update_notlisted_nontrans(wiphy, tmp_bss, mgmt, len, gfp); @@ -1792,7 +1786,8 @@ EXPORT_SYMBOL(cfg80211_put_bss); void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct cfg80211_internal_bss *bss, *nontrans_bss, *tmp; + struct cfg80211_internal_bss *bss, *tmp1; + struct cfg80211_bss *nontrans_bss, *tmp; if (WARN_ON(!pub)) return; @@ -1800,17 +1795,21 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) bss = container_of(pub, struct cfg80211_internal_bss, pub); spin_lock_bh(&rdev->bss_lock); - if (!list_empty(&bss->list)) { - list_for_each_entry_safe(nontrans_bss, tmp, - &bss->nontrans_list, - nontrans_list) { - if (__cfg80211_unlink_bss(rdev, nontrans_bss)) - rdev->bss_generation++; - } + if (list_empty(&bss->list)) + goto out; - if (__cfg80211_unlink_bss(rdev, bss)) + list_for_each_entry_safe(nontrans_bss, tmp, + &pub->nontrans_list, + nontrans_list) { + tmp1 = container_of(nontrans_bss, + struct cfg80211_internal_bss, pub); + if (__cfg80211_unlink_bss(rdev, tmp1)) rdev->bss_generation++; } + + if (__cfg80211_unlink_bss(rdev, bss)) + rdev->bss_generation++; +out: spin_unlock_bh(&rdev->bss_lock); } EXPORT_SYMBOL(cfg80211_unlink_bss); From patchwork Thu Dec 20 23:13:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 10739683 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C7FC3746 for ; Thu, 20 Dec 2018 23:14:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B79F828434 for ; Thu, 20 Dec 2018 23:14:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ABD422843C; Thu, 20 Dec 2018 23:14:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C35CB28434 for ; Thu, 20 Dec 2018 23:14:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390302AbeLTXOP (ORCPT ); Thu, 20 Dec 2018 18:14:15 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37690 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390299AbeLTXOO (ORCPT ); Thu, 20 Dec 2018 18:14:14 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id DC7A760915; Thu, 20 Dec 2018 23:14:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347653; bh=1cOWtfmuHDBbrZaGUSiQfjbYU1tF2g/OWIqoyygSu3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ToJQAE9GQSQnivrTCCGcY4G9kk/gtQx8QQLQDlj8TpsZqH/wb5jhFgSPrOxI47yJm 1MG7FRdyyFK8bQal1b5d8W+YJlc3skuyFC6s9kWT7Y3UQ1yAJ4m7GhoUae3QjOyl6+ slUMQNUOkcwFNldIuuW39o5d/csuXVs8l2txTKkw= Received: from jouni.codeaurora.org (87-95-219-4.bb.dnainternet.fi [87.95.219.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id B386D60907; Thu, 20 Dec 2018 23:14:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347653; bh=1cOWtfmuHDBbrZaGUSiQfjbYU1tF2g/OWIqoyygSu3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ToJQAE9GQSQnivrTCCGcY4G9kk/gtQx8QQLQDlj8TpsZqH/wb5jhFgSPrOxI47yJm 1MG7FRdyyFK8bQal1b5d8W+YJlc3skuyFC6s9kWT7Y3UQ1yAJ4m7GhoUae3QjOyl6+ slUMQNUOkcwFNldIuuW39o5d/csuXVs8l2txTKkw= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B386D60907 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Sara Sharon , Johannes Berg , Jouni Malinen Subject: [PATCH v2 4/5] mac80211: Declare support for Multi-BSSID if driver supports it Date: Fri, 21 Dec 2018 01:13:55 +0200 Message-Id: <1545347636-5076-4-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> References: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sara Sharon Define bits and flags for indicating support of Multi-BSSID feature and indicate support for this if the driver supports it. Signed-off-by: Sara Sharon Signed-off-by: Johannes Berg Signed-off-by: Jouni Malinen --- include/linux/ieee80211.h | 5 +++++ include/net/mac80211.h | 3 +++ net/mac80211/debugfs.c | 1 + net/mac80211/main.c | 4 ++++ 4 files changed, 13 insertions(+) v2: - remove an extra empty line to silence checkpatch.pl --strict diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 407d6fd..bd23436 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2656,6 +2656,11 @@ enum ieee80211_tdls_actioncode { */ #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) +/* Multiple BSSID capability is set in the 6th bit of the 3rd byte of the + * @WLAN_EID_EXT_CAPABILITY information element + */ +#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(6) + /* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */ #define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4) #define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index aecbdf3..659c94f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2181,6 +2181,8 @@ struct ieee80211_txq { * MMPDUs on station interfaces. This of course requires the driver to use * TXQs to start with. * + * @IEEE80211_HW_SUPPORTS_MULTI_BSSID: Hardware supports multi BSSID + * * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { @@ -2229,6 +2231,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_BUFF_MMPDU_TXQ, IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW, IEEE80211_HW_STA_MMPDU_TXQ, + IEEE80211_HW_SUPPORTS_MULTI_BSSID, /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 3fe541e..28a7e60 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -218,6 +218,7 @@ static const char *hw_flag_names[] = { FLAG(BUFF_MMPDU_TXQ), FLAG(SUPPORTS_VHT_EXT_NSS_BW), FLAG(STA_MMPDU_TXQ), + FLAG(SUPPORTS_MULTI_BSSID), #undef FLAG }; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ada8e16..2e3136b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1104,6 +1104,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; + /* mac80211 supports multi BSSID, if the driver supports it */ + if (ieee80211_hw_check(&local->hw, SUPPORTS_MULTI_BSSID)) + local->ext_capa[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT; + local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; result = wiphy_register(local->hw.wiphy); From patchwork Thu Dec 20 23:13:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jouni Malinen X-Patchwork-Id: 10739681 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CA69B13BF for ; Thu, 20 Dec 2018 23:14:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BBFE028434 for ; Thu, 20 Dec 2018 23:14:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B04502843C; Thu, 20 Dec 2018 23:14:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7257F28434 for ; Thu, 20 Dec 2018 23:14:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390304AbeLTXOP (ORCPT ); Thu, 20 Dec 2018 18:14:15 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:37734 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390296AbeLTXOP (ORCPT ); Thu, 20 Dec 2018 18:14:15 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id B492C6090B; Thu, 20 Dec 2018 23:14:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347654; bh=vjT7O+matsxPZs8gGlXl57DqETh8hnTH5ga45TPgQ4c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U+j+0IzszP3B3LHJQUvT7LCJZQGXm+AxJP02VsQv3SFkQ5b1a9bRhUQW7GXheE4mK YC9zIneZyuZOUwffUblMywX1Jfwq6Ak82cEHxsW3WwbROEXfcLO7qWN6UTNDOdICyA bUeAsZ93+iSAJalsdY18llMGDdhyI5dvryn4M7lg= Received: from jouni.codeaurora.org (87-95-219-4.bb.dnainternet.fi [87.95.219.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jouni@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 8392A60867; Thu, 20 Dec 2018 23:14:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1545347654; bh=vjT7O+matsxPZs8gGlXl57DqETh8hnTH5ga45TPgQ4c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U+j+0IzszP3B3LHJQUvT7LCJZQGXm+AxJP02VsQv3SFkQ5b1a9bRhUQW7GXheE4mK YC9zIneZyuZOUwffUblMywX1Jfwq6Ak82cEHxsW3WwbROEXfcLO7qWN6UTNDOdICyA bUeAsZ93+iSAJalsdY18llMGDdhyI5dvryn4M7lg= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 8392A60867 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jouni@codeaurora.org From: Jouni Malinen To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Jouni Malinen Subject: [PATCH v2 5/5] mac80211_hwsim: Declare support for Multi-BSSID Date: Fri, 21 Dec 2018 01:13:56 +0200 Message-Id: <1545347636-5076-5-git-send-email-jouni@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> References: <1545347636-5076-1-git-send-email-jouni@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This can be used to test cfg80211 support for Multi-BSSID scan result parsing. Signed-off-by: Jouni Malinen --- drivers/net/wireless/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+) v2: - no changes diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e4db8e2..74096d4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2794,6 +2794,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ieee80211_hw_set(hw, TDLS_WIDER_BW); if (rctbl) ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); + ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |