Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 749bc0d2 authored by Srinivas Dasari's avatar Srinivas Dasari
Browse files

qcacld-3.0: Consider PMF capa of peer also for rmf frame processing

Cache the PMF capability of peer in peer_mlme_priv_obj while
adding bss for both station and AP modes. Process the mgmt frames
received from the peer as rmf frames only if the peer is of PMF
capable.
Remove the check where WEP bit is validated and modified based on
PMF capability of the peer. This is already taken care while
setting WEP bit in lim.

Change-Id: I0c93bb25db6a866e4c1793c9ba4c60773c0f019d
CRs-Fixed: 2520249
parent 3700576c
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -35,9 +35,11 @@
/**
 * struct peer_mlme_priv_obj - peer MLME component object
 * @ucast_key_cipher: unicast crypto type.
 * @is_pmf_enabled: True if PMF is enabled
 */
struct peer_mlme_priv_obj {
	uint32_t ucast_key_cipher;
	bool is_pmf_enabled;
};

/**
@@ -199,4 +201,23 @@ mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer,
QDF_STATUS
mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer,
					void *arg);

/**
 * mlme_set_peer_pmf_status() - set pmf status of peer
 * @peer: PEER object
 * @is_pmf_enabled: Carries if PMF is enabled or not
 *
 * is_pmf_enabled will be set to true if PMF is enabled by peer
 *
 * Return: void
 */
void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer,
			      bool is_pmf_enabled);
/**
 * mlme_get_peer_pmf_status() - get if peer is of pmf capable
 * @peer: PEER object
 *
 * Return: Value of is_pmf_enabled; True if PMF is enabled by peer
 */
bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer);
#endif
+28 −0
Original line number Diff line number Diff line
@@ -300,3 +300,31 @@ mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer,

	return status;
}

void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer,
			      bool is_pmf_enabled)
{
	struct peer_mlme_priv_obj *peer_priv;

	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
							  WLAN_UMAC_COMP_MLME);
	if (!peer_priv) {
		mlme_err(" peer mlme component object is NULL");
		return;
	}
	peer_priv->is_pmf_enabled = is_pmf_enabled;
}

bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer)
{
	struct peer_mlme_priv_obj *peer_priv;

	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
							  WLAN_UMAC_COMP_MLME);
	if (!peer_priv) {
		mlme_err("peer mlme component object is NULL");
		return false;
	}

	return peer_priv->is_pmf_enabled;
}
+0 −5
Original line number Diff line number Diff line
@@ -2562,11 +2562,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
			frmLen = newFrmLen;
			pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(tx_frame));
		}
	} else if (iface && !iface->rmfEnabled) {
		if (pFc->wep && (frmType == TXRX_FRM_802_11_MGMT)) {
			wma_err("PMF is disabled, but WEP is set");
			pFc->wep = 0;
		}
	}
#endif /* WLAN_FEATURE_11W */
	mHdr = (tpSirMacMgmtHdr)qdf_nbuf_data(tx_frame);
+41 −0
Original line number Diff line number Diff line
@@ -3955,10 +3955,46 @@ static void wma_set_mgmt_frame_protection(tp_wma_handle wma)
		WMA_LOGD("%s: QOS MFP/PMF set", __func__);
	}
}

/**
 * wma_set_peer_pmf_status() - Get the peer and update PMF capability of it
 * @wma: wma handle
 * @peer_mac: peer mac addr
 * @is_pmf_enabled: Carries the status whether PMF is enabled or not
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS
wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac,
			bool is_pmf_enabled)
{
	struct wlan_objmgr_peer *peer;

	peer = wlan_objmgr_get_peer(wma->psoc,
				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
				    peer_mac, WLAN_LEGACY_WMA_ID);
	if (!peer) {
		WMA_LOGE("Peer of peer_mac %pM not found",
			 peer_mac);
		return QDF_STATUS_E_INVAL;
	}
	mlme_set_peer_pmf_status(peer, is_pmf_enabled);
	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
	WMA_LOGD("set is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac);

	return QDF_STATUS_SUCCESS;
}
#else
static inline void wma_set_mgmt_frame_protection(tp_wma_handle wma)
{
}

static QDF_STATUS
wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac,
			bool is_pmf_enabled)
{
	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_11W */

