qcacld-2.0: Fix logic to drop duplicate deauth/disassoc frames

propagation from qcacld-3.0 to qcacld-2.0.

The frame received time is updated even when the frame was
dropped and thus the received time of the frame keeps on increasing.
Thus the condition to check if frame is allowed after
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER ms always fails if driver
continuously keep on getting the frames.

This can lead to dropping of valid deauth/disassoc frames in case
if RMF is enabled and some rogue peer keep on sending rogue
deauth/disassoc frames and thus even if peer send valid deauth
peer will not get disconnected.

Fix this by updating the rcvd time stamp only when the frame is
allowed, as this timestamp should be used to block the duplicate
frames for TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER ms.

Change-Id: I4f480e21369b585d78f240c5f4f062d010d889a8
CRs-Fixed: 2258844
This commit is contained in:
gaolez 2018-06-12 17:51:44 +08:00 committed by syphyr
parent ac2156d3ba
commit ec9f4b123e
5 changed files with 37 additions and 32 deletions

View File

@ -510,36 +510,33 @@ static bool tlshim_is_pkt_drop_candidate(tp_wma_handle wma_handle,
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
if (peer->last_assoc_rcvd) {
if (adf_os_gettimestamp() - peer->last_assoc_rcvd <
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER) {
TLSHIM_LOGD(FL("Dropping Assoc Req received"));
should_drop = TRUE;
}
if (peer->last_assoc_rcvd &&
vos_system_time_after(peer->last_assoc_rcvd +
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER,
adf_os_gettimestamp())) {
TLSHIM_LOGD(FL("Dropping Assoc Req as it is received after %d ms of last frame. Allow it only after %d ms"),
(int) (adf_os_gettimestamp() -
peer->last_assoc_rcvd),
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER);
should_drop = TRUE;
break;
}
peer->last_assoc_rcvd = adf_os_gettimestamp();
break;
case IEEE80211_FC0_SUBTYPE_DISASSOC:
if (peer->last_disassoc_rcvd) {
if (adf_os_gettimestamp() -
peer->last_disassoc_rcvd <
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER) {
TLSHIM_LOGD(FL("Dropping DisAssoc received"));
should_drop = TRUE;
}
}
peer->last_disassoc_rcvd = adf_os_gettimestamp();
break;
case IEEE80211_FC0_SUBTYPE_DEAUTH:
if (peer->last_deauth_rcvd) {
if (adf_os_gettimestamp() -
peer->last_deauth_rcvd <
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER) {
TLSHIM_LOGD(FL("Dropping Deauth received"));
should_drop = TRUE;
}
if (peer->last_disassoc_deauth_rcvd &&
vos_system_time_after(peer->last_disassoc_deauth_rcvd +
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER,
adf_os_gettimestamp())) {
TLSHIM_LOGD(FL("Dropping subtype %x frame as it is received after %d ms of last frame. Allow it only after %d ms"),
subtype, (int) (adf_os_gettimestamp() -
peer->last_disassoc_deauth_rcvd),
TLSHIM_MGMT_FRAME_DETECT_DOS_TIMER);
should_drop = TRUE;
break;
}
peer->last_deauth_rcvd = adf_os_gettimestamp();
peer->last_disassoc_deauth_rcvd = adf_os_gettimestamp();
break;
default:
break;

View File

@ -1131,8 +1131,7 @@ ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer)
peer->security[txrx_sec_mcast].sec_type = htt_sec_type_none;
peer->keyinstalled = 0;
peer->last_assoc_rcvd = 0;
peer->last_disassoc_rcvd = 0;
peer->last_deauth_rcvd = 0;
peer->last_disassoc_deauth_rcvd = 0;
adf_os_atomic_init(&peer->fw_pn_check);
}
@ -1142,8 +1141,7 @@ ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer)
{
peer->keyinstalled = 0;
peer->last_assoc_rcvd = 0;
peer->last_disassoc_rcvd = 0;
peer->last_deauth_rcvd = 0;
peer->last_disassoc_deauth_rcvd = 0;
ol_rx_reorder_peer_cleanup(vdev, peer);
adf_os_mem_free(peer->reorder_history);
peer->reorder_history = NULL;

View File

@ -1155,8 +1155,7 @@ struct ol_txrx_peer_t {
u_int16_t tx_pause_flag;
#endif
adf_os_time_t last_assoc_rcvd;
adf_os_time_t last_disassoc_rcvd;
adf_os_time_t last_deauth_rcvd;
adf_os_time_t last_disassoc_deauth_rcvd;
struct ol_rx_reorder_history * reorder_history;
};

View File

@ -329,6 +329,17 @@ v_TIME_t vos_timer_get_system_ticks( v_VOID_t );
------------------------------------------------------------------------*/
v_TIME_t vos_timer_get_system_time( v_VOID_t );
/**
* vos_system_time_after() - Check if a is later than b
* @a: Time stamp value a
* @b: Time stamp value b
*
* Return:
* true if a is after b else false
*/
static inline bool vos_system_time_after(vos_time_t a, vos_time_t b)
{
return (long)(b) - (long)(a) < 0;
}
#endif // #if !defined __VOSS_TIMER_H

View File

@ -98,7 +98,7 @@ static inline unsigned int vos_round_div(unsigned int dividend,
#endif
typedef unsigned long vos_time_t;
/*--------------------------------------------------------------------------
Type declarations
------------------------------------------------------------------------*/