diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5dc84dd3aca0..c2029667a0ce 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -123,6 +123,7 @@ #include "wlan_reg_ucfg_api.h" #include "wlan_hdd_rx_monitor.h" #include "sme_power_save_api.h" +#include "enet.h" #ifdef CNSS_GENL #include @@ -4848,6 +4849,64 @@ static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params { } #endif +/** + * hdd_update_hlp_info() - Update HLP packet received in FILS assoc rsp + * @dev: net device + * @roam_fils_params: Fils join rsp params + * + * This API is used to send the received HLP packet in Assoc rsp(FILS AKM) + * to the network layer. + * + * Return: None + */ +static void hdd_update_hlp_info(struct net_device *dev, + struct fils_join_rsp_params *roam_fils_params) +{ + struct sk_buff *skb; + uint16_t skb_len; + struct llc_snap_hdr_t *llc_hdr; + QDF_STATUS status; + uint8_t *hlp_data = roam_fils_params->hlp_data; + uint16_t hlp_data_len = roam_fils_params->hlp_data_len; + struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev); + + /* Calculate skb length */ + skb_len = (2 * ETH_ALEN) + hlp_data_len; + skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false); + if (skb == NULL) { + hdd_err("HLP packet nbuf alloc fails"); + return; + } + + qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes, + QDF_MAC_ADDR_SIZE); + + llc_hdr = (struct llc_snap_hdr_t *) hlp_data; + if (IS_SNAP(llc_hdr)) { + hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE; + hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE; + } + + qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len); + + /* + * This HLP packet is formed from HLP info encapsulated + * in assoc response frame which is AEAD encrypted. + * Hence, this checksum validation can be set unnecessary. + * i.e. network layer need not worry about checksum. + */ + skb->ip_summed = CHECKSUM_UNNECESSARY; + + status = hdd_rx_packet_cbk(padapter, skb); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Sending HLP packet fails"); + return; + } + hdd_debug("send HLP packet to netif successfully"); +} + /** * hdd_connect_done() - Wrapper API to call cfg80211_connect_done * @dev: network device @@ -4904,6 +4963,9 @@ static void hdd_connect_done(struct net_device *dev, const u8 *bssid, cfg80211_connect_done(dev, &fils_params, gfp); + if (roam_fils_params && roam_fils_params->hlp_data_len) + hdd_update_hlp_info(dev, roam_fils_params); + /* Clear all the FILS key info */ if (roam_fils_params && roam_fils_params->fils_pmk) qdf_mem_free(roam_fils_params->fils_pmk); @@ -4921,6 +4983,11 @@ static inline void hdd_connect_done(struct net_device *dev, const u8 *bssid, timeout_reason, struct fils_join_rsp_params *roam_fils_params) { } + +static inline void hdd_update_hlp_info(struct net_device *dev, + struct fils_join_rsp_params *roam_fils_params) + +{ } #endif #endif diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index f70febb1bef9..e2e20b339c27 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -343,6 +343,10 @@ struct fils_join_rsp_params { uint8_t tk_len; uint8_t gtk_len; uint8_t gtk[MAX_GTK_LEN]; + struct qdf_mac_addr dst_mac; + struct qdf_mac_addr src_mac; + uint16_t hlp_data_len; + uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN]; }; #endif diff --git a/core/mac/src/pe/include/lim_fils_defs.h b/core/mac/src/pe/include/lim_fils_defs.h index 81aa23ce5913..44fde3920d5e 100644 --- a/core/mac/src/pe/include/lim_fils_defs.h +++ b/core/mac/src/pe/include/lim_fils_defs.h @@ -217,6 +217,10 @@ struct fils_auth_rsp_info { * @igtk_len: igtk length * @igtk: igtk data pointer * @ipn: pointer to ipn data + * @dst_mac: HLP destination mac address + * @src_mac: HLP source mac address + * @hlp_data_len: HLP data length + * @hlp_data: pointer to HLP data */ struct pe_fils_session { bool is_fils_connection; @@ -260,4 +264,8 @@ struct pe_fils_session { uint8_t igtk_len; uint8_t igtk[MAX_IGTK_LEN]; uint8_t ipn[IPN_LEN]; + struct qdf_mac_addr dst_mac; + struct qdf_mac_addr src_mac; + uint16_t hlp_data_len; + uint8_t *hlp_data; }; diff --git a/core/mac/src/pe/lim/lim_process_fils.c b/core/mac/src/pe/lim/lim_process_fils.c index f3c3c9c4df7b..e429277690bf 100644 --- a/core/mac/src/pe/lim/lim_process_fils.c +++ b/core/mac/src/pe/lim/lim_process_fils.c @@ -1294,6 +1294,12 @@ void populate_fils_connect_params(tpAniSirGlobal mac_ctx, fils_join_rsp->gtk_len = fils_info->gtk_len; qdf_mem_copy(fils_join_rsp->gtk, fils_info->gtk, fils_info->gtk_len); + cds_copy_hlp_info(&fils_info->dst_mac, &fils_info->src_mac, + fils_info->hlp_data_len, fils_info->hlp_data, + &fils_join_rsp->dst_mac, &fils_join_rsp->src_mac, + &fils_join_rsp->hlp_data_len, + fils_join_rsp->hlp_data); + pe_debug("FILS connect params copied lim"); pe_delete_fils_info(session); } diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index 09d88ed14092..ffc1ad735410 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -307,6 +307,8 @@ void pe_delete_fils_info(tpPESession session) qdf_mem_free(fils_info->auth_info.keyname); if (fils_info->auth_info.domain_name) qdf_mem_free(fils_info->auth_info.domain_name); + if (fils_info->hlp_data) + qdf_mem_free(fils_info->hlp_data); qdf_mem_free(fils_info); session->fils_info = NULL; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index a46d51f4303f..49dec43d7aba 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -7066,6 +7066,11 @@ static QDF_STATUS populate_fils_params_join_rsp(tpAniSirGlobal mac_ctx, qdf_mem_copy(roam_fils_info->gtk, fils_join_rsp->gtk, roam_fils_info->gtk_len); + cds_copy_hlp_info(&fils_join_rsp->dst_mac, &fils_join_rsp->src_mac, + fils_join_rsp->hlp_data_len, fils_join_rsp->hlp_data, + &roam_fils_info->dst_mac, &roam_fils_info->src_mac, + &roam_fils_info->hlp_data_len, + roam_fils_info->hlp_data); sme_debug("FILS connect params copied to CSR!"); free_fils_join_rsp: