cfg80211: handle Association Response from S1G STA
authorThomas Pedersen <thomas@adapt-ip.com>
Tue, 22 Sep 2020 02:28:09 +0000 (19:28 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 28 Sep 2020 11:54:03 +0000 (13:54 +0200)
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 <thomas@adapt-ip.com>
Link: https://lore.kernel.org/r/20200922022818.15855-9-thomas@adapt-ip.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/linux/ieee80211.h
net/wireless/mlme.c

index 1ce0b37441b9d4a6b4834752c5faaba1689959cd..d0fda842411887263642335fac120c5b5841d642 100644 (file)
@@ -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;
index db7333e20dd7172a98b7942c1ba715d0818d0b6f..0ac820780437d54baa4da315eb7e5397cf65b112 100644 (file)
@@ -30,6 +30,15 @@ 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 u8 *resp_ie = mgmt->u.assoc_resp.variable;
+       size_t resp_ie_len = len - offsetof(struct ieee80211_mgmt,
+                                           u.assoc_resp.variable);
+
+       if (bss->channel->band == NL80211_BAND_S1GHZ) {
+               resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
+               resp_ie_len = 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);
@@ -37,9 +46,8 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
        cr.bss = bss;
        cr.req_ie = req_ies;
        cr.req_ie_len = req_ies_len;
-       cr.resp_ie = mgmt->u.assoc_resp.variable;
-       cr.resp_ie_len =
-               len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+       cr.resp_ie = resp_ie;
+       cr.resp_ie_len = resp_ie_len;
        cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
 
        trace_cfg80211_send_rx_assoc(dev, bss);