/**
@@ -4325,6 +4361,8 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
		iface->llbCoexist = add_bss->llbCoexist;
		iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported;
		iface->nwType = add_bss->nwType;
		if (add_bss->rmfEnabled)
			wma_set_peer_pmf_status(wma, add_bss->bssId, true);
		if (add_bss->nonRoamReassoc) {
			peer = cdp_peer_find_by_addr(soc,
					pdev, add_bss->bssId,
@@ -4784,6 +4822,9 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
		}
	}
#endif
	if (add_sta->rmfEnabled)
		wma_set_peer_pmf_status(wma, add_sta->staMac, true);

	if (add_sta->uAPSD) {
		status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId,
					    add_sta->staMac,
+91 −20
Original line number Diff line number Diff line
@@ -3813,16 +3813,94 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle,
	}
	return 0;
}
#else
static inline int wma_process_rmf_frame(tp_wma_handle wma_handle,
	struct wma_txrx_node *iface,
	struct ieee80211_frame *wh,

/**
 * wma_get_peer_pmf_status() - Get the PMF capability of peer
 * @wma: wma handle
 * @peer_mac: peer mac addr
 *
 * Return: True if PMF is enabled, false otherwise.
 */
static bool
wma_get_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac)
{
	struct wlan_objmgr_peer *peer;
	bool is_pmf_enabled;

	if (!peer_mac) {
		WMA_LOGE("peer_mac is NULL");
		return false;
	}

	peer = wlan_objmgr_get_peer(wma->psoc,
				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
				    peer_mac, WLAN_LEGACY_WMA_ID);
	if (!peer) {
		WMA_LOGE("Peer of peer_mac %pM not found",
			 peer_mac);
		return false;
	}
	is_pmf_enabled = mlme_get_peer_pmf_status(peer);
	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
	WMA_LOGD("get is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac);

	return is_pmf_enabled;
}

/**
 * wma_check_and_process_rmf_frame() - Process the frame if it is of rmf type
 * @wma_handle: wma handle
 * @vdev_id: vdev id
 * @wh: double pointer to 802.11 frame header which will be updated if the
 *	frame is of rmf type.
 * @rx_pkt: rx packet
 * @buf: Buffer
 *
 * Process the frame as rmf frame only if both DUT and peer are of PMF capable
 *
 * Return: 0 for success or error code
 */
static int
wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,
				uint8_t vdev_id,
				struct ieee80211_frame **wh,
				cds_pkt_t *rx_pkt,
	qdf_nbuf_t wbuf)
				qdf_nbuf_t buf)
{
	int status;
	struct wma_txrx_node *iface;
	struct ieee80211_frame *hdr = *wh;

	iface = &(wma_handle->interfaces[vdev_id]);
	if (!iface->rmfEnabled)
		return 0;

	if (qdf_is_macaddr_group((struct qdf_mac_addr *)(hdr->i_addr1)) ||
	    qdf_is_macaddr_broadcast((struct qdf_mac_addr *)(hdr->i_addr1)) ||
	    wma_get_peer_pmf_status(wma_handle, hdr->i_addr2)) {
		status = wma_process_rmf_frame(wma_handle, iface, hdr,
					       rx_pkt, buf);
		if (status)
			return status;
		/*
		 * CCMP header might have been pulled off reinitialize the
		 * start pointer of mac header
		 */
		*wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
	}

	return 0;
}
#else
static inline int
wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,
				uint8_t vdev_id,
				struct ieee80211_frame **wh,
				cds_pkt_t *rx_pkt,
				qdf_nbuf_t buf)
{
	return 0;
}
#endif

/**
@@ -3860,7 +3938,6 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
			struct mgmt_rx_event_params *mgmt_rx_params,
			cds_pkt_t *rx_pkt)
{
	struct wma_txrx_node *iface = NULL;
	uint8_t vdev_id = WMA_INVALID_VDEV_ID;
	struct ieee80211_frame *wh;
	uint8_t mgt_type, mgt_subtype;
@@ -4000,19 +4077,13 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
	     mgt_subtype == IEEE80211_FC0_SUBTYPE_ACTION)) {
		if (wma_find_vdev_by_bssid(
			wma_handle, wh->i_addr3, &vdev_id)) {
			iface = &(wma_handle->interfaces[vdev_id]);
			if (iface->rmfEnabled) {
				status = wma_process_rmf_frame(wma_handle,
					iface, wh, rx_pkt, buf);
				if (status != 0)
			status = wma_check_and_process_rmf_frame(wma_handle,
								 vdev_id,
								 &wh,
								 rx_pkt,
								 buf);
			if (status)
				return status;
				/*
				 * CCMP header might have been pulled off
				 * reinitialize the start pointer of mac header
				 */
				wh = (struct ieee80211_frame *)
						qdf_nbuf_data(buf);
			}
		}
	}