qcacld-3.0: Add flow control to limit deauth per peer

Invalid peer keeps sending rx ind which triggers sending of
deauth mgmt frame continiously.

Fix is to add flow control in wma_rx_invalid_peer_ind()
to limit per peer deauth mgmt frame to one.

Change-Id: Icfbcb9452ee9890a26945b3cdd0c0ab07649367a
CRs-Fixed: 2538222
This commit is contained in:
Amruta Kulkarni
2019-10-11 17:47:48 -07:00
zatwierdzone przez nshrivas
rodzic e487f79e22
commit f3773e9435
3 zmienionych plików z 105 dodań i 8 usunięć

Wyświetl plik

@@ -90,6 +90,7 @@
#define wma_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_WMA, params)
#define wma_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_WMA, params)
#define wma_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_WMA, params)
#define wma_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_WMA, params)
#define wma_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_WMA, params)
#define wma_nofl_alert(params...) \
@@ -672,6 +673,16 @@ struct roam_synch_frame_ind {
uint8_t *reassoc_rsp;
};
/* Max number of invalid peer entries */
#define INVALID_PEER_MAX_NUM 5
/**
* struct wma_invalid_peer_params - stores invalid peer entries
* @rx_macaddr: store mac addr of invalid peer
*/
struct wma_invalid_peer_params {
uint8_t rx_macaddr[QDF_MAC_ADDR_SIZE];
};
/**
* struct wma_txrx_node - txrx node
@@ -725,7 +736,8 @@ struct roam_synch_frame_ind {
* @vdev_set_key_runtime_wakelock: runtime pm wakelock for set key
* @ch_freq: channel frequency
* @roam_scan_stats_req: cached roam scan stats request
*
* @wma_invalid_peer_params: structure storing invalid peer params
* @invalid_peer_idx: invalid peer index
* It stores parameters per vdev in wma.
*/
struct wma_txrx_node {
@@ -785,6 +797,8 @@ struct wma_txrx_node {
bool is_waiting_for_key;
uint32_t ch_freq;
struct sir_roam_scan_stats *roam_scan_stats_req;
struct wma_invalid_peer_params invalid_peers[INVALID_PEER_MAX_NUM];
uint8_t invalid_peer_idx;
};
/**
@@ -2434,7 +2448,16 @@ void wma_check_and_set_wake_timer(uint32_t time);
#endif
/**
* wma_rx_invalid_peer_ind(): the callback for DP to notify WMA layer
* wma_delete_invalid_peer_entries() - Delete invalid peer entries stored
* @vdev_id: virtual interface id
* @peer_mac_addr: Peer MAC address
*
* Removes the invalid peer mac entry from wma node
*/
void wma_delete_invalid_peer_entries(uint8_t vdev_id, uint8_t *peer_mac_addr);
/**
* wma_rx_invalid_peer_ind() - the callback for DP to notify WMA layer
* invalid peer data is received, this function will send message to
* lim module.
* @vdev_id: virtual device ID

Wyświetl plik

@@ -3091,27 +3091,97 @@ QDF_STATUS wma_lro_config_cmd(void *handle,
&wmi_lro_cmd);
}
void wma_delete_invalid_peer_entries(uint8_t vdev_id, uint8_t *peer_mac_addr)
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
uint8_t i;
struct wma_txrx_node *iface;
if (!wma) {
wma_err("wma handle is NULL");
return;
}
iface = &wma->interfaces[vdev_id];
if (peer_mac_addr) {
for (i = 0; i < INVALID_PEER_MAX_NUM; i++) {
if (qdf_mem_cmp
(iface->invalid_peers[i].rx_macaddr,
peer_mac_addr,
QDF_MAC_ADDR_SIZE) == 0) {
qdf_mem_zero(iface->invalid_peers[i].rx_macaddr,
sizeof(QDF_MAC_ADDR_SIZE));
break;
}
}
if (i == INVALID_PEER_MAX_NUM)
wma_debug("peer_mac_addr %pM is not found", peer_mac_addr);
} else {
qdf_mem_zero(iface->invalid_peers,
sizeof(iface->invalid_peers));
}
}
uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh)
{
struct ol_rx_inv_peer_params *rx_inv_msg;
struct ieee80211_frame *wh_l = (struct ieee80211_frame *)wh;
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
uint8_t i, index;
bool invalid_peer_found = false;
struct wma_txrx_node *iface;
if (!wma) {
wma_err("wma handle is NULL");
return -EINVAL;
}
iface = &wma->interfaces[vdev_id];
rx_inv_msg = qdf_mem_malloc(sizeof(struct ol_rx_inv_peer_params));
if (!rx_inv_msg)
return -ENOMEM;
index = iface->invalid_peer_idx;
rx_inv_msg->vdev_id = vdev_id;
qdf_mem_copy(rx_inv_msg->ra, wh_l->i_addr1, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(rx_inv_msg->ta, wh_l->i_addr2, QDF_MAC_ADDR_SIZE);
WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
wma_debug("RA:"QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(rx_inv_msg->ra));
wma_debug("TA:"QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(rx_inv_msg->ta));
wma_send_msg(wma, SIR_LIM_RX_INVALID_PEER, (void *)rx_inv_msg, 0);
for (i = 0; i < INVALID_PEER_MAX_NUM; i++) {
if (qdf_mem_cmp
(iface->invalid_peers[i].rx_macaddr,
rx_inv_msg->ra,
QDF_MAC_ADDR_SIZE) == 0) {
invalid_peer_found = true;
break;
}
}
if (!invalid_peer_found) {
qdf_mem_copy(iface->invalid_peers[index].rx_macaddr,
rx_inv_msg->ra,
QDF_MAC_ADDR_SIZE);
/* reset count if reached max */
iface->invalid_peer_idx =
(index + 1) % INVALID_PEER_MAX_NUM;
/* send deauth */
WMA_LOGD("%s: vdev_id %d", __func__, vdev_id);
wma_debug(" RA: " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(rx_inv_msg->ra));
wma_debug(" TA: " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(rx_inv_msg->ta));
wma_send_msg(wma,
SIR_LIM_RX_INVALID_PEER,
(void *)rx_inv_msg, 0);
} else {
wma_debug_rl("Ignore invalid peer indication as received more than once "
QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(rx_inv_msg->ra));
}
return 0;
}

Wyświetl plik

@@ -3966,6 +3966,8 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
goto send_rsp;
}
wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac);
status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
WMI_PEER_TYPE_DEFAULT, add_sta->smesessionId,
false);
@@ -5113,6 +5115,8 @@ void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id)
goto out;
}
wma_delete_invalid_peer_entries(vdev_id, NULL);
if (iface->psnr_req) {
qdf_mem_free(iface->psnr_req);
iface->psnr_req = NULL;