Browse Source

qcacmn: Update dp_peer structure to store qdf timers to detect DOS attack

Update dp_peer structure to store qdf timers to detect DOS attack. Following
driver ops are registerd to access the dp peer information
    - last_assoc_received
    - last_disassoc_received
    - last_deaauth_received
    - clear_peer

Change-Id: I21a3f4e5ab626e62f58f307d02640b7d96c9b1ef
CRs-Fixed: 1116647
Krishna Kumaar Natarajan 8 years ago
parent
commit
d684ba2f05
5 changed files with 85 additions and 6 deletions
  1. 6 3
      dp/inc/cdp_txrx_peer_ops.h
  2. 4 0
      dp/wifi3.0/dp_internal.h
  3. 9 2
      dp/wifi3.0/dp_main.c
  4. 61 0
      dp/wifi3.0/dp_peer.c
  5. 5 1
      dp/wifi3.0/dp_types.h

+ 6 - 3
dp/inc/cdp_txrx_peer_ops.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -61,7 +61,7 @@ cdp_peer_register(ol_txrx_soc_handle soc, void *pdev,
 }
 
 /**
- * cdp_peer_clear() - remove peer from physical device
+ * cdp_clear_peer() - remove peer from physical device
  * @soc - data path soc handle
  * @pdev - data path device instance
  * @sta_id - local peer id
@@ -72,7 +72,7 @@ cdp_peer_register(ol_txrx_soc_handle soc, void *pdev,
  *         QDF_STATUS_E_NOSUPPORT not support this feature
  */
 static inline QDF_STATUS
-cdp_peer_clear(ol_txrx_soc_handle soc, void *pdev, uint8_t sta_id)
+cdp_clear_peer(ol_txrx_soc_handle soc, void *pdev, uint8_t sta_id)
 {
 	if (!soc || !soc->ops || !soc->ops->peer_ops) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
@@ -80,6 +80,9 @@ cdp_peer_clear(ol_txrx_soc_handle soc, void *pdev, uint8_t sta_id)
 		return QDF_STATUS_E_INVAL;
 	}
 
+	if (soc->ops->peer_ops->clear_peer)
+		return soc->ops->peer_ops->clear_peer(pdev, sta_id);
+
 	return QDF_STATUS_E_NOSUPPORT;
 }
 

+ 4 - 0
dp/wifi3.0/dp_internal.h

@@ -58,6 +58,7 @@ extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer);
 extern void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer);
 extern void dp_peer_find_hash_erase(struct dp_soc *soc);
 extern void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer);
+extern void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer);
 extern void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer);
 extern void dp_peer_unref_delete(void *peer_handle);
 extern void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer,
@@ -81,6 +82,9 @@ int dp_get_peer_state(void *peer_handle);
 void dp_local_peer_id_pool_init(struct dp_pdev *pdev);
 void dp_local_peer_id_alloc(struct dp_pdev *pdev, struct dp_peer *peer);
 void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer);
