qcacld-3.0: Send update OWE info event

When receiving assoc request from OWE STA, always send update OWE
info event which contains the following information:
- MAC address of STA
- RSN IE in assoc request
- DH IE in assoc request

Change-Id: I7017c5d2730e493db2472ae53d5dfa69553cfe45
CRs-Fixed: 2396925
This commit is contained in:
Min Liu
2019-02-01 15:00:34 +08:00
committed by nshrivas
vanhempi d816803646
commit e34708a91d
10 muutettua tiedostoa jossa 282 lisäystä ja 12 poistoa

Näytä tiedosto

@@ -3640,4 +3640,29 @@ QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event);
*/
void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id);
/**
* hdd_send_update_owe_info_event - Send update OWE info event
* @adapter: Pointer to adapter
* @sta_addr: MAC address of peer STA
* @owe_ie: OWE IE
* @owe_ie_len: Length of OWE IE
*
* Send update OWE info event to hostapd
*
* Return: none
*/
#ifdef CFG80211_EXTERNAL_DH_UPDATE_SUPPORT
void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
uint8_t sta_addr[],
uint8_t *owe_ie,
uint32_t owe_ie_len);
#else
static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
uint8_t sta_addr[],
uint8_t *owe_ie,
uint32_t owe_ie_len)
{
}
#endif
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */

Näytä tiedosto

