qtnfmac: enable WPA3 OWE support
In the case of OWE, STA should be able to pass DH IEs from AP assoc responses to wpa_s for processing. For this purpose DH IEs are received from firmware in BSS_JOIN events and passed to wireless core and then to wpa_s as additional optional rsp_ies parameter for cfg80211_connect_result. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
38ef8d9016
commit
524d6323af
@ -150,6 +150,13 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif,
|
|||||||
struct cfg80211_chan_def chandef;
|
struct cfg80211_chan_def chandef;
|
||||||
struct cfg80211_bss *bss = NULL;
|
struct cfg80211_bss *bss = NULL;
|
||||||
u8 *ie = NULL;
|
u8 *ie = NULL;
|
||||||
|
size_t payload_len;
|
||||||
|
u16 tlv_type;
|
||||||
|
u16 tlv_value_len;
|
||||||
|
size_t tlv_full_len;
|
||||||
|
const struct qlink_tlv_hdr *tlv;
|
||||||
|
const u8 *rsp_ies = NULL;
|
||||||
|
size_t rsp_ies_len = 0;
|
||||||
|
|
||||||
if (unlikely(len < sizeof(*join_info))) {
|
if (unlikely(len < sizeof(*join_info))) {
|
||||||
pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
|
pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
|
||||||
@ -167,67 +174,118 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif,
|
|||||||
pr_debug("VIF%u.%u: BSSID:%pM status:%u\n",
|
pr_debug("VIF%u.%u: BSSID:%pM status:%u\n",
|
||||||
vif->mac->macid, vif->vifid, join_info->bssid, status);
|
vif->mac->macid, vif->vifid, join_info->bssid, status);
|
||||||
|
|
||||||
if (status == WLAN_STATUS_SUCCESS) {
|
if (status != WLAN_STATUS_SUCCESS)
|
||||||
qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef);
|
goto done;
|
||||||
if (!cfg80211_chandef_valid(&chandef)) {
|
|
||||||
pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
|
qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef);
|
||||||
|
if (!cfg80211_chandef_valid(&chandef)) {
|
||||||
|
pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
|
||||||
|
vif->mac->macid, vif->vifid,
|
||||||
|
chandef.chan->center_freq,
|
||||||
|
chandef.center_freq1,
|
||||||
|
chandef.center_freq2,
|
||||||
|
chandef.width);
|
||||||
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid,
|
||||||
|
NULL, 0, IEEE80211_BSS_TYPE_ESS,
|
||||||
|
IEEE80211_PRIVACY_ANY);
|
||||||
|
if (!bss) {
|
||||||
|
pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n",
|
||||||
|
vif->mac->macid, vif->vifid,
|
||||||
|
join_info->bssid, chandef.chan->hw_value);
|
||||||
|
|
||||||
|
if (!vif->wdev.ssid_len) {
|
||||||
|
pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n",
|
||||||
vif->mac->macid, vif->vifid,
|
vif->mac->macid, vif->vifid,
|
||||||
chandef.chan->center_freq,
|
join_info->bssid);
|
||||||
chandef.center_freq1,
|
|
||||||
chandef.center_freq2,
|
|
||||||
chandef.width);
|
|
||||||
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid,
|
ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL);
|
||||||
NULL, 0, IEEE80211_BSS_TYPE_ESS,
|
if (!ie) {
|
||||||
IEEE80211_PRIVACY_ANY);
|
pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n",
|
||||||
if (!bss) {
|
|
||||||
pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n",
|
|
||||||
vif->mac->macid, vif->vifid,
|
vif->mac->macid, vif->vifid,
|
||||||
join_info->bssid, chandef.chan->hw_value);
|
join_info->bssid);
|
||||||
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (!vif->wdev.ssid_len) {
|
ie[0] = WLAN_EID_SSID;
|
||||||
pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n",
|
ie[1] = vif->wdev.ssid_len;
|
||||||
vif->mac->macid, vif->vifid,
|
memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len);
|
||||||
join_info->bssid);
|
|
||||||
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL);
|
bss = cfg80211_inform_bss(wiphy, chandef.chan,
|
||||||
if (!ie) {
|
CFG80211_BSS_FTYPE_UNKNOWN,
|
||||||
pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n",
|
join_info->bssid, 0,
|
||||||
vif->mac->macid, vif->vifid,
|
WLAN_CAPABILITY_ESS, 100,
|
||||||
join_info->bssid);
|
ie, 2 + vif->wdev.ssid_len,
|
||||||
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
0, GFP_KERNEL);
|
||||||
goto done;
|
if (!bss) {
|
||||||
}
|
pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n",
|
||||||
|
vif->mac->macid, vif->vifid,
|
||||||
ie[0] = WLAN_EID_SSID;
|
join_info->bssid);
|
||||||
ie[1] = vif->wdev.ssid_len;
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len);
|
goto done;
|
||||||
|
|
||||||
bss = cfg80211_inform_bss(wiphy, chandef.chan,
|
|
||||||
CFG80211_BSS_FTYPE_UNKNOWN,
|
|
||||||
join_info->bssid, 0,
|
|
||||||
WLAN_CAPABILITY_ESS, 100,
|
|
||||||
ie, 2 + vif->wdev.ssid_len,
|
|
||||||
0, GFP_KERNEL);
|
|
||||||
if (!bss) {
|
|
||||||
pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n",
|
|
||||||
vif->mac->macid, vif->vifid,
|
|
||||||
join_info->bssid);
|
|
||||||
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload_len = len - sizeof(*join_info);
|
||||||
|
tlv = (struct qlink_tlv_hdr *)join_info->ies;
|
||||||
|
|
||||||
|
while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
|
||||||
|
tlv_type = le16_to_cpu(tlv->type);
|
||||||
|
tlv_value_len = le16_to_cpu(tlv->len);
|
||||||
|
tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
|
||||||
|
|
||||||
|
if (payload_len < tlv_full_len) {
|
||||||
|
pr_warn("invalid %u TLV\n", tlv_type);
|
||||||
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tlv_type == QTN_TLV_ID_IE_SET) {
|
||||||
|
const struct qlink_tlv_ie_set *ie_set;
|
||||||
|
unsigned int ie_len;
|
||||||
|
|
||||||
|
if (payload_len < sizeof(*ie_set)) {
|
||||||
|
pr_warn("invalid IE_SET TLV\n");
|
||||||
|
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ie_set = (const struct qlink_tlv_ie_set *)tlv;
|
||||||
|
ie_len = tlv_value_len -
|
||||||
|
(sizeof(*ie_set) - sizeof(ie_set->hdr));
|
||||||
|
|
||||||
|
switch (ie_set->type) {
|
||||||
|
case QLINK_IE_SET_ASSOC_RESP:
|
||||||
|
if (ie_len) {
|
||||||
|
rsp_ies = ie_set->ie_data;
|
||||||
|
rsp_ies_len = ie_len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_warn("unexpected IE type: %u\n",
|
||||||
|
ie_set->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload_len -= tlv_full_len;
|
||||||
|
tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload_len)
|
||||||
|
pr_warn("VIF%u.%u: unexpected remaining payload: %zu\n",
|
||||||
|
vif->mac->macid, vif->vifid, payload_len);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, NULL,
|
cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, rsp_ies,
|
||||||
0, status, GFP_KERNEL);
|
rsp_ies_len, status, GFP_KERNEL);
|
||||||
if (bss) {
|
if (bss) {
|
||||||
if (!ether_addr_equal(vif->bssid, join_info->bssid))
|
if (!ether_addr_equal(vif->bssid, join_info->bssid))
|
||||||
ether_addr_copy(vif->bssid, join_info->bssid);
|
ether_addr_copy(vif->bssid, join_info->bssid);
|
||||||
|
@ -984,6 +984,7 @@ struct qlink_event_bss_join {
|
|||||||
struct qlink_chandef chan;
|
struct qlink_chandef chan;
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
__le16 status;
|
__le16 status;
|
||||||
|
u8 ies[0];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user