From 29d256f801df951bd09152b55b6503635495e1b2 Mon Sep 17 00:00:00 2001 From: Ananya Gupta Date: Wed, 18 Aug 2021 13:14:35 +0530 Subject: [PATCH] qcacmn: Log DHCP, EAPOL packets to logging queue Log DHCP and EAPOL packets to wlan connectivity logging queue. Change-Id: Ib0c84c389c0f5fd7e742722c0e03c84b9732de19 CRs-Fixed: 3030936 --- qdf/inc/qdf_nbuf.h | 19 ++++- qdf/linux/src/qdf_trace.c | 163 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 175 insertions(+), 7 deletions(-) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index e86baee410..f6d0c28dd4 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -95,13 +95,28 @@ /* EAPOL Related MASK */ #define EAPOL_PACKET_TYPE_OFFSET 15 #define EAPOL_KEY_INFO_OFFSET 19 -#define EAPOL_PKT_LEN_OFFSET 16 -#define EAPOL_KEY_LEN_OFFSET 21 +#define EAPOL_PKT_LEN_OFFSET 16 +#define EAPOL_KEY_LEN_OFFSET 21 +#define EAPOL_PACKET_TYPE_KEY 3 #define EAPOL_MASK 0x8013 #define EAPOL_M1_BIT_MASK 0x8000 #define EAPOL_M2_BIT_MASK 0x0001 #define EAPOL_M3_BIT_MASK 0x8013 #define EAPOL_M4_BIT_MASK 0x0003 +#define EAPOL_KEY_TYPE_MASK 0x0800 +#define EAPOL_KEY_ENCRYPTED_MASK 0x0010 + +/* EAP Related Mask */ + +#define EAP_CODE_OFFSET 18 +#define EAP_LENGTH_OFFSET 20 +#define EAP_TYPE_OFFSET 22 +#define QDF_EAP_REQUEST 1 +#define QDF_EAP_RESPONE 2 +#define QDF_EAP_SUCCESS 3 +#define QDF_EAP_FAILURE 4 +#define QDF_EAP_INITIATE 5 +#define QDF_EAP_FINISH 6 /* ARP Related MASK */ #define QDF_NBUF_PKT_ARP_OPCODE_OFFSET 20 diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index e17b99e40e..9283e2189e 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -47,6 +47,10 @@ qdf_declare_param(qdf_log_flush_timer_period, uint); #include "qdf_mc_timer.h" #include +#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING +#include +#endif + /* Global qdf print id */ /* Preprocessor definitions and constants */ @@ -1720,6 +1724,143 @@ static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb, return false; } +#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING +/** + * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag + * @subtype: EAPoL key subtype + * + * Return: Wlan main tag subtype + */ +static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype) +{ + switch (subtype) { + case QDF_PROTO_DHCP_DISCOVER: + return WLAN_DHCP_DISCOVER; + case QDF_PROTO_DHCP_REQUEST: + return WLAN_DHCP_REQUEST; + case QDF_PROTO_DHCP_OFFER: + return WLAN_DHCP_OFFER; + case QDF_PROTO_DHCP_ACK: + return WLAN_DHCP_ACK; + case QDF_PROTO_DHCP_NACK: + return WLAN_DHCP_NACK; + case QDF_PROTO_EAPOL_M1: + return WLAN_EAPOL_M1; + case QDF_PROTO_EAPOL_M2: + return WLAN_EAPOL_M2; + case QDF_PROTO_EAPOL_M3: + return WLAN_EAPOL_M3; + case QDF_PROTO_EAPOL_M4: + return WLAN_EAPOL_M4; + default: + return WLAN_TAG_MAX; + } +} + +/** + * qdf_get_wlan_eap_code() - Get EAP code + * @data: skb data pointer + * + * Return: EAP code value + */ +static int qdf_get_wlan_eap_code(uint8_t *data) +{ + uint8_t code = *(data + EAP_CODE_OFFSET); + + switch (code) { + case QDF_EAP_REQUEST: + return WLAN_EAP_REQUEST; + case QDF_EAP_RESPONE: + return WLAN_EAP_RESPONSE; + case QDF_EAP_SUCCESS: + return WLAN_EAP_SUCCESS; + case QDF_EAP_FAILURE: + return WLAN_EAP_FAILURE; + default: + return WLAN_TAG_MAX; + } +} + +/** + * qdf_eapol_get_key_type() - Get EAPOL key type + * @data: skb data pointer + * @subtype: EAPoL key subtype + * + * Return: EAPOL key type + */ +static +uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype) +{ + uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET); + + /* If key type is PTK, key type will be set in EAPOL Key info */ + if (key_info & EAPOL_KEY_TYPE_MASK) + return qdf_subtype_to_wlan_main_tag(subtype); + else if (key_info & EAPOL_KEY_ENCRYPTED_MASK) + return WLAN_GTK_M1; + else + return WLAN_GTK_M2; +} + +/** + * qdf_fill_wlan_connectivity_log() - Fill and queue protocol packet to logging + * the logging queue + * @type: Protocol type + * @subtype: Protocol subtype + * @dir: Rx or Tx + * @qdf_tx_status: Tx completion status + * @vdev_id: DP vdev ID + * @data: skb data pointer + * + * Return: None + */ +static +void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type, + enum qdf_proto_subtype subtype, + enum qdf_proto_dir dir, + enum qdf_dp_tx_rx_status qdf_tx_status, + uint8_t vdev_id, uint8_t *data) +{ + struct wlan_log_record log_buf; + uint8_t pkt_type; + + log_buf.timestamp_us = qdf_get_time_of_the_day_ms() * 1000; + log_buf.vdev_id = vdev_id; + if (type == QDF_PROTO_TYPE_DHCP) { + log_buf.log_subtype = qdf_subtype_to_wlan_main_tag(subtype); + } else if (type == QDF_PROTO_TYPE_EAPOL) { + pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET); + if (pkt_type == 0) { + log_buf.log_subtype = qdf_get_wlan_eap_code(data); + log_buf.pkt_info.eap_type = *(data + EAP_TYPE_OFFSET); + log_buf.pkt_info.eap_len = + qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET)); + } else if (pkt_type == EAPOL_PACKET_TYPE_KEY) { + log_buf.log_subtype = qdf_eapol_get_key_type(data, + subtype); + } + } else { + return; + } + + /*Tx completion status needs to be logged*/ + if (dir == QDF_TX) + log_buf.pkt_info.tx_status = qdf_tx_status; + + wlan_connectivity_log_enqueue(&log_buf); +} + +#else +static inline +void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type, + enum qdf_proto_subtype subtype, + enum qdf_proto_dir dir, + enum qdf_dp_tx_rx_status qdf_tx_status, + uint8_t vdev_id, uint8_t *data) +{ +} +#endif + /** * qdf_log_eapol_pkt() - log EAPOL packet * @vdev_id: ID of the vdev @@ -1750,12 +1891,15 @@ static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb, subtype = qdf_nbuf_get_eapol_subtype(skb); - if (dp_eap_event && dir == QDF_RX) + if (dp_eap_event && dir == QDF_RX) { qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET, skb->data + QDF_NBUF_DEST_MAC_OFFSET, QDF_PROTO_TYPE_EAPOL, subtype, dir, QDF_TRACE_DEFAULT_MSDU_ID, QDF_TX_RX_STATUS_INVALID); + qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_EAPOL, subtype, + QDF_RX, 0, vdev_id, skb->data); + } if (dp_eap_trace) { QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; @@ -1825,12 +1969,15 @@ static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb, subtype = qdf_nbuf_get_dhcp_subtype(skb); - if (dp_dhcp_event && dir == QDF_RX) + if (dp_dhcp_event && dir == QDF_RX) { qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET, skb->data + QDF_NBUF_DEST_MAC_OFFSET, QDF_PROTO_TYPE_DHCP, subtype, dir, QDF_TRACE_DEFAULT_MSDU_ID, QDF_TX_RX_STATUS_INVALID); + qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_DHCP, subtype, + QDF_RX, 0, vdev_id, 0); + } if (dp_dhcp_trace) { QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; @@ -2331,16 +2478,22 @@ void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, struct qdf_dp_trace_ptr_buf buf; int buf_size = sizeof(struct qdf_dp_trace_ptr_buf); enum qdf_proto_type pkt_type; + enum qdf_proto_subtype subtype; pkt_type = qdf_dp_get_pkt_proto_type(nbuf); if ((code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD || code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD) && - qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) + qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) { + subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type); qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET, nbuf->data + QDF_NBUF_DEST_MAC_OFFSET, - pkt_type, - qdf_dp_get_pkt_subtype(nbuf, pkt_type), + pkt_type, subtype, QDF_TX, msdu_id, qdf_tx_status); + qdf_fill_wlan_connectivity_log(pkt_type, subtype, + QDF_TX, qdf_tx_status, + QDF_NBUF_CB_TX_VDEV_CTX(nbuf), + nbuf->data); + } if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false) return;