Преглед на файлове

qcacld-3.0: Fix incorrect head_skb IP/UDP header in fisa flow

Host received mixed vlan header frames and non-vlan header frames,
and these frames is belong to same UDP flow. currently wlan host
will assume same UDP flow frames with same L2 header length which
then get incorrect IP/UDP header for non-vlan frames.
Determine FISA continuation by RX frame self L2/L3 header length,
update head skb L2/L3 header length in fisa flow when head skb
changed.

Change-Id: Id61b856773b8dd7f0199055b1e0bf9a2bd98e401
CRs-Fixed: 2778403
Jinwei Chen преди 4 години
родител
ревизия
2c0ab424d7
променени са 1 файла, в които са добавени 14 реда и са изтрити 10 реда
  1. 14 10
      core/dp/txrx3.0/dp_fisa_rx.c

+ 14 - 10
core/dp/txrx3.0/dp_fisa_rx.c

@@ -1003,16 +1003,19 @@ static int get_transport_payload_offset(struct dp_rx_fst *fisa_hdl,
 /**
  * get_transport_header_offset() - Get transport header offset
  * @fisa_flow: Handle to FISA sw flow entry
- * @nbuf: Incoming nbuf, should have data pointing to ethernet hdr
+ * @rx_tlv_hdr: TLV hdr pointer
  *
  * Return: Offset value to transport header
  */
 static int get_transport_header_offset(struct dp_fisa_rx_sw_ft *fisa_flow,
-				       qdf_nbuf_t nbuf)
+				       uint8_t *rx_tlv_hdr)
 
 {
-	return (fisa_flow->head_skb_ip_hdr_offset +
-		fisa_flow->head_skb_l4_hdr_offset);
+	uint32_t eth_hdr_len = HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr);
+	uint32_t ip_hdr_len = HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr);
+
+	/* ETHERNET_HDR_LEN + ip_hdr_len */
+	return (eth_hdr_len + ip_hdr_len);
 }
 
 /**
@@ -1038,7 +1041,7 @@ dp_rx_fisa_aggr_udp(struct dp_rx_fst *fisa_hdl,
 	qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + l2_hdr_offset);
 
 	udp_hdr = (struct udphdr *)(qdf_nbuf_data(nbuf) +
-			get_transport_header_offset(fisa_flow, nbuf));
+			get_transport_header_offset(fisa_flow, rx_tlv_hdr));
 
 	udp_len = qdf_ntohs(udp_hdr->len);
 
@@ -1065,6 +1068,10 @@ dp_rx_fisa_aggr_udp(struct dp_rx_fst *fisa_hdl,
 		fisa_flow->head_skb_udp_hdr = udp_hdr;
 		fisa_flow->cur_aggr_gso_size = udp_len - sizeof(struct udphdr);
 		fisa_flow->adjusted_cumulative_ip_length = udp_len;
+		fisa_flow->head_skb_ip_hdr_offset =
+					HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr);
+		fisa_flow->head_skb_l4_hdr_offset =
+					HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr);
 
 		fisa_flow->frags_cumulative_len = 0;
 
@@ -1234,7 +1241,8 @@ dp_rx_fisa_flush_udp_flow(struct dp_vdev *vdev,
 						   head_skb_iph->ihl);
 
 		head_skb_udp_hdr->len =
-			qdf_htons(qdf_ntohs(head_skb_iph->tot_len) - 20);
+			qdf_htons(qdf_ntohs(head_skb_iph->tot_len) -
+				  fisa_flow->head_skb_l4_hdr_offset);
 		head_skb_udp_hdr->check = pseudo;
 		head_skb->csum_start = (u8 *)head_skb_udp_hdr - head_skb->head;
 		head_skb->csum_offset = offsetof(struct udphdr, check);
@@ -1503,10 +1511,6 @@ static int dp_add_nbuf_to_fisa_flow(struct dp_rx_fst *fisa_hdl,
 
 	if (!fisa_flow->head_skb) {
 		/* This is start of aggregation for the flow, save the offsets*/
-		fisa_flow->head_skb_ip_hdr_offset =
-					HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr);
-		fisa_flow->head_skb_l4_hdr_offset =
-					HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr);
 		fisa_flow->napi_flush_cumulative_l4_checksum = 0;
 		fisa_flow->cur_aggr = 0;
 	}