[PATCH v3 13/22] cfg80211: handle Association Response from S1G STA
From: Thomas Pedersen <hidden>
Date: 2020-09-08 19:04:06
Subsystem:
802.11 (including cfg80211/nl80211), the rest · Maintainers:
Johannes Berg, Linus Torvalds
The sending STA type is implicit based on beacon or probe response content. If sending STA was an S1G STA, adjust the Information Element location accordingly. Signed-off-by: Thomas Pedersen <redacted> --- include/linux/ieee80211.h | 5 +++++ net/wireless/mlme.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index bca4bb443291..690d00505649 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h@@ -1100,6 +1100,11 @@ struct ieee80211_mgmt { /* followed by Supported rates */ u8 variable[0]; } __packed assoc_resp, reassoc_resp; + struct { + __le16 capab_info; + __le16 status_code; + u8 variable[0]; + } __packed s1g_assoc_resp, s1g_reassoc_resp; struct { __le16 capab_info; __le16 listen_interval;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index db7333e20dd7..f8655452b81a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c@@ -30,6 +30,8 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; struct cfg80211_connect_resp_params cr; + const struct cfg80211_bss_ies *ies; + const u8 *s1g; memset(&cr, 0, sizeof(cr)); cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
@@ -42,6 +44,24 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED; + /* Detect whether this was an S1G Association Response and adjust IE + * location accordingly. + */ + rcu_read_lock(); + ies = rcu_dereference(bss->ies); + if (WARN_ON(!ies)) { + rcu_read_unlock(); + return; + } + s1g = cfg80211_find_ie(WLAN_EID_S1G_CAPABILITIES, ies->data, ies->len); + if (s1g) { + cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; + cr.resp_ie_len = + len - offsetof(struct ieee80211_mgmt, + u.s1g_assoc_resp.variable); + } + rcu_read_unlock(); + trace_cfg80211_send_rx_assoc(dev, bss); /*
--
2.20.1