提交 46b9d180 编写于 作者: J Johannes Berg

cfg80211: send extended capabilities IE in connect

If the connect request from userspace didn't include an extended
capabilities IE, create one using the driver capabilities. This
fixes VHT associations, since those need to set the operating mode
notification capability.
Reviewed-by: NGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 29464ccc
......@@ -42,7 +42,7 @@ struct cfg80211_conn {
CFG80211_CONN_CONNECTED,
} state;
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
u8 *ie;
const u8 *ie;
size_t ie_len;
bool auto_auth, prev_bssid_valid;
};
......@@ -423,6 +423,62 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
schedule_work(&rdev->conn_work);
}
static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
const u8 *ies, size_t ies_len,
const u8 **out_ies, size_t *out_ies_len)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
u8 *buf;
size_t offs;
if (!rdev->wiphy.extended_capabilities_len ||
(ies && cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, ies, ies_len))) {
*out_ies = kmemdup(ies, ies_len, GFP_KERNEL);
if (!*out_ies)
return -ENOMEM;
*out_ies_len = ies_len;
return 0;
}
buf = kmalloc(ies_len + rdev->wiphy.extended_capabilities_len + 2,
GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (ies_len) {
static const u8 before_extcapa[] = {
/* not listing IEs expected to be created by driver */
WLAN_EID_RSN,
WLAN_EID_QOS_CAPA,
WLAN_EID_RRM_ENABLED_CAPABILITIES,
WLAN_EID_MOBILITY_DOMAIN,
WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
WLAN_EID_BSS_COEX_2040,
};
offs = ieee80211_ie_split(ies, ies_len, before_extcapa,
ARRAY_SIZE(before_extcapa), 0);
memcpy(buf, ies, offs);
/* leave a whole for extended capabilities IE */
memcpy(buf + offs + rdev->wiphy.extended_capabilities_len + 2,
ies + offs, ies_len - offs);
} else {
offs = 0;
}
/* place extended capabilities IE (with only driver capabilities) */
buf[offs] = WLAN_EID_EXT_CAPABILITY;
buf[offs + 1] = rdev->wiphy.extended_capabilities_len;
memcpy(buf + offs + 2,
rdev->wiphy.extended_capabilities,
rdev->wiphy.extended_capabilities_len);
*out_ies = buf;
*out_ies_len = ies_len + rdev->wiphy.extended_capabilities_len + 2;
return 0;
}
static int cfg80211_sme_connect(struct wireless_dev *wdev,
struct cfg80211_connect_params *connect,
const u8 *prev_bssid)
......@@ -453,16 +509,14 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
}
if (connect->ie) {
wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
GFP_KERNEL);
wdev->conn->params.ie = wdev->conn->ie;
if (!wdev->conn->ie) {
kfree(wdev->conn);
wdev->conn = NULL;
return -ENOMEM;
}
if (cfg80211_sme_get_conn_ies(wdev, connect->ie, connect->ie_len,
&wdev->conn->ie,
&wdev->conn->params.ie_len)) {
kfree(wdev->conn);
wdev->conn = NULL;
return -ENOMEM;
}
wdev->conn->params.ie = wdev->conn->ie;
if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
wdev->conn->auto_auth = true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册