+qdf_time_t *dp_get_last_assoc_received(void *peer_handle);
+qdf_time_t *dp_get_last_disassoc_received(void *peer_handle);
+qdf_time_t *dp_get_last_deauth_received(void *peer_handle);
 #endif
 extern int dp_addba_requestprocess_wifi3(void *peer_handle,
 	uint8_t dialogtoken, uint16_t tid, uint16_t batimeout,

+ 9 - 2
dp/wifi3.0/dp_main.c

@@ -1425,6 +1425,10 @@ static void dp_peer_setup_wifi3(void *vdev_hdl, void *peer_hdl)
 
 	dp_peer_rx_init(pdev, peer);
 
+	peer->last_assoc_rcvd = 0;
+	peer->last_disassoc_rcvd = 0;
+	peer->last_deauth_rcvd = 0;
+
 	if (soc->cdp_soc.ol_ops->peer_set_default_routing) {
 		/* TODO: Check the destination ring number to be passed to FW */
 		soc->cdp_soc.ol_ops->peer_set_default_routing(soc->osif_soc,
@@ -1517,8 +1521,8 @@ void dp_peer_unref_delete(void *peer_handle)
 				peer, vdev, &peer->vdev->peer_list);
 		}
 
-		/* cleanup the Rx reorder queues for this peer */
-		dp_peer_rx_cleanup(vdev, peer);
+		/* cleanup the peer data */
+		dp_peer_cleanup(vdev, peer);
 
 		/* check whether the parent vdev has no peers left */
 		if (TAILQ_EMPTY(&vdev->peer_list)) {
@@ -1774,6 +1778,9 @@ static struct cdp_peer_ops dp_ops_peer = {
 	.peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr,
 	.get_vdev_for_peer = dp_get_vdev_for_peer,
 	.get_peer_state = dp_get_peer_state,
+	.last_assoc_received = dp_get_last_assoc_received,
+	.last_disassoc_received = dp_get_last_disassoc_received,
+	.last_deauth_received = dp_get_last_deauth_received,
 };
 #endif
 

+ 61 - 0
dp/wifi3.0/dp_peer.c

@@ -760,6 +760,22 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
 #endif
 }
 
+/*
+ * dp_peer_cleanup() – Cleanup peer information
+ * @vdev: Datapath vdev
+ * @peer: Datapath peer
+ *
+ */
+void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
+{
+	peer->last_assoc_rcvd = 0;
+	peer->last_disassoc_rcvd = 0;
+	peer->last_deauth_rcvd = 0;
+
+	/* cleanup the Rx reorder queues for this peer */
+	dp_peer_rx_cleanup(vdev, peer);
+}
+
 /*
 * dp_rx_addba_requestprocess_wifi3() – Process ADDBA request from peer
 *
@@ -1167,6 +1183,51 @@ int dp_get_peer_state(void *peer_handle)
 	return peer->state;
 }
 
+/**
+ * dp_get_last_assoc_received() - get time of last assoc received
+ * @peer_handle: peer handle
+ *
+ * Return: pointer for the time of last assoc received
+ */
+qdf_time_t *dp_get_last_assoc_received(void *peer_handle)
+{
+	struct dp_peer *peer = peer_handle;
+
+	DP_TRACE(INFO, "peer %p last_assoc_rcvd: %lu", peer,
+		peer->last_assoc_rcvd);
+	return &peer->last_assoc_rcvd;
+}
+
+/**
+ * dp_get_last_disassoc_received() - get time of last disassoc received
+ * @peer_handle: peer handle
+ *
+ * Return: pointer for the time of last disassoc received
+ */
+qdf_time_t *dp_get_last_disassoc_received(void *peer_handle)
+{
+	struct dp_peer *peer = peer_handle;
+
+	DP_TRACE(INFO, "peer %p last_disassoc_rcvd: %lu", peer,
+		peer->last_disassoc_rcvd);
+	return &peer->last_disassoc_rcvd;
+}
+
+/**
+ * dp_get_last_deauth_received() - get time of last deauth received
+ * @peer_handle: peer handle
+ *
+ * Return: pointer for the time of last deauth received
+ */
+qdf_time_t *dp_get_last_deauth_received(void *peer_handle)
+{
+	struct dp_peer *peer = peer_handle;
+
+	DP_TRACE(INFO, "peer %p last_deauth_rcvd: %lu", peer,
+		peer->last_deauth_rcvd);
+	return &peer->last_deauth_rcvd;
+}
+
 /**
  * dp_local_peer_id_pool_init() - local peer id pool alloc for physical device
  * @pdev - data path device instance

+ 5 - 1
dp/wifi3.0/dp_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -711,6 +711,10 @@ struct dp_peer {
 	uint16_t local_id;
 	enum ol_txrx_peer_state state;
 	qdf_spinlock_t peer_info_lock;
+
+	qdf_time_t last_assoc_rcvd;
+	qdf_time_t last_disassoc_rcvd;
+	qdf_time_t last_deauth_rcvd;
 	/* TBD */
 };