diff mbox series

[v6,mptcp-next,03/22] Squash-to: "mptcp: generate the data checksum"

Message ID 6525941e117435c08f154b62bdfd10197169d36e.1620163861.git.pabeni@redhat.com
State Accepted, archived
Delegated to: Matthieu Baerts
Headers show
Series mptcp: data checksum support | expand

Commit Message

Paolo Abeni May 4, 2021, 9:41 p.m. UTC
We must generate the csum for zero window probe, too.

Do the csum update incrementally, to avoid multiple csum computation
when the data is appended to existing skb.

Note that in a later patch we will skip unneeded csum related
operation. Changes not included here to keep the delta small.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
v4 -> v5:
 - build the csum incrementally
 - pseudo hdr fields are in NBO/BE
 - must use len in NBO when updating the csum for data fin
---
 net/mptcp/options.c  |  3 +++
 net/mptcp/protocol.c | 29 ++++++++++++-----------------
 net/mptcp/protocol.h |  6 +++---
 3 files changed, 18 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 99fc21406168..beac01f58cba 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -519,6 +519,9 @@  static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
 		 */
 		ext->data_fin = 1;
 		ext->data_len++;
+
+		/* the pseudo header has changed, update the csum accordingly */
+		csum_replace2(&ext->csum, htons(ext->data_len - 1), htons(ext->data_len));
 	}
 }
 
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 2a094d35a099..f2874afca3ce 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1279,23 +1279,16 @@  static bool mptcp_alloc_tx_skb(struct sock *sk, struct sock *ssk)
 	return __mptcp_alloc_tx_skb(sk, ssk, sk->sk_allocation);
 }
 
-static __sum16 mptcp_generate_data_checksum(struct sk_buff *skb)
+/* note: this always recompute the csum on the whole skb, even
+ * if we just appended a single frag. More status info needed
+ */
+static void mptcp_update_data_checksum(struct sk_buff *skb, int added)
 {
-	struct csum_pseudo_header header;
-	struct mptcp_ext *mpext;
-	__wsum csum;
-
-	mpext = mptcp_get_ext(skb);
-
-	header.data_seq = mpext->data_seq;
-	header.subflow_seq = mpext->subflow_seq;
-	header.data_len = mpext->data_len;
-	header.csum = 0;
+	struct mptcp_ext *mpext = mptcp_get_ext(skb);
+	__wsum csum = csum_unfold(mpext->csum);
+	int offset = skb->len - added;
 
-	csum = skb_checksum(skb, 0, skb->len, 0);
-	csum = csum_partial(&header, sizeof(header), csum);
-
-	return csum_fold(csum);
+	mpext->csum = csum_fold(csum_block_add(csum, skb_checksum(skb, offset, added, 0), offset));
 }
 
 static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
@@ -1392,12 +1385,14 @@  static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 	if (zero_window_probe) {
 		mptcp_subflow_ctx(ssk)->rel_write_seq += ret;
 		mpext->frozen = 1;
-		ret = 0;
+		if (READ_ONCE(msk->csum_enabled))
+			mptcp_update_data_checksum(tail, ret);
 		tcp_push_pending_frames(ssk);
+		return 0;
 	}
 out:
 	if (READ_ONCE(msk->csum_enabled))
-		mpext->csum = mptcp_generate_data_checksum(tail);
+		mptcp_update_data_checksum(tail, ret);
 	mptcp_subflow_ctx(ssk)->rel_write_seq += ret;
 	return ret;
 }
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 63a1651f9069..236782702bfb 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -336,9 +336,9 @@  static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk)
 }
 
 struct csum_pseudo_header {
-	u64 data_seq;
-	u32 subflow_seq;
-	u16 data_len;
+	__be64 data_seq;
+	__be32 subflow_seq;
+	__be16 data_len;
 	__sum16 csum;
 };