Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 249ff30d authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: qualcomm: rmnet: treat IPv4 UDP zero checksum as valid"

parents c0ad5a2d f9af0ab5
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -672,6 +672,12 @@ static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc,
		new_frag->tcp_seq_set = 1;
		new_frag->tcp_seq = htonl(ntohl(th->seq) +
					  coal_desc->data_offset);
	} else if (coal_desc->trans_proto == IPPROTO_UDP) {
		struct udphdr *uh;

		uh = (struct udphdr *)(hdr_start + coal_desc->ip_len);
		if (coal_desc->ip_proto == 4 && !uh->check)
			csum_valid = true;
	}

	if (coal_desc->ip_proto == 4) {
@@ -736,6 +742,7 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc,
	u8 pkt, total_pkt = 0;
	u8 nlo;
	bool gro = coal_desc->dev->features & NETIF_F_GRO_HW;
	bool zero_csum = false;

	/* Pull off the headers we no longer need */
	if (!rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header)))
@@ -796,7 +803,12 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc,
		th = (struct tcphdr *)((u8 *)iph + coal_desc->ip_len);
		coal_desc->trans_len = th->doff * 4;
	} else if (coal_desc->trans_proto == IPPROTO_UDP) {
		coal_desc->trans_len = sizeof(struct udphdr);
		struct udphdr *uh;

		uh = (struct udphdr *)((u8 *)iph + coal_desc->ip_len);
		coal_desc->trans_len = sizeof(*uh);
		if (coal_desc->ip_proto == 4 && !uh->check)
			zero_csum = true;
	} else {
		priv->stats.coal.coal_trans_invalid++;
		return;
@@ -804,7 +816,7 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc,

	coal_desc->hdrs_valid = 1;

	if (rmnet_map_v5_csum_buggy(coal_hdr)) {
	if (rmnet_map_v5_csum_buggy(coal_hdr) && !zero_csum) {
		/* Mark the checksum as valid if it checks out */
		if (rmnet_frag_validate_csum(coal_desc))
			coal_desc->csum_valid = true;
+9 −2
Original line number Diff line number Diff line
@@ -716,6 +716,7 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
	struct rmnet_priv *priv = netdev_priv(coal_skb->dev);
	__sum16 *check = NULL;
	u32 alloc_len;
	bool zero_csum = false;

	/* We can avoid copying the data if the SKB we got from the lower-level
	 * drivers was nonlinear.
@@ -747,6 +748,8 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,

		uh->len = htons(skbn->len);
		check = &uh->check;
		if (coal_meta->ip_proto == 4 && !uh->check)
			zero_csum = true;
	}

	/* Push IP header and update necessary fields */
@@ -767,7 +770,7 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
	}

	/* Handle checksum status */
	if (likely(csum_valid)) {
	if (likely(csum_valid) || zero_csum) {
		/* Set the partial checksum information */
		rmnet_map_partial_csum(skbn, coal_meta);
	} else if (check) {
@@ -865,6 +868,7 @@ static void rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
	u8 pkt, total_pkt = 0;
	u8 nlo;
	bool gro = coal_skb->dev->features & NETIF_F_GRO_HW;
	bool zero_csum = false;

	memset(&coal_meta, 0, sizeof(coal_meta));

@@ -926,12 +930,15 @@ static void rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
		uh = (struct udphdr *)((u8 *)iph + coal_meta.ip_len);
		coal_meta.trans_len = sizeof(*uh);
		coal_meta.trans_header = uh;
		/* Check for v4 zero checksum */
		if (coal_meta.ip_proto == 4 && !uh->check)
			zero_csum = true;
	} else {
		priv->stats.coal.coal_trans_invalid++;
		return;
	}

	if (rmnet_map_v5_csum_buggy(coal_hdr)) {
	if (rmnet_map_v5_csum_buggy(coal_hdr) && !zero_csum) {
		rmnet_map_move_headers(coal_skb);
		/* Mark as valid if it checks out */
		if (rmnet_map_validate_csum(coal_skb, &coal_meta))