|
@@ -118,6 +118,61 @@ static qdf_atomic_t nbuf_count;
|
|
|
static bool is_initial_mem_debug_disabled;
|
|
|
#endif
|
|
|
|
|
|
+/**
|
|
|
+ * __qdf_nbuf_get_ip_offset - Get IPV4/V6 header offset
|
|
|
+ * @data: Pointer to network data buffer
|
|
|
+ *
|
|
|
+ * Get the IP header offset in case of 8021Q and 8021AD
|
|
|
+ * tag is present in L2 header.
|
|
|
+ *
|
|
|
+ * Return: IP header offset
|
|
|
+ */
|
|
|
+static inline uint8_t __qdf_nbuf_get_ip_offset(uint8_t *data)
|
|
|
+{
|
|
|
+ uint16_t ether_type;
|
|
|
+
|
|
|
+ ether_type = *(uint16_t *)(data +
|
|
|
+ QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
|
|
|
+
|
|
|
+ if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q)))
|
|
|
+ return QDF_NBUF_TRAC_VLAN_IP_OFFSET;
|
|
|
+ else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD)))
|
|
|
+ return QDF_NBUF_TRAC_DOUBLE_VLAN_IP_OFFSET;
|
|
|
+
|
|
|
+ return QDF_NBUF_TRAC_IP_OFFSET;
|
|
|
+}
|
|
|
+
|
|
|
+qdf_export_symbol(__qdf_nbuf_get_ip_offset);
|
|
|
+
|
|
|
+/**
|
|
|
+ * __qdf_nbuf_get_ether_type - Get the ether type
|
|
|
+ * @data: Pointer to network data buffer
|
|
|
+ *
|
|
|
+ * Get the ether type in case of 8021Q and 8021AD tag
|
|
|
+ * is present in L2 header, e.g for the returned ether type
|
|
|
+ * value, if IPV4 data ether type 0x0800, return 0x0008.
|
|
|
+ *
|
|
|
+ * Return ether type.
|
|
|
+ */
|
|
|
+static inline uint16_t __qdf_nbuf_get_ether_type(uint8_t *data)
|
|
|
+{
|
|
|
+ uint16_t ether_type;
|
|
|
+
|
|
|
+ ether_type = *(uint16_t *)(data +
|
|
|
+ QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
|
|
|
+
|
|
|
+ if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q)))
|
|
|
+ ether_type = *(uint16_t *)(data +
|
|
|
+ QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET);
|
|
|
+ else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD)))
|
|
|
+ ether_type = *(uint16_t *)(data +
|
|
|
+ QDF_NBUF_TRAC_DOUBLE_VLAN_ETH_TYPE_OFFSET);
|
|
|
+
|
|
|
+ return ether_type;
|
|
|
+}
|
|
|
+
|
|
|
+qdf_export_symbol(__qdf_nbuf_get_ether_type);
|
|
|
+
|
|
|
/**
|
|
|
* qdf_nbuf_tx_desc_count_display() - Displays the packet counter
|
|
|
*
|
|
@@ -1370,12 +1425,21 @@ bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data)
|
|
|
{
|
|
|
uint16_t sport;
|
|
|
uint16_t dport;
|
|
|
+ uint8_t ipv4_offset;
|
|
|
+ uint8_t ipv4_hdr_len;
|
|
|
+ struct iphdr *iphdr;
|
|
|
+
|
|
|
+ if (__qdf_nbuf_get_ether_type(data) !=
|
|
|
+ QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE))
|
|
|
+ return false;
|
|
|
|
|
|
- sport = (uint16_t)(*(uint16_t *)(data + QDF_NBUF_TRAC_IPV4_OFFSET +
|
|
|
- QDF_NBUF_TRAC_IPV4_HEADER_SIZE));
|
|
|
- dport = (uint16_t)(*(uint16_t *)(data + QDF_NBUF_TRAC_IPV4_OFFSET +
|
|
|
- QDF_NBUF_TRAC_IPV4_HEADER_SIZE +
|
|
|
- sizeof(uint16_t)));
|
|
|
+ ipv4_offset = __qdf_nbuf_get_ip_offset(data);
|
|
|
+ iphdr = (struct iphdr *)(data + ipv4_offset);
|
|
|
+ ipv4_hdr_len = iphdr->ihl * QDF_NBUF_IPV4_HDR_SIZE_UNIT;
|
|
|
+
|
|
|
+ sport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len);
|
|
|
+ dport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len +
|
|
|
+ sizeof(uint16_t));
|
|
|
|
|
|
if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_SRV_PORT)) &&
|
|
|
(dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_CLI_PORT))) ||
|
|
@@ -1400,8 +1464,7 @@ bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data)
|
|
|
{
|
|
|
uint16_t ether_type;
|
|
|
|
|
|
- ether_type = (uint16_t)(*(uint16_t *)(data +
|
|
|
- QDF_NBUF_TRAC_ETH_TYPE_OFFSET));
|
|
|
+ ether_type = __qdf_nbuf_get_ether_type(data);
|
|
|
|
|
|
if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_EAPOL_ETH_TYPE))
|
|
|
return true;
|
|
@@ -1469,8 +1532,7 @@ bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data)
|
|
|
{
|
|
|
uint16_t ether_type;
|
|
|
|
|
|
- ether_type = (uint16_t)(*(uint16_t *)(data +
|
|
|
- QDF_NBUF_TRAC_ETH_TYPE_OFFSET));
|
|
|
+ ether_type = __qdf_nbuf_get_ether_type(data);
|
|
|
|
|
|
if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_ARP_ETH_TYPE))
|
|
|
return true;
|
|
@@ -1845,12 +1907,14 @@ bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data)
|
|
|
{
|
|
|
uint16_t sport;
|
|
|
uint16_t dport;
|
|
|
-
|
|
|
- sport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
|
|
|
- QDF_NBUF_TRAC_IPV6_HEADER_SIZE);
|
|
|
- dport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
|
|
|
- QDF_NBUF_TRAC_IPV6_HEADER_SIZE +
|
|
|
- sizeof(uint16_t));
|
|
|
+ uint8_t ipv6_offset;
|
|
|
+
|
|
|
+ ipv6_offset = __qdf_nbuf_get_ip_offset(data);
|
|
|
+ sport = *(uint16_t *)(data + ipv6_offset +
|
|
|
+ QDF_NBUF_TRAC_IPV6_HEADER_SIZE);
|
|
|
+ dport = *(uint16_t *)(data + ipv6_offset +
|
|
|
+ QDF_NBUF_TRAC_IPV6_HEADER_SIZE +
|
|
|
+ sizeof(uint16_t));
|
|
|
|
|
|
if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT)) &&
|
|
|
(dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT))) ||
|