@@ -20999,6 +20999,27 @@ void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw)
}
#endif
#ifdef CFG80211_EXTERNAL_DH_UPDATE_SUPPORT
void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
uint8_t sta_addr[],
uint8_t *owe_ie,
uint32_t owe_ie_len)
{
struct cfg80211_update_owe_info owe_info;
struct net_device *dev = adapter->dev;
hdd_enter_dev(dev);
qdf_mem_copy(owe_info.bssid, sta_addr, ETH_ALEN);
owe_info.ie = owe_ie;
owe_info.ie_len = owe_ie_len;
cfg80211_update_owe_info_event(dev, &owe_info, GFP_KERNEL);
hdd_exit();
}
#endif
/**
* struct cfg80211_ops - cfg80211_ops
*

Näytä tiedosto

@@ -2440,6 +2440,16 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
hdd_debug("%s", maxAssocExceededEvent);
break;
case eSAP_STA_ASSOC_IND:
if (pSapEvent->sapevt.sapAssocIndication.owe_ie) {
hdd_send_update_owe_info_event(adapter,
pSapEvent->sapevt.sapAssocIndication.staMac.bytes,
pSapEvent->sapevt.sapAssocIndication.owe_ie,
pSapEvent->sapevt.sapAssocIndication.owe_ie_len);
qdf_mem_free(
pSapEvent->sapevt.sapAssocIndication.owe_ie);
pSapEvent->sapevt.sapAssocIndication.owe_ie = NULL;
pSapEvent->sapevt.sapAssocIndication.owe_ie_len = 0;
}
return QDF_STATUS_SUCCESS;
case eSAP_DISCONNECT_ALL_P2P_CLIENT:

Näytä tiedosto

@@ -1120,6 +1120,16 @@ struct assoc_ind {
bool is_sae_authenticated;
};
/**
* struct owe_assoc_ind - owe association indication
* @node : List entry element
* @assoc_ind: pointer to assoc ind
*/
struct owe_assoc_ind {
qdf_list_node_t node;
struct assoc_ind *assoc_ind;
};
/* / Definition for Association confirm */
/* / ---> MAC */
struct assoc_cnf {

Näytä tiedosto

@@ -255,6 +255,8 @@ typedef struct sap_StationAssocIndication_s {
eCsrEncryptionType negotiatedMCEncryptionType;
bool fAuthRequired;
uint8_t ecsa_capable;
uint32_t owe_ie_len;
uint8_t *owe_ie;
} tSap_StationAssocIndication;
typedef struct sap_StationAssocReassocCompleteEvent_s {

Näytä tiedosto

@@ -1342,6 +1342,101 @@ static void sap_handle_acs_scan_event(struct sap_context *sap_context,
}
#endif
#define DH_OUI_TYPE "\x20"
#define DH_OUI_TYPE_SIZE (1)
/**
* sap_fill_owe_ie_in_assoc_ind() - Fill OWE IE in assoc indication
* Function to fill OWE IE in assoc indication
* @assoc_ind: SAP STA association indication
* @sme_assoc_ind: SME association indication
*
* This function is to get OWE IEs (RSN IE, DH IE etc) from assoc request
* and fill them in association indication.
*
* Return: true for success and false for failure
*/
static bool sap_fill_owe_ie_in_assoc_ind(tSap_StationAssocIndication *assoc_ind,
struct assoc_ind *sme_assoc_ind)
{
uint32_t owe_ie_len, rsn_ie_len, dh_ie_len;
const uint8_t *rsn_ie, *dh_ie;
rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN,
assoc_ind->assocReqPtr,
assoc_ind->assocReqLength);
if (!rsn_ie) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "RSN IE is not present");
return false;
}
rsn_ie_len = rsn_ie[1] + 2;
if (rsn_ie_len < DOT11F_IE_RSN_MIN_LEN ||
rsn_ie_len > DOT11F_IE_RSN_MAX_LEN) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid RSN IE len %d",
rsn_ie_len);
return false;
}
dh_ie = wlan_get_ext_ie_ptr_from_ext_id(DH_OUI_TYPE, DH_OUI_TYPE_SIZE,
assoc_ind->assocReqPtr,
(uint16_t)assoc_ind->assocReqLength);
if (!dh_ie) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "DH IE is not present");
return false;
}
dh_ie_len = dh_ie[1] + 2;
if (dh_ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN ||
dh_ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid DH IE len %d",
dh_ie_len);
return false;
}
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
FL("rsn_ie_len = %d, dh_ie_len = %d"), rsn_ie_len, dh_ie_len);
owe_ie_len = rsn_ie_len + dh_ie_len;
assoc_ind->owe_ie = qdf_mem_malloc(owe_ie_len);
if (!assoc_ind->owe_ie)
return false;
qdf_mem_copy(assoc_ind->owe_ie, rsn_ie, rsn_ie_len);
qdf_mem_copy(assoc_ind->owe_ie + rsn_ie_len, dh_ie, dh_ie_len);
assoc_ind->owe_ie_len = owe_ie_len;
return true;
}
/**
* sap_save_owe_pending_assoc_ind() - Save pending assoc indication
* Function to save pending assoc indication in SAP context
* @sap_ctx: SAP context
* @sme_assoc_ind: SME association indication
*
* This function is to save pending assoc indication in linked list
* in SAP context.
*
* Return: true for success and false for failure
*/
static bool sap_save_owe_pending_assoc_ind(struct sap_context *sap_ctx,
struct assoc_ind *sme_assoc_ind)
{
struct owe_assoc_ind *assoc_ind;
QDF_STATUS status;
assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
if (!assoc_ind)
return false;
assoc_ind->assoc_ind = sme_assoc_ind;
status = qdf_list_insert_back(&sap_ctx->owe_pending_assoc_ind_list,
&assoc_ind->node);
if (QDF_STATUS_SUCCESS != status) {
qdf_mem_free(assoc_ind);
return false;
}
return true;
}
/**
* sap_signal_hdd_event() - send event notification
* @sap_ctx: Sap Context
@@ -1414,6 +1509,29 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
csr_roaminfo->u.pConnectedProfile->mcEncryptionType;
assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired;
}
if (csr_roaminfo->owe_pending_assoc_ind) {
if (!sap_fill_owe_ie_in_assoc_ind(assoc_ind,
csr_roaminfo->owe_pending_assoc_ind)) {
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_ERROR,
FL("Failed to fill OWE IE"));
qdf_mem_free(csr_roaminfo->
owe_pending_assoc_ind);
csr_roaminfo->owe_pending_assoc_ind = NULL;
return QDF_STATUS_E_INVAL;
}
if (!sap_save_owe_pending_assoc_ind(sap_ctx,
csr_roaminfo->owe_pending_assoc_ind)) {
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_ERROR,
FL("Failed to save assoc ind"));
qdf_mem_free(csr_roaminfo->
owe_pending_assoc_ind);
csr_roaminfo->owe_pending_assoc_ind = NULL;
return QDF_STATUS_E_INVAL;
}
csr_roaminfo->owe_pending_assoc_ind = NULL;
}
break;
case eSAP_START_BSS_EVENT:
sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;

Näytä tiedosto

@@ -226,6 +226,7 @@ struct sap_context {
uint8_t sap_sta_id;
bool dfs_cac_offload;
bool is_chan_change_inprogress;
qdf_list_t owe_pending_assoc_ind_list;
};
/*----------------------------------------------------------------------------

Näytä tiedosto

@@ -242,6 +242,67 @@ struct sap_context *sap_create_ctx(void)
return sap_ctx;
} /* sap_create_ctx */
static QDF_STATUS wlansap_owe_init(struct sap_context *sap_ctx)
{
qdf_list_create(&sap_ctx->owe_pending_assoc_ind_list, 0);
return QDF_STATUS_SUCCESS;
}
static void wlansap_owe_cleanup(struct sap_context *sap_ctx)
{
struct mac_context *mac;
struct owe_assoc_ind *owe_assoc_ind;
struct assoc_ind *assoc_ind = NULL;
qdf_list_node_t *node = NULL, *next_node = NULL;
QDF_STATUS status;
if (!sap_ctx) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid SAP context");
return;
}
mac = sap_get_mac_context();
if (!mac) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
return;
}
if (QDF_STATUS_SUCCESS !=
qdf_list_peek_front(&sap_ctx->owe_pending_assoc_ind_list,
&node)) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP,
"Failed to find assoc ind list");
return;
}
while (node) {
qdf_list_peek_next(&sap_ctx->owe_pending_assoc_ind_list,
node, &next_node);
owe_assoc_ind = qdf_container_of(node, struct owe_assoc_ind,
node);
status = qdf_list_remove_node(
&sap_ctx->owe_pending_assoc_ind_list,
node);
if (status == QDF_STATUS_SUCCESS) {
assoc_ind = owe_assoc_ind->assoc_ind;
qdf_mem_free(owe_assoc_ind);
/* TODO: disassoc OWE STA */
qdf_mem_free(assoc_ind);
} else {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP,
"Failed to remove assoc ind");
}
node = next_node;
next_node = NULL;
}
}
static void wlansap_owe_deinit(struct sap_context *sap_ctx)
{
qdf_list_destroy(&sap_ctx->owe_pending_assoc_ind_list);
}
QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
enum QDF_OPMODE mode,
uint8_t *addr, uint32_t session_id, bool reinit)
@@ -294,6 +355,15 @@ QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
ucfg_scan_register_requester(mac->psoc, "SAP",
sap_scan_event_callback, sap_ctx);
if (!reinit) {
status = wlansap_owe_init(sap_ctx);
if (QDF_STATUS_SUCCESS != status) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP,
"OWE init failed");
return QDF_STATUS_E_FAILURE;
}
}
return QDF_STATUS_SUCCESS;
}
@@ -311,6 +381,9 @@ QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx)
return QDF_STATUS_E_FAULT;
}
wlansap_owe_cleanup(sap_ctx);
wlansap_owe_deinit(sap_ctx);
mac = sap_get_mac_context();
if (!mac) {
QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");

Näytä tiedosto

@@ -1181,6 +1181,7 @@ struct csr_roam_info {
#ifdef WLAN_FEATURE_SAE
struct sir_sae_info *sae_info;
#endif
struct assoc_ind *owe_pending_assoc_ind;
};
typedef struct sSirSmeAssocIndToUpperLayerCnf {

Näytä tiedosto

@@ -10804,6 +10804,13 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
} else {
roam_info->fAuthRequired = true;
}
if (csr_akm_type == eCSR_AUTH_TYPE_OWE) {
roam_info->owe_pending_assoc_ind = qdf_mem_malloc(
sizeof(*pAssocInd));
if (roam_info->owe_pending_assoc_ind)
qdf_mem_copy(roam_info->owe_pending_assoc_ind,
pAssocInd, sizeof(*pAssocInd));
}
status = csr_roam_call_callback(mac_ctx, sessionId,
roam_info, 0, eCSR_ROAM_INFRA_IND,
eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
@@ -10833,18 +10840,20 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
}
}
/* Send Association completion message to PE */
status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
mac_status_code);
/*
* send a message to CSR itself just to avoid the EAPOL frames going
* OTA before association response
*/
if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) &&
roam_info->statusCode != eSIR_SME_ASSOC_REFUSED) {
roam_info->fReassocReq = pAssocInd->reassocReq;
status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
pAssocInd, status, sessionId);
if (csr_akm_type != eCSR_AUTH_TYPE_OWE) {
/* Send Association completion message to PE */
status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
mac_status_code);
/*
* send a message to CSR itself just to avoid the EAPOL frames
* going OTA before association response
*/
if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) &&
roam_info->statusCode != eSIR_SME_ASSOC_REFUSED) {
roam_info->fReassocReq = pAssocInd->reassocReq;
status = csr_send_assoc_ind_to_upper_layer_cnf_msg(
mac_ctx, pAssocInd, status, sessionId);
}
}
qdf_mem_free(roam_info);