Commit 5cd212cb authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: cfg80211: extend cfg80211_rx_assoc_resp() for MLO



Extend the cfg80211_rx_assoc_resp() to cover multiple
BSSes, the AP MLD address and local link addresses
for MLO.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent cd47c0f5
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -6886,14 +6886,21 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
 *	as the AC bitmap in the QoS info field
 * @req_ies: information elements from the (Re)Association Request frame
 * @req_ies_len: length of req_ies data
 * @ap_mld_addr: AP MLD address (in case of MLO)
 * @links: per-link information indexed by link ID, use links[0] for
 *	non-MLO connections
 */
struct cfg80211_rx_assoc_resp {
	struct cfg80211_bss *bss;
	const u8 *buf;
	size_t len;
	const u8 *req_ies;
	size_t req_ies_len;
	int uapsd_queues;
	const u8 *ap_mld_addr;
	struct {
		const u8 *addr;
		struct cfg80211_bss *bss;
	} links[IEEE80211_MLD_MAX_NUM_LINKS];
};

/**
+1 −1
Original line number Diff line number Diff line
@@ -3995,7 +3995,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
		info.success = 1;
	}

	resp.bss = cbss;
	resp.links[0].bss = cbss;
	resp.buf = (u8 *)mgmt;
	resp.len = len;
	resp.req_ies = ifmgd->assoc_req_ies;
+42 −22
Original line number Diff line number Diff line
@@ -28,28 +28,41 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf;
	struct cfg80211_connect_resp_params cr;
	const u8 *resp_ie = mgmt->u.assoc_resp.variable;
	size_t resp_ie_len = data->len - offsetof(struct ieee80211_mgmt,
						  u.assoc_resp.variable);

	if (data->bss->channel->band == NL80211_BAND_S1GHZ) {
		resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
		resp_ie_len = data->len - offsetof(struct ieee80211_mgmt,
	struct cfg80211_connect_resp_params cr = {
		.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED,
		.req_ie = data->req_ies,
		.req_ie_len = data->req_ies_len,
		.resp_ie = mgmt->u.assoc_resp.variable,
		.resp_ie_len = data->len -
			       offsetof(struct ieee80211_mgmt,
					u.assoc_resp.variable),
		.status = le16_to_cpu(mgmt->u.assoc_resp.status_code),
		.ap_mld_addr = data->ap_mld_addr,
	};
	unsigned int link_id;

	for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
		cr.links[link_id].bss = data->links[link_id].bss;
		if (!cr.links[link_id].bss)
			continue;
		cr.links[link_id].bssid = data->links[link_id].bss->bssid;
		cr.links[link_id].addr = data->links[link_id].addr;
		/* need to have local link addresses for MLO connections */
		WARN_ON(cr.ap_mld_addr && !cr.links[link_id].addr);

		if (cr.links[link_id].bss->channel->band == NL80211_BAND_S1GHZ) {
			WARN_ON(link_id);
			cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
			cr.resp_ie_len = data->len -
					 offsetof(struct ieee80211_mgmt,
						  u.s1g_assoc_resp.variable);
		}

	memset(&cr, 0, sizeof(cr));
	cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
	cr.links[0].bssid = mgmt->bssid;
	cr.links[0].bss = data->bss;
	cr.req_ie = data->req_ies;
	cr.req_ie_len = data->req_ies_len;
	cr.resp_ie = resp_ie;
	cr.resp_ie_len = resp_ie_len;
	cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
		if (cr.ap_mld_addr)
			cr.valid_links |= BIT(link_id);
	}

	trace_cfg80211_send_rx_assoc(dev, data->bss);
	trace_cfg80211_send_rx_assoc(dev, data);

	/*
	 * This is a bit of a hack, we don't notify userspace of
@@ -58,8 +71,15 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
	 * frame instead of reassoc.
	 */
	if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
		cfg80211_unhold_bss(bss_from_pub(data->bss));
		cfg80211_put_bss(wiphy, data->bss);
		for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
			struct cfg80211_bss *bss = data->links[link_id].bss;

			if (!bss)
				continue;

			cfg80211_unhold_bss(bss_from_pub(bss));
			cfg80211_put_bss(wiphy, bss);
		}
		return;
	}

+8 −8
Original line number Diff line number Diff line
@@ -2887,20 +2887,20 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth,
);

TRACE_EVENT(cfg80211_send_rx_assoc,
	TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss),
	TP_ARGS(netdev, bss),
	TP_PROTO(struct net_device *netdev,
		 struct cfg80211_rx_assoc_resp *data),
	TP_ARGS(netdev, data),
	TP_STRUCT__entry(
		NETDEV_ENTRY
		MAC_ENTRY(bssid)
		CHAN_ENTRY
		MAC_ENTRY(ap_addr)
	),
	TP_fast_assign(
		NETDEV_ASSIGN;
		MAC_ASSIGN(bssid, bss->bssid);
		CHAN_ASSIGN(bss->channel);
		MAC_ASSIGN(ap_addr,
			   data->ap_mld_addr ?: data->links[0].bss->bssid);
	),
	TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT,
		  NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
	TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
		  NETDEV_PR_ARG, MAC_PR_ARG(ap_addr))
);

DECLARE_EVENT_CLASS(netdev_frame_event,