mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [MPTCP][PATCH v2 mptcp-next 00/16] data checksum support
@ 2021-03-29 10:40 Geliang Tang
  2021-03-29 10:40 ` [MPTCP][PATCH v2 mptcp-next 01/16] mptcp: add csum_enabled in mptcp_sock Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

v2:
 - add the checksum support for MP_CAPABLE + data too.
 - validate the data that has been split in different skbs too.
 - add more patches.
 - tag: export/20210329T052816
 - patch 14 ("mptcp: add trace event for data checksum") depends on the
"add tracepoints" series.
 
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/134

Geliang Tang (16):
  mptcp: add csum_enabled in mptcp_sock
  mptcp: generate the data checksum
  mptcp: add csum_reqd in mptcp_out_options
  mptcp: send out checksum for MP_CAPABLE with data
  mptcp: send out checksum for DSS
  mptcp: add csum_reqd in mptcp_options_received
  mptcp: add sk parameter for mptcp_parse_option
  mptcp: receive checksum for MP_CAPABLE with data
  mptcp: receive checksum for DSS
  mptcp: validate the data checksum
  mptcp: add the mib for data checksum
  mptcp: add a new sysctl checksum_enabled
  mptcp: add mptcpi_csum_enabled in mptcp_info
  mptcp: add trace event for data checksum
  selftests: mptcp: enable checksum in mptcp_connect.sh
  selftests: mptcp: enable checksum in mptcp_join.sh

 Documentation/networking/mptcp-sysctl.rst     |   8 ++
 include/net/mptcp.h                           |   4 +-
 include/trace/events/mptcp.h                  |  38 ++++++
 include/uapi/linux/mptcp.h                    |   1 +
 net/mptcp/ctrl.c                              |  14 +++
 net/mptcp/mib.c                               |   1 +
 net/mptcp/mib.h                               |   1 +
 net/mptcp/mptcp_diag.c                        |   1 +
 net/mptcp/options.c                           | 112 +++++++++++++-----
 net/mptcp/protocol.c                          |  65 ++++++++++
 net/mptcp/protocol.h                          |  20 +++-
 net/mptcp/subflow.c                           |  20 ++--
 .../selftests/net/mptcp/mptcp_connect.sh      |  13 +-
 .../testing/selftests/net/mptcp/mptcp_join.sh |  40 ++++++-
 14 files changed, 294 insertions(+), 44 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 01/16] mptcp: add csum_enabled in mptcp_sock
  2021-03-29 10:40 [MPTCP][PATCH v2 mptcp-next 00/16] data checksum support Geliang Tang
@ 2021-03-29 10:40 ` Geliang Tang
  2021-03-29 10:40   ` [MPTCP][PATCH v2 mptcp-next 02/16] mptcp: generate the data checksum Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new member named csum_enabled in struct mptcp_sock,
used a dummy mptcp_is_checksum_enabled() helper to initialize it.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/protocol.c | 1 +
 net/mptcp/protocol.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 0265b8be0f84..56103814afed 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2368,6 +2368,7 @@ static int __mptcp_init_sock(struct sock *sk)
 	msk->ack_hint = NULL;
 	msk->first = NULL;
 	inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
+	WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
 
 	mptcp_pm_data_init(msk);
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 20770fe39ea5..826019bb2093 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -233,6 +233,7 @@ struct mptcp_sock {
 	bool		snd_data_fin_enable;
 	bool		rcv_fastclose;
 	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
+	bool		csum_enabled;
 	spinlock_t	join_list_lock;
 	struct sock	*ack_hint;
 	struct work_struct work;
@@ -519,6 +520,7 @@ static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *su
 
 int mptcp_is_enabled(struct net *net);
 unsigned int mptcp_get_add_addr_timeout(struct net *net);
+static inline int mptcp_is_checksum_enabled(struct net *net) { return false; }
 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
 				     struct mptcp_options_received *mp_opt);
 bool mptcp_subflow_data_available(struct sock *sk);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 02/16] mptcp: generate the data checksum
  2021-03-29 10:40 ` [MPTCP][PATCH v2 mptcp-next 01/16] mptcp: add csum_enabled in mptcp_sock Geliang Tang
@ 2021-03-29 10:40   ` Geliang Tang
  2021-03-29 10:40     ` [MPTCP][PATCH v2 mptcp-next 03/16] mptcp: add csum_reqd in mptcp_out_options Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch add a new member named csum in struct mptcp_ext, implemented a
new function named mptcp_generate_data_checksum().

Generate the data checksum in mptcp_sendmsg_frag, save it in mpext->csum.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 include/net/mptcp.h  |  1 +
 net/mptcp/protocol.c | 21 +++++++++++++++++++++
 net/mptcp/protocol.h |  7 +++++++
 3 files changed, 29 insertions(+)

diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 83f23774b908..23bbd439e115 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -23,6 +23,7 @@ struct mptcp_ext {
 	u64		data_seq;
 	u32		subflow_seq;
 	u16		data_len;
+	__sum16		csum;
 	u8		use_map:1,
 			dsn64:1,
 			data_fin:1,
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 56103814afed..b053f92a8ee1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1254,6 +1254,25 @@ 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)
+{
+	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;
+
+	csum = skb_checksum(skb, 0, skb->len, 0);
+	csum = csum_partial(&header, sizeof(header), csum);
+
+	return csum_fold(csum);
+}
+
 static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 			      struct mptcp_data_frag *dfrag,
 			      struct mptcp_sendmsg_info *info)
@@ -1352,6 +1371,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 		tcp_push_pending_frames(ssk);
 	}
 out:
+	if (READ_ONCE(msk->csum_enabled))
+		mpext->csum = mptcp_generate_data_checksum(tail);
 	mptcp_subflow_ctx(ssk)->rel_write_seq += ret;
 	return ret;
 }
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 826019bb2093..b13b95cedb5e 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -332,6 +332,13 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk)
 	return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
 }
 
+struct csum_pseudo_header {
+	u64 data_seq;
+	u32 subflow_seq;
+	u16 data_len;
+	__sum16 csum;
+};
+
 struct mptcp_subflow_request_sock {
 	struct	tcp_request_sock sk;
 	u16	mp_capable : 1,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 03/16] mptcp: add csum_reqd in mptcp_out_options
  2021-03-29 10:40   ` [MPTCP][PATCH v2 mptcp-next 02/16] mptcp: generate the data checksum Geliang Tang
@ 2021-03-29 10:40     ` Geliang Tang
  2021-03-29 10:40       ` [MPTCP][PATCH v2 mptcp-next 04/16] mptcp: send out checksum for MP_CAPABLE with data Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new member csum_reqd in struct mptcp_out_options and
struct mptcp_subflow_request_sock. Initialized it with the helper
function mptcp_is_checksum_enabled().

In mptcp_write_options, if this field is enabled, send out the MP_CAPABLE
suboption with the MPTCP_CAP_CHECKSUM_REQD flag.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 include/net/mptcp.h  |  3 ++-
 net/mptcp/options.c  | 10 ++++++++--
 net/mptcp/protocol.h |  3 ++-
 net/mptcp/subflow.c  |  1 +
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 23bbd439e115..8f86c05ddbfd 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -65,7 +65,8 @@ struct mptcp_out_options {
 	u8 join_id;
 	u8 backup;
 	u8 reset_reason:4;
-	u8 reset_transient:1;
+	u8 reset_transient:1,
+	   csum_reqd:1;
 	u32 nonce;
 	u64 thmac;
 	u32 token;
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 87bd1bfde964..c57b2a03b756 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -381,6 +381,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
 	subflow->snd_isn = TCP_SKB_CB(skb)->end_seq;
 	if (subflow->request_mptcp) {
 		opts->suboptions = OPTION_MPTCP_MPC_SYN;
+		opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
 		*size = TCPOLEN_MPTCP_MPC_SYN;
 		return true;
 	} else if (subflow->request_join) {
@@ -466,6 +467,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 		opts->suboptions = OPTION_MPTCP_MPC_ACK;
 		opts->sndr_key = subflow->local_key;
 		opts->rcvr_key = subflow->remote_key;
+		opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
 
 		/* Section 3.1.
 		 * The MP_CAPABLE option is carried on the SYN, SYN/ACK, and ACK
@@ -789,6 +791,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
 	if (subflow_req->mp_capable) {
 		opts->suboptions = OPTION_MPTCP_MPC_SYNACK;
 		opts->sndr_key = subflow_req->local_key;
+		opts->csum_reqd = subflow_req->csum_reqd;
 		*size = TCPOLEN_MPTCP_MPC_SYNACK;
 		pr_debug("subflow_req=%p, local_key=%llu",
 			 subflow_req, subflow_req->local_key);
@@ -1120,7 +1123,7 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 {
 	if ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK |
 	     OPTION_MPTCP_MPC_ACK) & opts->suboptions) {
-		u8 len;
+		u8 len, flag = MPTCP_CAP_HMAC_SHA256;
 
 		if (OPTION_MPTCP_MPC_SYN & opts->suboptions)
 			len = TCPOLEN_MPTCP_MPC_SYN;
@@ -1131,9 +1134,12 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 		else
 			len = TCPOLEN_MPTCP_MPC_ACK;
 
+		if (opts->csum_reqd)
+			flag |= MPTCP_CAP_CHECKSUM_REQD;
+
 		*ptr++ = mptcp_option(MPTCPOPT_MP_CAPABLE, len,
 				      MPTCP_SUPPORTED_VERSION,
-				      MPTCP_CAP_HMAC_SHA256);
+				      flag);
 
 		if (!((OPTION_MPTCP_MPC_SYNACK | OPTION_MPTCP_MPC_ACK) &
 		    opts->suboptions))
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index b13b95cedb5e..e5cbf5153d8f 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -343,7 +343,8 @@ struct mptcp_subflow_request_sock {
 	struct	tcp_request_sock sk;
 	u16	mp_capable : 1,
 		mp_join : 1,
-		backup : 1;
+		backup : 1,
+		csum_reqd : 1;
 	u8	local_id;
 	u8	remote_id;
 	u64	local_key;
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index d79a99c2bfc4..010e2fec5189 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -108,6 +108,7 @@ static void subflow_init_req(struct request_sock *req, const struct sock *sk_lis
 
 	subflow_req->mp_capable = 0;
 	subflow_req->mp_join = 0;
+	subflow_req->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk_listener));
 	subflow_req->msk = NULL;
 	mptcp_token_init_request(req);
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 04/16] mptcp: send out checksum for MP_CAPABLE with data
  2021-03-29 10:40     ` [MPTCP][PATCH v2 mptcp-next 03/16] mptcp: add csum_reqd in mptcp_out_options Geliang Tang
@ 2021-03-29 10:40       ` Geliang Tang
  2021-03-29 10:40         ` [MPTCP][PATCH v2 mptcp-next 05/16] mptcp: send out checksum for DSS Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

If the checksum is enabled, send out the data checksum with the
MP_CAPABLE suboption with data.

In mptcp_established_options_mp, save the data checksum in
opts->ext_copy.csum. In mptcp_write_options, adjust the option length and
send it out with the MP_CAPABLE suboption.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index c57b2a03b756..1ea41f9f05f3 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -439,6 +439,8 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
 	struct mptcp_ext *mpext;
 	unsigned int data_len;
+	__sum16 csum;
+	u8 len;
 
 	/* When skb is not available, we better over-estimate the emitted
 	 * options len. A full DSS option (28 bytes) is longer than
@@ -458,6 +460,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 	if (subflow->mp_capable) {
 		mpext = mptcp_get_ext(skb);
 		data_len = mpext ? mpext->data_len : 0;
+		csum = mpext ? mpext->csum : 0;
 
 		/* we will check ext_copy.data_len in mptcp_write_options() to
 		 * discriminate between TCPOLEN_MPTCP_MPC_ACK_DATA and
@@ -468,16 +471,22 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 		opts->sndr_key = subflow->local_key;
 		opts->rcvr_key = subflow->remote_key;
 		opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
+		if (opts->csum_reqd)
+			opts->ext_copy.csum = csum;
 
 		/* Section 3.1.
 		 * The MP_CAPABLE option is carried on the SYN, SYN/ACK, and ACK
 		 * packets that start the first subflow of an MPTCP connection,
 		 * as well as the first packet that carries data
 		 */
-		if (data_len > 0)
-			*size = ALIGN(TCPOLEN_MPTCP_MPC_ACK_DATA, 4);
-		else
+		if (data_len > 0) {
+			len = TCPOLEN_MPTCP_MPC_ACK_DATA;
+			if (opts->csum_reqd)
+				len += TCPOLEN_MPTCP_DSS_CHECKSUM;
+			*size = ALIGN(len, 4);
+		} else {
 			*size = TCPOLEN_MPTCP_MPC_ACK;
+		}
 
 		pr_debug("subflow=%p, local_key=%llu, remote_key=%llu map_len=%d",
 			 subflow, subflow->local_key, subflow->remote_key,
@@ -1125,14 +1134,17 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 	     OPTION_MPTCP_MPC_ACK) & opts->suboptions) {
 		u8 len, flag = MPTCP_CAP_HMAC_SHA256;
 
-		if (OPTION_MPTCP_MPC_SYN & opts->suboptions)
+		if (OPTION_MPTCP_MPC_SYN & opts->suboptions) {
 			len = TCPOLEN_MPTCP_MPC_SYN;
-		else if (OPTION_MPTCP_MPC_SYNACK & opts->suboptions)
+		} else if (OPTION_MPTCP_MPC_SYNACK & opts->suboptions) {
 			len = TCPOLEN_MPTCP_MPC_SYNACK;
-		else if (opts->ext_copy.data_len)
+		} else if (opts->ext_copy.data_len) {
 			len = TCPOLEN_MPTCP_MPC_ACK_DATA;
-		else
+			if (opts->csum_reqd)
+				len += TCPOLEN_MPTCP_DSS_CHECKSUM;
+		} else {
 			len = TCPOLEN_MPTCP_MPC_ACK;
+		}
 
 		if (opts->csum_reqd)
 			flag |= MPTCP_CAP_CHECKSUM_REQD;
@@ -1155,8 +1167,13 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 		if (!opts->ext_copy.data_len)
 			goto mp_capable_done;
 
-		put_unaligned_be32(opts->ext_copy.data_len << 16 |
-				   TCPOPT_NOP << 8 | TCPOPT_NOP, ptr);
+		if (opts->csum_reqd) {
+			put_unaligned_be32(opts->ext_copy.data_len << 16 |
+					   (__force u16)opts->ext_copy.csum, ptr);
+		} else {
+			put_unaligned_be32(opts->ext_copy.data_len << 16 |
+					   TCPOPT_NOP << 8 | TCPOPT_NOP, ptr);
+		}
 		ptr += 1;
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 05/16] mptcp: send out checksum for DSS
  2021-03-29 10:40       ` [MPTCP][PATCH v2 mptcp-next 04/16] mptcp: send out checksum for MP_CAPABLE with data Geliang Tang
@ 2021-03-29 10:40         ` Geliang Tang
  2021-03-29 10:40           ` [MPTCP][PATCH v2 mptcp-next 06/16] mptcp: add csum_reqd in mptcp_options_received Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

In mptcp_write_options, If the checksum is enabled, adjust the option
length and send out the data checksum with DSS suboption.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 1ea41f9f05f3..0f9abe8ea7cd 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -547,6 +547,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
 	bool ret = false;
 	u64 ack_seq;
 
+	opts->csum_reqd = READ_ONCE(msk->csum_enabled);
 	mpext = skb ? mptcp_get_ext(skb) : NULL;
 
 	if (!skb || (mpext && mpext->use_map) || snd_data_fin_enable) {
@@ -1325,6 +1326,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 			flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64;
 			if (mpext->data_fin)
 				flags |= MPTCP_DSS_DATA_FIN;
+
+			if (opts->csum_reqd)
+				len += TCPOLEN_MPTCP_DSS_CHECKSUM;
 		}
 
 		*ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags);
@@ -1344,8 +1348,13 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 			ptr += 2;
 			put_unaligned_be32(mpext->subflow_seq, ptr);
 			ptr += 1;
-			put_unaligned_be32(mpext->data_len << 16 |
-					   TCPOPT_NOP << 8 | TCPOPT_NOP, ptr);
+			if (opts->csum_reqd) {
+				put_unaligned_be32(mpext->data_len << 16 |
+						   (__force u16)mpext->csum, ptr);
+			} else {
+				put_unaligned_be32(mpext->data_len << 16 |
+						   TCPOPT_NOP << 8 | TCPOPT_NOP, ptr);
+			}
 		}
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 06/16] mptcp: add csum_reqd in mptcp_options_received
  2021-03-29 10:40         ` [MPTCP][PATCH v2 mptcp-next 05/16] mptcp: send out checksum for DSS Geliang Tang
@ 2021-03-29 10:40           ` Geliang Tang
  2021-03-29 10:40             ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new flag csum_reqd in struct mptcp_options_received, if
the flag MPTCP_CAP_CHECKSUM_REQD is set in the receiving MP_CAPABLE
suboption, set this flag.

In mptcp_sk_clone and subflow_finish_connect, if the flag csum_reqd is set,
set the flag msk->csum_enabled to true.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c  | 5 ++---
 net/mptcp/protocol.c | 2 ++
 net/mptcp/protocol.h | 1 +
 net/mptcp/subflow.c  | 2 ++
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 0f9abe8ea7cd..6acb7469bae9 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -71,11 +71,9 @@ static void mptcp_parse_option(const struct sk_buff *skb,
 		 * "If a checksum is not present when its use has been
 		 * negotiated, the receiver MUST close the subflow with a RST as
 		 * it is considered broken."
-		 *
-		 * We don't implement DSS checksum - fall back to TCP.
 		 */
 		if (flags & MPTCP_CAP_CHECKSUM_REQD)
-			break;
+			mp_opt->csum_reqd = 1;
 
 		mp_opt->mp_capable = 1;
 		if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) {
@@ -342,6 +340,7 @@ void mptcp_get_options(const struct sk_buff *skb,
 	mp_opt->dss = 0;
 	mp_opt->mp_prio = 0;
 	mp_opt->reset = 0;
+	mp_opt->csum_reqd = 0;
 
 	length = (th->doff * 4) - sizeof(struct tcphdr);
 	ptr = (const unsigned char *)(th + 1);
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index b053f92a8ee1..436969d95e36 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2718,6 +2718,8 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
 	msk->token = subflow_req->token;
 	msk->subflow = NULL;
 	WRITE_ONCE(msk->fully_established, false);
+	if (mp_opt->csum_reqd)
+		WRITE_ONCE(msk->csum_enabled, true);
 
 	msk->write_seq = subflow_req->idsn + 1;
 	msk->snd_nxt = msk->write_seq;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index e5cbf5153d8f..ae7d47352d09 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -132,6 +132,7 @@ struct mptcp_options_received {
 		rm_addr : 1,
 		mp_prio : 1,
 		echo : 1,
+		csum_reqd : 1,
 		backup : 1;
 	u32	token;
 	u32	nonce;
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 010e2fec5189..cbdfa5a6f8f6 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -405,6 +405,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
 			goto fallback;
 		}
 
+		if (mp_opt.csum_reqd)
+			WRITE_ONCE(mptcp_sk(parent)->csum_enabled, true);
 		subflow->mp_capable = 1;
 		subflow->can_ack = 1;
 		subflow->remote_key = mp_opt.sndr_key;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option
  2021-03-29 10:40           ` [MPTCP][PATCH v2 mptcp-next 06/16] mptcp: add csum_reqd in mptcp_options_received Geliang Tang
@ 2021-03-29 10:40             ` Geliang Tang
  2021-03-29 10:40               ` [MPTCP][PATCH v2 mptcp-next 08/16] mptcp: receive checksum for MP_CAPABLE with data Geliang Tang
  2021-03-30  0:15               ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Mat Martineau
  0 siblings, 2 replies; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new parameter name sk in mptcp_parse_option() and
mptcp_get_options().

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c  | 10 ++++++----
 net/mptcp/protocol.h |  3 ++-
 net/mptcp/subflow.c  | 10 +++++-----
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 6acb7469bae9..cb423cba5c3b 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -20,7 +20,8 @@ static bool mptcp_cap_flag_sha256(u8 flags)
 	return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256;
 }
 
-static void mptcp_parse_option(const struct sk_buff *skb,
+static void mptcp_parse_option(const struct sock *sk,
+			       const struct sk_buff *skb,
 			       const unsigned char *ptr, int opsize,
 			       struct mptcp_options_received *mp_opt)
 {
@@ -322,7 +323,8 @@ static void mptcp_parse_option(const struct sk_buff *skb,
 	}
 }
 
-void mptcp_get_options(const struct sk_buff *skb,
+void mptcp_get_options(const struct sock *sk,
+		       const struct sk_buff *skb,
 		       struct mptcp_options_received *mp_opt)
 {
 	const struct tcphdr *th = tcp_hdr(skb);
@@ -362,7 +364,7 @@ void mptcp_get_options(const struct sk_buff *skb,
 			if (opsize > length)
 				return;	/* don't parse partial options */
 			if (opcode == TCPOPT_MPTCP)
-				mptcp_parse_option(skb, ptr, opsize, mp_opt);
+				mptcp_parse_option(sk, skb, ptr, opsize, mp_opt);
 			ptr += opsize - 2;
 			length -= opsize;
 		}
@@ -1016,7 +1018,7 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 		return;
 	}
 
-	mptcp_get_options(skb, &mp_opt);
+	mptcp_get_options(sk, skb, &mp_opt);
 	if (!check_fully_established(msk, sk, subflow, skb, &mp_opt))
 		return;
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index ae7d47352d09..cfdecfb90776 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -570,7 +570,8 @@ int __init mptcp_proto_v6_init(void);
 struct sock *mptcp_sk_clone(const struct sock *sk,
 			    const struct mptcp_options_received *mp_opt,
 			    struct request_sock *req);
-void mptcp_get_options(const struct sk_buff *skb,
+void mptcp_get_options(const struct sock *sk,
+		       const struct sk_buff *skb,
 		       struct mptcp_options_received *mp_opt);
 
 void mptcp_finish_connect(struct sock *sk);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index cbdfa5a6f8f6..75664da251a6 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -151,7 +151,7 @@ static int subflow_check_req(struct request_sock *req,
 		return -EINVAL;
 #endif
 
-	mptcp_get_options(skb, &mp_opt);
+	mptcp_get_options(sk_listener, skb, &mp_opt);
 
 	if (mp_opt.mp_capable) {
 		SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
@@ -248,7 +248,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
 	int err;
 
 	subflow_init_req(req, sk_listener);
-	mptcp_get_options(skb, &mp_opt);
+	mptcp_get_options(sk_listener, skb, &mp_opt);
 
 	if (mp_opt.mp_capable && mp_opt.mp_join)
 		return -EINVAL;
@@ -395,7 +395,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
 	subflow->ssn_offset = TCP_SKB_CB(skb)->seq;
 	pr_debug("subflow=%p synack seq=%x", subflow, subflow->ssn_offset);
 
-	mptcp_get_options(skb, &mp_opt);
+	mptcp_get_options(sk, skb, &mp_opt);
 	if (subflow->request_mptcp) {
 		if (!mp_opt.mp_capable) {
 			MPTCP_INC_STATS(sock_net(sk),
@@ -642,7 +642,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 			goto create_msk;
 		}
 
-		mptcp_get_options(skb, &mp_opt);
+		mptcp_get_options(sk, skb, &mp_opt);
 		if (!mp_opt.mp_capable) {
 			fallback = true;
 			goto create_child;
@@ -653,7 +653,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 		if (!new_msk)
 			fallback = true;
 	} else if (subflow_req->mp_join) {
-		mptcp_get_options(skb, &mp_opt);
+		mptcp_get_options(sk, skb, &mp_opt);
 		if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) ||
 		    !mptcp_can_accept_new_subflow(subflow_req->msk)) {
 			SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 08/16] mptcp: receive checksum for MP_CAPABLE with data
  2021-03-29 10:40             ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Geliang Tang
@ 2021-03-29 10:40               ` Geliang Tang
  2021-03-29 10:40                 ` [MPTCP][PATCH v2 mptcp-next 09/16] mptcp: receive checksum for DSS Geliang Tang
  2021-03-30  0:15               ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Mat Martineau
  1 sibling, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new member named csum in struct mptcp_options_received.

When parsing the MP_CAPABLE with data, if the checksum is enabled,
adjust the expected_opsize. If the receiving option length matches the
length with the data checksum, get the checksum value and save it in
mp_opt->csum. And in mptcp_incoming_options, pass it to mpext->csum.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c  | 23 ++++++++++++++++++-----
 net/mptcp/protocol.h |  1 +
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index cb423cba5c3b..e3a28633ac2c 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -25,6 +25,8 @@ static void mptcp_parse_option(const struct sock *sk,
 			       const unsigned char *ptr, int opsize,
 			       struct mptcp_options_received *mp_opt)
 {
+	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
 	u8 subtype = *ptr >> 4;
 	int expected_opsize;
 	u8 version;
@@ -35,10 +37,13 @@ static void mptcp_parse_option(const struct sock *sk,
 	case MPTCPOPT_MP_CAPABLE:
 		/* strict size checking */
 		if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) {
-			if (skb->len > tcp_hdr(skb)->doff << 2)
+			if (skb->len > tcp_hdr(skb)->doff << 2) {
 				expected_opsize = TCPOLEN_MPTCP_MPC_ACK_DATA;
-			else
+				if (READ_ONCE(msk->csum_enabled))
+					expected_opsize += TCPOLEN_MPTCP_DSS_CHECKSUM;
+			} else {
 				expected_opsize = TCPOLEN_MPTCP_MPC_ACK;
+			}
 		} else {
 			if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)
 				expected_opsize = TCPOLEN_MPTCP_MPC_SYNACK;
@@ -85,7 +90,7 @@ static void mptcp_parse_option(const struct sock *sk,
 			mp_opt->rcvr_key = get_unaligned_be64(ptr);
 			ptr += 8;
 		}
-		if (opsize == TCPOLEN_MPTCP_MPC_ACK_DATA) {
+		if (opsize >= TCPOLEN_MPTCP_MPC_ACK_DATA) {
 			/* Section 3.1.:
 			 * "the data parameters in a MP_CAPABLE are semantically
 			 * equivalent to those in a DSS option and can be used
@@ -97,9 +102,13 @@ static void mptcp_parse_option(const struct sock *sk,
 			mp_opt->data_len = get_unaligned_be16(ptr);
 			ptr += 2;
 		}
-		pr_debug("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d",
+		if (opsize == TCPOLEN_MPTCP_MPC_ACK_DATA + TCPOLEN_MPTCP_DSS_CHECKSUM) {
+			mp_opt->csum = (__force __sum16)get_unaligned_be16(ptr);
+			ptr += 2;
+		}
+		pr_debug("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d csum=%u",
 			 version, flags, opsize, mp_opt->sndr_key,
-			 mp_opt->rcvr_key, mp_opt->data_len);
+			 mp_opt->rcvr_key, mp_opt->data_len, mp_opt->csum);
 		break;
 
 	case MPTCPOPT_MP_JOIN:
@@ -343,6 +352,7 @@ void mptcp_get_options(const struct sock *sk,
 	mp_opt->mp_prio = 0;
 	mp_opt->reset = 0;
 	mp_opt->csum_reqd = 0;
+	mp_opt->csum = 0;
 
 	length = (th->doff * 4) - sizeof(struct tcphdr);
 	ptr = (const unsigned char *)(th + 1);
@@ -1110,6 +1120,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 		}
 		mpext->data_len = mp_opt.data_len;
 		mpext->use_map = 1;
+
+		if (READ_ONCE(msk->csum_enabled))
+			mpext->csum = mp_opt.csum;
 	}
 }
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index cfdecfb90776..6be10ebabcd5 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -123,6 +123,7 @@ struct mptcp_options_received {
 	u64	data_seq;
 	u32	subflow_seq;
 	u16	data_len;
+	__sum16	csum;
 	u16	mp_capable : 1,
 		mp_join : 1,
 		fastclose : 1,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 09/16] mptcp: receive checksum for DSS
  2021-03-29 10:40               ` [MPTCP][PATCH v2 mptcp-next 08/16] mptcp: receive checksum for MP_CAPABLE with data Geliang Tang
@ 2021-03-29 10:40                 ` Geliang Tang
  2021-03-29 10:40                   ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

In mptcp_parse_option, adjust the expected_opsize, and parse the data
checksum value from the receiving DSS, then save it in mp_opt->csum.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index e3a28633ac2c..4646947dea45 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -158,6 +158,7 @@ static void mptcp_parse_option(const struct sock *sk,
 		mp_opt->use_map = (flags & MPTCP_DSS_HAS_MAP) != 0;
 		mp_opt->ack64 = (flags & MPTCP_DSS_ACK64) != 0;
 		mp_opt->use_ack = (flags & MPTCP_DSS_HAS_ACK);
+		mp_opt->csum_reqd = READ_ONCE(msk->csum_enabled);
 
 		pr_debug("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d",
 			 mp_opt->data_fin, mp_opt->dsn64,
@@ -178,6 +179,9 @@ static void mptcp_parse_option(const struct sock *sk,
 				expected_opsize += TCPOLEN_MPTCP_DSS_MAP64;
 			else
 				expected_opsize += TCPOLEN_MPTCP_DSS_MAP32;
+
+			if (mp_opt->csum_reqd)
+				expected_opsize += TCPOLEN_MPTCP_DSS_CHECKSUM;
 		}
 
 		/* RFC 6824, Section 3.3:
@@ -185,8 +189,7 @@ static void mptcp_parse_option(const struct sock *sk,
 		 * not been negotiated in the MP_CAPABLE handshake,
 		 * the checksum field MUST be ignored.
 		 */
-		if (opsize != expected_opsize &&
-		    opsize != expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM)
+		if (opsize != expected_opsize)
 			break;
 
 		mp_opt->dss = 1;
@@ -218,9 +221,14 @@ static void mptcp_parse_option(const struct sock *sk,
 			mp_opt->data_len = get_unaligned_be16(ptr);
 			ptr += 2;
 
-			pr_debug("data_seq=%llu subflow_seq=%u data_len=%u",
+			if (mp_opt->csum_reqd) {
+				mp_opt->csum = (__force __sum16)get_unaligned_be16(ptr);
+				ptr += 2;
+			}
+
+			pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u",
 				 mp_opt->data_seq, mp_opt->subflow_seq,
-				 mp_opt->data_len);
+				 mp_opt->data_len, mp_opt->csum);
 		}
 
 		break;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum
  2021-03-29 10:40                 ` [MPTCP][PATCH v2 mptcp-next 09/16] mptcp: receive checksum for DSS Geliang Tang
@ 2021-03-29 10:40                   ` Geliang Tang
  2021-03-29 10:40                     ` [MPTCP][PATCH v2 mptcp-next 11/16] mptcp: add the mib for " Geliang Tang
  2021-03-30  0:40                     ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Mat Martineau
  0 siblings, 2 replies; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch add three new members named data_csum, csum_len and map_csum in
struct mptcp_subflow_context, implemented a new function named
mptcp_validate_data_checksum(). Validate the data checksum in the function
__mptcp_move_skbs_from_subflow.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/protocol.c | 35 +++++++++++++++++++++++++++++++++++
 net/mptcp/protocol.h |  3 +++
 net/mptcp/subflow.c  |  7 +++++--
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 436969d95e36..0b4ab35e234a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -532,6 +532,35 @@ static bool mptcp_check_data_fin(struct sock *sk)
 	return ret;
 }
 
+static bool mptcp_validate_data_checksum(struct sock *ssk)
+{
+	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+	struct csum_pseudo_header header;
+	__wsum csum;
+
+	if (__mptcp_check_fallback(msk))
+		goto out;
+
+	if (subflow->csum_len < subflow->map_data_len)
+		goto out;
+
+	header.data_seq = subflow->map_seq;
+	header.subflow_seq = subflow->map_subflow_seq;
+	header.data_len = subflow->map_data_len;
+	header.csum = subflow->map_csum;
+
+	csum = csum_partial(&header, sizeof(header), subflow->data_csum);
+
+	if (csum_fold(csum))
+		return false;
+	subflow->data_csum = 0;
+	subflow->csum_len = 0;
+
+out:
+	return true;
+}
+
 static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
 					   struct sock *ssk,
 					   unsigned int *bytes)
@@ -600,6 +629,12 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
 			if (tp->urg_data)
 				done = true;
 
+			if (READ_ONCE(msk->csum_enabled)) {
+				subflow->data_csum = skb_checksum(skb, offset, len,
+								  subflow->data_csum);
+				subflow->csum_len += len;
+				mptcp_validate_data_checksum(ssk);
+			}
 			if (__mptcp_move_skb(msk, ssk, skb, offset, len))
 				moved += len;
 			seq += len;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 6be10ebabcd5..d4bf264d16cc 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -394,6 +394,9 @@ struct mptcp_subflow_context {
 	u32	map_subflow_seq;
 	u32	ssn_offset;
 	u32	map_data_len;
+	__wsum	data_csum;
+	u32	csum_len;
+	__sum16	map_csum;
 	u32	request_mptcp : 1,  /* send MP_CAPABLE */
 		request_join : 1,   /* send MP_JOIN */
 		request_bkup : 1,
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 75664da251a6..df7ad478bb2e 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -944,9 +944,12 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
 	subflow->map_data_len = data_len;
 	subflow->map_valid = 1;
 	subflow->mpc_map = mpext->mpc_map;
-	pr_debug("new map seq=%llu subflow_seq=%u data_len=%u",
+	subflow->data_csum = 0;
+	subflow->csum_len = 0;
+	subflow->map_csum = mpext->csum;
+	pr_debug("new map seq=%llu subflow_seq=%u data_len=%u csum=%u",
 		 subflow->map_seq, subflow->map_subflow_seq,
-		 subflow->map_data_len);
+		 subflow->map_data_len, subflow->map_csum);
 
 validate_seq:
 	/* we revalidate valid mapping on new skb, because we must ensure
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 11/16] mptcp: add the mib for data checksum
  2021-03-29 10:40                   ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Geliang Tang
@ 2021-03-29 10:40                     ` Geliang Tang
  2021-03-29 10:40                       ` [MPTCP][PATCH v2 mptcp-next 12/16] mptcp: add a new sysctl checksum_enabled Geliang Tang
  2021-03-30  0:40                     ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Mat Martineau
  1 sibling, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added the mib for the data checksum, MPTCP_MIB_DSSCSUMERR.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/mib.c      | 1 +
 net/mptcp/mib.h      | 1 +
 net/mptcp/protocol.c | 4 +++-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
index eb2dc6dbe212..c7042e3317b5 100644
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -25,6 +25,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
 	SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
 	SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
 	SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
+	SNMP_MIB_ITEM("DSSCsumErr", MPTCP_MIB_DSSCSUMERR),
 	SNMP_MIB_ITEM("OFOQueueTail", MPTCP_MIB_OFOQUEUETAIL),
 	SNMP_MIB_ITEM("OFOQueue", MPTCP_MIB_OFOQUEUE),
 	SNMP_MIB_ITEM("OFOMerge", MPTCP_MIB_OFOMERGE),
diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
index f0da4f060fe1..c407358eced8 100644
--- a/net/mptcp/mib.h
+++ b/net/mptcp/mib.h
@@ -18,6 +18,7 @@ enum linux_mptcp_mib_field {
 	MPTCP_MIB_JOINACKMAC,		/* HMAC was wrong on ACK + MP_JOIN */
 	MPTCP_MIB_DSSNOMATCH,		/* Received a new mapping that did not match the previous one */
 	MPTCP_MIB_INFINITEMAPRX,	/* Received an infinite mapping */
+	MPTCP_MIB_DSSCSUMERR,		/* The DSS checksum fail */
 	MPTCP_MIB_OFOQUEUETAIL,	/* Segments inserted into OoO queue tail */
 	MPTCP_MIB_OFOQUEUE,		/* Segments inserted into OoO queue */
 	MPTCP_MIB_OFOMERGE,		/* Segments merged in OoO queue */
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 0b4ab35e234a..e414ff940727 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -552,8 +552,10 @@ static bool mptcp_validate_data_checksum(struct sock *ssk)
 
 	csum = csum_partial(&header, sizeof(header), subflow->data_csum);
 
-	if (csum_fold(csum))
+	if (csum_fold(csum)) {
+		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCSUMERR);
 		return false;
+	}
 	subflow->data_csum = 0;
 	subflow->csum_len = 0;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 12/16] mptcp: add a new sysctl checksum_enabled
  2021-03-29 10:40                     ` [MPTCP][PATCH v2 mptcp-next 11/16] mptcp: add the mib for " Geliang Tang
@ 2021-03-29 10:40                       ` Geliang Tang
  2021-03-29 10:40                         ` [MPTCP][PATCH v2 mptcp-next 13/16] mptcp: add mptcpi_csum_enabled in mptcp_info Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new sysctl, named checksum_enabled, to control
whether DSS checksum can be enabled.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 Documentation/networking/mptcp-sysctl.rst |  8 ++++++++
 net/mptcp/ctrl.c                          | 14 ++++++++++++++
 net/mptcp/protocol.h                      |  2 +-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst
index 6af0196c4297..566ec0e4a3da 100644
--- a/Documentation/networking/mptcp-sysctl.rst
+++ b/Documentation/networking/mptcp-sysctl.rst
@@ -24,3 +24,11 @@ add_addr_timeout - INTEGER (seconds)
 	sysctl.
 
 	Default: 120
+
+checksum_enabled - INTEGER
+	Control whether DSS checksum can be enabled.
+
+	DSS checksum can be enabled if the value is nonzero. This is a
+	per-namespace sysctl.
+
+	Default: 0
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index 96ba616f59bf..857e371c108c 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -19,6 +19,7 @@ struct mptcp_pernet {
 
 	int mptcp_enabled;
 	unsigned int add_addr_timeout;
+	int checksum_enabled;
 };
 
 static struct mptcp_pernet *mptcp_get_pernet(struct net *net)
@@ -36,6 +37,11 @@ unsigned int mptcp_get_add_addr_timeout(struct net *net)
 	return mptcp_get_pernet(net)->add_addr_timeout;
 }
 
+int mptcp_is_checksum_enabled(struct net *net)
+{
+	return mptcp_get_pernet(net)->checksum_enabled;
+}
+
 static struct ctl_table mptcp_sysctl_table[] = {
 	{
 		.procname = "enabled",
@@ -52,6 +58,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
 		.mode = 0644,
 		.proc_handler = proc_dointvec_jiffies,
 	},
+	{
+		.procname = "checksum_enabled",
+		.maxlen = sizeof(int),
+		.mode = 0644,
+		.proc_handler = proc_dointvec,
+	},
 	{}
 };
 
@@ -59,6 +71,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
 {
 	pernet->mptcp_enabled = 1;
 	pernet->add_addr_timeout = TCP_RTO_MAX;
+	pernet->checksum_enabled = 0;
 }
 
 static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
@@ -75,6 +88,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
 
 	table[0].data = &pernet->mptcp_enabled;
 	table[1].data = &pernet->add_addr_timeout;
+	table[2].data = &pernet->checksum_enabled;
 
 	hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
 	if (!hdr)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index d4bf264d16cc..a7b60710dc8e 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -533,7 +533,7 @@ static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *su
 
 int mptcp_is_enabled(struct net *net);
 unsigned int mptcp_get_add_addr_timeout(struct net *net);
-static inline int mptcp_is_checksum_enabled(struct net *net) { return false; }
+int mptcp_is_checksum_enabled(struct net *net);
 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
 				     struct mptcp_options_received *mp_opt);
 bool mptcp_subflow_data_available(struct sock *sk);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 13/16] mptcp: add mptcpi_csum_enabled in mptcp_info
  2021-03-29 10:40                       ` [MPTCP][PATCH v2 mptcp-next 12/16] mptcp: add a new sysctl checksum_enabled Geliang Tang
@ 2021-03-29 10:40                         ` Geliang Tang
  2021-03-29 10:40                           ` [MPTCP][PATCH v2 mptcp-next 14/16] mptcp: add trace event for data checksum Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added mptcpi_csum_enabled in struct mptcp_info to expose the
msk->csum_enabled.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 include/uapi/linux/mptcp.h | 1 +
 net/mptcp/mptcp_diag.c     | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h
index 8eb3c0844bff..7b05f7102321 100644
--- a/include/uapi/linux/mptcp.h
+++ b/include/uapi/linux/mptcp.h
@@ -105,6 +105,7 @@ struct mptcp_info {
 	__u64	mptcpi_rcv_nxt;
 	__u8	mptcpi_local_addr_used;
 	__u8	mptcpi_local_addr_max;
+	__u8	mptcpi_csum_enabled;
 };
 
 /*
diff --git a/net/mptcp/mptcp_diag.c b/net/mptcp/mptcp_diag.c
index f16d9b5ee978..8f88ddeab6a2 100644
--- a/net/mptcp/mptcp_diag.c
+++ b/net/mptcp/mptcp_diag.c
@@ -144,6 +144,7 @@ static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 	info->mptcpi_write_seq = READ_ONCE(msk->write_seq);
 	info->mptcpi_snd_una = READ_ONCE(msk->snd_una);
 	info->mptcpi_rcv_nxt = READ_ONCE(msk->ack_seq);
+	info->mptcpi_csum_enabled = READ_ONCE(msk->csum_enabled);
 	unlock_sock_fast(sk, slow);
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 14/16] mptcp: add trace event for data checksum
  2021-03-29 10:40                         ` [MPTCP][PATCH v2 mptcp-next 13/16] mptcp: add mptcpi_csum_enabled in mptcp_info Geliang Tang
@ 2021-03-29 10:40                           ` Geliang Tang
  2021-03-29 10:40                             ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Geliang Tang
  0 siblings, 1 reply; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added the trace event for the data checksum. Add the tracepoints
in mptcp_generate_data_checksum and mptcp_validate_data_checksum.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 include/trace/events/mptcp.h | 38 ++++++++++++++++++++++++++++++++++++
 net/mptcp/protocol.c         |  4 ++++
 2 files changed, 42 insertions(+)

diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h
index 5571c45c61f2..ebfcc1a6fe3d 100644
--- a/include/trace/events/mptcp.h
+++ b/include/trace/events/mptcp.h
@@ -145,6 +145,44 @@ TRACE_EVENT(subflow_check_data_avail,
 		  __entry->skb)
 );
 
+DECLARE_EVENT_CLASS(mptcp_event_data_checksum,
+
+	TP_PROTO(struct csum_pseudo_header *header, __sum16 csum),
+
+	TP_ARGS(header, csum),
+
+	TP_STRUCT__entry(
+		__field(u64, data_seq)
+		__field(u32, subflow_seq)
+		__field(u16, data_len)
+		__field(u16, data_csum)
+		__field(u16, csum)
+	),
+
+	TP_fast_assign(
+		__entry->data_seq = header->data_seq;
+		__entry->subflow_seq = header->subflow_seq;
+		__entry->data_len = header->data_len;
+		__entry->data_csum = (__force u16)header->csum;
+		__entry->csum = (__force u16)csum;
+	),
+
+	TP_printk("data_seq=%llu subflow_seq=%u data_len=%u csum=%u",
+		  __entry->data_seq, __entry->subflow_seq, __entry->data_len,
+		  __entry->csum)
+);
+
+DEFINE_EVENT(mptcp_event_data_checksum, mptcp_generate_data_checksum,
+	TP_PROTO(struct csum_pseudo_header *header, __sum16 csum),
+	TP_ARGS(header, csum));
+
+DEFINE_EVENT_PRINT(mptcp_event_data_checksum, mptcp_validate_data_checksum,
+	TP_PROTO(struct csum_pseudo_header *header, __sum16 csum),
+	TP_ARGS(header, csum),
+	TP_printk("data_seq=%llu subflow_seq=%u data_len=%u csum=%u, checksum %s!",
+		  __entry->data_seq, __entry->subflow_seq, __entry->data_len,
+		  __entry->data_csum, __entry->csum ? "error" : "done"));
+
 #endif /* _TRACE_MPTCP_H */
 
 /* This part must be outside protection */
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e414ff940727..0fe9c29bcda8 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -552,6 +552,8 @@ static bool mptcp_validate_data_checksum(struct sock *ssk)
 
 	csum = csum_partial(&header, sizeof(header), subflow->data_csum);
 
+	trace_mptcp_validate_data_checksum(&header, csum_fold(csum));
+
 	if (csum_fold(csum)) {
 		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCSUMERR);
 		return false;
@@ -1307,6 +1309,8 @@ static __sum16 mptcp_generate_data_checksum(struct sk_buff *skb)
 	csum = skb_checksum(skb, 0, skb->len, 0);
 	csum = csum_partial(&header, sizeof(header), csum);
 
+	trace_mptcp_generate_data_checksum(&header, csum_fold(csum));
+
 	return csum_fold(csum);
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh
  2021-03-29 10:40                           ` [MPTCP][PATCH v2 mptcp-next 14/16] mptcp: add trace event for data checksum Geliang Tang
@ 2021-03-29 10:40                             ` Geliang Tang
  2021-03-29 10:40                               ` [MPTCP][PATCH v2 mptcp-next 16/16] selftests: mptcp: enable checksum in mptcp_join.sh Geliang Tang
  2021-03-30  0:50                               ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Mat Martineau
  0 siblings, 2 replies; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new argument "C" for mptcp_connect.sh script to
set the sysctl checksum_enabled to 1 to enable the data checksum.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 tools/testing/selftests/net/mptcp/mptcp_connect.sh | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 385cdc98aed8..c769f1e962bd 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -3,7 +3,7 @@
 
 time_start=$(date +%s)
 
-optstring="S:R:d:e:l:r:h4cm:f:t"
+optstring="S:R:d:e:l:r:h4cm:f:tC"
 ret=0
 sin=""
 sout=""
@@ -22,6 +22,7 @@ sndbuf=0
 rcvbuf=0
 options_log=true
 do_tcp=0
+checksum=false
 filesize=0
 
 if [ $tc_loss -eq 100 ];then
@@ -47,6 +48,7 @@ usage() {
 	echo -e "\t-R: set rcvbuf value (default: use kernel default)"
 	echo -e "\t-m: test mode (poll, sendfile; default: poll)"
 	echo -e "\t-t: also run tests with TCP (use twice to non-fallback tcp)"
+	echo -e "\t-C: enable the MPTCP data checksum"
 }
 
 while getopts "$optstring" option;do
@@ -104,6 +106,9 @@ while getopts "$optstring" option;do
 	"t")
 		do_tcp=$((do_tcp+1))
 		;;
+	"C")
+		checksum=true
+		;;
 	"?")
 		usage $0
 		exit 1
@@ -200,6 +205,12 @@ ip -net "$ns4" route add default via dead:beef:3::2
 # use TCP syn cookies, even if no flooding was detected.
 ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2
 
+if $checksum; then
+	for i in "$ns1" "$ns2" "$ns3" "$ns4";do
+		ip netns exec $i sysctl -q net.mptcp.checksum_enabled=1
+	done
+fi
+
 set_ethtool_flags() {
 	local ns="$1"
 	local dev="$2"
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [MPTCP][PATCH v2 mptcp-next 16/16] selftests: mptcp: enable checksum in mptcp_join.sh
  2021-03-29 10:40                             ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Geliang Tang
@ 2021-03-29 10:40                               ` Geliang Tang
  2021-03-30  0:50                               ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Mat Martineau
  1 sibling, 0 replies; 20+ messages in thread
From: Geliang Tang @ 2021-03-29 10:40 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

This patch added a new argument "C" for mptcp_join.sh script to set the
sysctl checksum_enabled to 1 to enable the data checksum.

In chk_join_nr, check the counter of the mib for the data checksum.

The output looks like this:

 01 no JOIN                            syn[ ok ] - synack[ ok ] - ack[ ok ]
                                       sum[ ok ] - csum  [ ok ]
 02 single subflow, limited by client  syn[ ok ] - synack[ ok ] - ack[ ok ]
                                       sum[ ok ] - csum  [ ok ]

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 .../testing/selftests/net/mptcp/mptcp_join.sh | 40 +++++++++++++++++--
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index fd99485cf2a4..b98ff993bcfe 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -12,6 +12,7 @@ timeout_poll=30
 timeout_test=$((timeout_poll * 2 + 1))
 mptcp_connect=""
 capture=0
+checksum=0
 do_all_tests=1
 
 TEST_COUNT=0
@@ -49,6 +50,9 @@ init()
 		ip netns exec $netns sysctl -q net.mptcp.enabled=1
 		ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0
 		ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0
+		if [ $checksum -eq 1 ]; then
+			ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
+		fi
 	done
 
 	#  ns1              ns2
@@ -517,6 +521,28 @@ chk_join_nr()
 	else
 		echo "[ ok ]"
 	fi
+	if [ $checksum -eq 1 ]; then
+		printf "%-39s %s" " " "sum"
+		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtDSSCsumErr | awk '{print $2}'`
+		[ -z "$count" ] && count=0
+		if [ "$count" != 0 ]; then
+			echo "[fail] got $count data checksum error[s] expected 0"
+			ret=1
+			dump_stats=1
+		else
+			echo -n "[ ok ]"
+		fi
+		echo -n " - csum  "
+		count=`ip netns exec $ns2 nstat -as | grep MPTcpExtDSSCsumErr | awk '{print $2}'`
+		[ -z "$count" ] && count=0
+		if [ "$count" != 0 ]; then
+			echo "[fail] got $count data checksum error[s] expected 0"
+			ret=1
+			dump_stats=1
+		else
+			echo "[ ok ]"
+		fi
+	fi
 	if [ "${dump_stats}" = 1 ]; then
 		echo Server ns stats
 		ip netns exec $ns1 nstat -as | grep MPTcp
@@ -1404,6 +1430,7 @@ usage()
 	echo "  -p add_addr_ports_tests"
 	echo "  -k syncookies_tests"
 	echo "  -c capture pcap files"
+	echo "  -C enable data checksum"
 	echo "  -h help"
 }
 
@@ -1418,13 +1445,16 @@ make_file "$sin" "server" 1
 trap cleanup EXIT
 
 for arg in "$@"; do
-	# check for "capture" arg before launching tests
+	# check for "capture/checksum" args before launching tests
 	if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"c"[0-9a-zA-Z]*$ ]]; then
 		capture=1
 	fi
+	if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"C"[0-9a-zA-Z]*$ ]]; then
+		checksum=1
+	fi
 
-	# exception for the capture option, the rest means: a part of the tests
-	if [ "${arg}" != "-c" ]; then
+	# exception for the capture/checksum options, the rest means: a part of the tests
+	if [ "${arg}" != "-c" ] && [ "${arg}" != "-C" ]; then
 		do_all_tests=0
 	fi
 done
@@ -1434,7 +1464,7 @@ if [ $do_all_tests -eq 1 ]; then
 	exit $ret
 fi
 
-while getopts 'fsltra64bpkch' opt; do
+while getopts 'fsltra64bpkchC' opt; do
 	case $opt in
 		f)
 			subflows_tests
@@ -1471,6 +1501,8 @@ while getopts 'fsltra64bpkch' opt; do
 			;;
 		c)
 			;;
+		C)
+			;;
 		h | *)
 			usage
 			;;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option
  2021-03-29 10:40             ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Geliang Tang
  2021-03-29 10:40               ` [MPTCP][PATCH v2 mptcp-next 08/16] mptcp: receive checksum for MP_CAPABLE with data Geliang Tang
@ 2021-03-30  0:15               ` Mat Martineau
  1 sibling, 0 replies; 20+ messages in thread
From: Mat Martineau @ 2021-03-30  0:15 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

On Mon, 29 Mar 2021, Geliang Tang wrote:

> This patch added a new parameter name sk in mptcp_parse_option() and
> mptcp_get_options().
>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---

Could you squash patches 7, 8, and 9 to help keep the patch set size under 
15 (netdev patchwork flags patchsets longer than that)?

Thanks,

Mat


> net/mptcp/options.c  | 10 ++++++----
> net/mptcp/protocol.h |  3 ++-
> net/mptcp/subflow.c  | 10 +++++-----
> 3 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 6acb7469bae9..cb423cba5c3b 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -20,7 +20,8 @@ static bool mptcp_cap_flag_sha256(u8 flags)
> 	return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256;
> }
>
> -static void mptcp_parse_option(const struct sk_buff *skb,
> +static void mptcp_parse_option(const struct sock *sk,
> +			       const struct sk_buff *skb,
> 			       const unsigned char *ptr, int opsize,
> 			       struct mptcp_options_received *mp_opt)
> {
> @@ -322,7 +323,8 @@ static void mptcp_parse_option(const struct sk_buff *skb,
> 	}
> }
>
> -void mptcp_get_options(const struct sk_buff *skb,
> +void mptcp_get_options(const struct sock *sk,
> +		       const struct sk_buff *skb,
> 		       struct mptcp_options_received *mp_opt)
> {
> 	const struct tcphdr *th = tcp_hdr(skb);
> @@ -362,7 +364,7 @@ void mptcp_get_options(const struct sk_buff *skb,
> 			if (opsize > length)
> 				return;	/* don't parse partial options */
> 			if (opcode == TCPOPT_MPTCP)
> -				mptcp_parse_option(skb, ptr, opsize, mp_opt);
> +				mptcp_parse_option(sk, skb, ptr, opsize, mp_opt);
> 			ptr += opsize - 2;
> 			length -= opsize;
> 		}
> @@ -1016,7 +1018,7 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
> 		return;
> 	}
>
> -	mptcp_get_options(skb, &mp_opt);
> +	mptcp_get_options(sk, skb, &mp_opt);
> 	if (!check_fully_established(msk, sk, subflow, skb, &mp_opt))
> 		return;
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index ae7d47352d09..cfdecfb90776 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -570,7 +570,8 @@ int __init mptcp_proto_v6_init(void);
> struct sock *mptcp_sk_clone(const struct sock *sk,
> 			    const struct mptcp_options_received *mp_opt,
> 			    struct request_sock *req);
> -void mptcp_get_options(const struct sk_buff *skb,
> +void mptcp_get_options(const struct sock *sk,
> +		       const struct sk_buff *skb,
> 		       struct mptcp_options_received *mp_opt);
>
> void mptcp_finish_connect(struct sock *sk);
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index cbdfa5a6f8f6..75664da251a6 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -151,7 +151,7 @@ static int subflow_check_req(struct request_sock *req,
> 		return -EINVAL;
> #endif
>
> -	mptcp_get_options(skb, &mp_opt);
> +	mptcp_get_options(sk_listener, skb, &mp_opt);
>
> 	if (mp_opt.mp_capable) {
> 		SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
> @@ -248,7 +248,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
> 	int err;
>
> 	subflow_init_req(req, sk_listener);
> -	mptcp_get_options(skb, &mp_opt);
> +	mptcp_get_options(sk_listener, skb, &mp_opt);
>
> 	if (mp_opt.mp_capable && mp_opt.mp_join)
> 		return -EINVAL;
> @@ -395,7 +395,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
> 	subflow->ssn_offset = TCP_SKB_CB(skb)->seq;
> 	pr_debug("subflow=%p synack seq=%x", subflow, subflow->ssn_offset);
>
> -	mptcp_get_options(skb, &mp_opt);
> +	mptcp_get_options(sk, skb, &mp_opt);
> 	if (subflow->request_mptcp) {
> 		if (!mp_opt.mp_capable) {
> 			MPTCP_INC_STATS(sock_net(sk),
> @@ -642,7 +642,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> 			goto create_msk;
> 		}
>
> -		mptcp_get_options(skb, &mp_opt);
> +		mptcp_get_options(sk, skb, &mp_opt);
> 		if (!mp_opt.mp_capable) {
> 			fallback = true;
> 			goto create_child;
> @@ -653,7 +653,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> 		if (!new_msk)
> 			fallback = true;
> 	} else if (subflow_req->mp_join) {
> -		mptcp_get_options(skb, &mp_opt);
> +		mptcp_get_options(sk, skb, &mp_opt);
> 		if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) ||
> 		    !mptcp_can_accept_new_subflow(subflow_req->msk)) {
> 			SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
> -- 
> 2.30.2
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum
  2021-03-29 10:40                   ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Geliang Tang
  2021-03-29 10:40                     ` [MPTCP][PATCH v2 mptcp-next 11/16] mptcp: add the mib for " Geliang Tang
@ 2021-03-30  0:40                     ` Mat Martineau
  1 sibling, 0 replies; 20+ messages in thread
From: Mat Martineau @ 2021-03-30  0:40 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp


Hi Geliang,

On Mon, 29 Mar 2021, Geliang Tang wrote:

> This patch add three new members named data_csum, csum_len and map_csum in
> struct mptcp_subflow_context, implemented a new function named
> mptcp_validate_data_checksum(). Validate the data checksum in the function
> __mptcp_move_skbs_from_subflow.
>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> net/mptcp/protocol.c | 35 +++++++++++++++++++++++++++++++++++
> net/mptcp/protocol.h |  3 +++
> net/mptcp/subflow.c  |  7 +++++--
> 3 files changed, 43 insertions(+), 2 deletions(-)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 436969d95e36..0b4ab35e234a 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -532,6 +532,35 @@ static bool mptcp_check_data_fin(struct sock *sk)
> 	return ret;
> }
>
> +static bool mptcp_validate_data_checksum(struct sock *ssk)
> +{
> +	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
> +	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> +	struct csum_pseudo_header header;
> +	__wsum csum;
> +
> +	if (__mptcp_check_fallback(msk))
> +		goto out;
> +
> +	if (subflow->csum_len < subflow->map_data_len)
> +		goto out;
> +
> +	header.data_seq = subflow->map_seq;
> +	header.subflow_seq = subflow->map_subflow_seq;
> +	header.data_len = subflow->map_data_len;
> +	header.csum = subflow->map_csum;
> +
> +	csum = csum_partial(&header, sizeof(header), subflow->data_csum);
> +
> +	if (csum_fold(csum))
> +		return false;
> +	subflow->data_csum = 0;
> +	subflow->csum_len = 0;
> +
> +out:
> +	return true;
> +}
> +
> static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
> 					   struct sock *ssk,
> 					   unsigned int *bytes)
> @@ -600,6 +629,12 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
> 			if (tp->urg_data)
> 				done = true;
>
> +			if (READ_ONCE(msk->csum_enabled)) {
> +				subflow->data_csum = skb_checksum(skb, offset, len,
> +								  subflow->data_csum);
> +				subflow->csum_len += len;
> +				mptcp_validate_data_checksum(ssk);

The return value is ignored there so a bad checksum doesn't seem to have 
any effect.

There needs to be different handling for several different cases here.


1. Checksums are not enabled, code works same as before this patch set


2. All data needed for the checksum is present and the checksum is valid

    --> Checksum validation will have to look through the queue of skbs in 
sk_receive_queue to add up the available length and compare to map length, 
then if there is enough combined data to cover map_data_len, go ahead and 
validate the checksum. For example, map_data_len could be 4500, and the 
payload of the first skb might be only 1500 bytes. Would have to wait for 
skb2 and skb3 (each with 1500 bytes) to arrive before validating the 
checksum.

    --> If the checksum for all the data is valid, make sure all skbs 
covered by the checksum are moved to the msk with __mptcp_move_skb()


3. All data needed for the checksum is present and the checksum is invalid

    --> Ignore all data from mapping (it must not be acked at the MPTCP 
level), update MPTCP_MIB_DSSCSUMERR). Discard the skbs with bad data, but 
be careful with the last skb in case it has a new mapping.


4. Checksums are enabled but there is some kind of non-checksum condition 
to handle (FIN flag, etc)

    --> Probably best to treat like a failed checksum and ensure other 
required actions happen, like handling the FIN


Thanks,

Mat



> +			}
> 			if (__mptcp_move_skb(msk, ssk, skb, offset, len))
> 				moved += len;
> 			seq += len;
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 6be10ebabcd5..d4bf264d16cc 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -394,6 +394,9 @@ struct mptcp_subflow_context {
> 	u32	map_subflow_seq;
> 	u32	ssn_offset;
> 	u32	map_data_len;
> +	__wsum	data_csum;
> +	u32	csum_len;
> +	__sum16	map_csum;
> 	u32	request_mptcp : 1,  /* send MP_CAPABLE */
> 		request_join : 1,   /* send MP_JOIN */
> 		request_bkup : 1,
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 75664da251a6..df7ad478bb2e 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -944,9 +944,12 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
> 	subflow->map_data_len = data_len;
> 	subflow->map_valid = 1;
> 	subflow->mpc_map = mpext->mpc_map;
> -	pr_debug("new map seq=%llu subflow_seq=%u data_len=%u",
> +	subflow->data_csum = 0;
> +	subflow->csum_len = 0;
> +	subflow->map_csum = mpext->csum;
> +	pr_debug("new map seq=%llu subflow_seq=%u data_len=%u csum=%u",
> 		 subflow->map_seq, subflow->map_subflow_seq,
> -		 subflow->map_data_len);
> +		 subflow->map_data_len, subflow->map_csum);
>
> validate_seq:
> 	/* we revalidate valid mapping on new skb, because we must ensure
> -- 
> 2.30.2
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh
  2021-03-29 10:40                             ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Geliang Tang
  2021-03-29 10:40                               ` [MPTCP][PATCH v2 mptcp-next 16/16] selftests: mptcp: enable checksum in mptcp_join.sh Geliang Tang
@ 2021-03-30  0:50                               ` Mat Martineau
  1 sibling, 0 replies; 20+ messages in thread
From: Mat Martineau @ 2021-03-30  0:50 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

On Mon, 29 Mar 2021, Geliang Tang wrote:

> This patch added a new argument "C" for mptcp_connect.sh script to
> set the sysctl checksum_enabled to 1 to enable the data checksum.
>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>

In addition to the "-C" flag for adding checksums to most test cases, it 
would help to have a few more test cases added that verify the checksum 
handshake:

  * Sender and listener both have checksums off
  * Sender and listener both have checksums on
  * Sender checksums off, listener checksums on
  * Sender checksums on, listener checksums off

Those could run the same with or without "-C", but the rest of the tests 
would only enable checksums when "-C" was used.


Thanks,

Mat


> ---
> tools/testing/selftests/net/mptcp/mptcp_connect.sh | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> index 385cdc98aed8..c769f1e962bd 100755
> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> @@ -3,7 +3,7 @@
>
> time_start=$(date +%s)
>
> -optstring="S:R:d:e:l:r:h4cm:f:t"
> +optstring="S:R:d:e:l:r:h4cm:f:tC"
> ret=0
> sin=""
> sout=""
> @@ -22,6 +22,7 @@ sndbuf=0
> rcvbuf=0
> options_log=true
> do_tcp=0
> +checksum=false
> filesize=0
>
> if [ $tc_loss -eq 100 ];then
> @@ -47,6 +48,7 @@ usage() {
> 	echo -e "\t-R: set rcvbuf value (default: use kernel default)"
> 	echo -e "\t-m: test mode (poll, sendfile; default: poll)"
> 	echo -e "\t-t: also run tests with TCP (use twice to non-fallback tcp)"
> +	echo -e "\t-C: enable the MPTCP data checksum"
> }
>
> while getopts "$optstring" option;do
> @@ -104,6 +106,9 @@ while getopts "$optstring" option;do
> 	"t")
> 		do_tcp=$((do_tcp+1))
> 		;;
> +	"C")
> +		checksum=true
> +		;;
> 	"?")
> 		usage $0
> 		exit 1
> @@ -200,6 +205,12 @@ ip -net "$ns4" route add default via dead:beef:3::2
> # use TCP syn cookies, even if no flooding was detected.
> ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2
>
> +if $checksum; then
> +	for i in "$ns1" "$ns2" "$ns3" "$ns4";do
> +		ip netns exec $i sysctl -q net.mptcp.checksum_enabled=1
> +	done
> +fi
> +
> set_ethtool_flags() {
> 	local ns="$1"
> 	local dev="$2"
> -- 
> 2.30.2
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-03-30  0:50 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-29 10:40 [MPTCP][PATCH v2 mptcp-next 00/16] data checksum support Geliang Tang
2021-03-29 10:40 ` [MPTCP][PATCH v2 mptcp-next 01/16] mptcp: add csum_enabled in mptcp_sock Geliang Tang
2021-03-29 10:40   ` [MPTCP][PATCH v2 mptcp-next 02/16] mptcp: generate the data checksum Geliang Tang
2021-03-29 10:40     ` [MPTCP][PATCH v2 mptcp-next 03/16] mptcp: add csum_reqd in mptcp_out_options Geliang Tang
2021-03-29 10:40       ` [MPTCP][PATCH v2 mptcp-next 04/16] mptcp: send out checksum for MP_CAPABLE with data Geliang Tang
2021-03-29 10:40         ` [MPTCP][PATCH v2 mptcp-next 05/16] mptcp: send out checksum for DSS Geliang Tang
2021-03-29 10:40           ` [MPTCP][PATCH v2 mptcp-next 06/16] mptcp: add csum_reqd in mptcp_options_received Geliang Tang
2021-03-29 10:40             ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Geliang Tang
2021-03-29 10:40               ` [MPTCP][PATCH v2 mptcp-next 08/16] mptcp: receive checksum for MP_CAPABLE with data Geliang Tang
2021-03-29 10:40                 ` [MPTCP][PATCH v2 mptcp-next 09/16] mptcp: receive checksum for DSS Geliang Tang
2021-03-29 10:40                   ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Geliang Tang
2021-03-29 10:40                     ` [MPTCP][PATCH v2 mptcp-next 11/16] mptcp: add the mib for " Geliang Tang
2021-03-29 10:40                       ` [MPTCP][PATCH v2 mptcp-next 12/16] mptcp: add a new sysctl checksum_enabled Geliang Tang
2021-03-29 10:40                         ` [MPTCP][PATCH v2 mptcp-next 13/16] mptcp: add mptcpi_csum_enabled in mptcp_info Geliang Tang
2021-03-29 10:40                           ` [MPTCP][PATCH v2 mptcp-next 14/16] mptcp: add trace event for data checksum Geliang Tang
2021-03-29 10:40                             ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Geliang Tang
2021-03-29 10:40                               ` [MPTCP][PATCH v2 mptcp-next 16/16] selftests: mptcp: enable checksum in mptcp_join.sh Geliang Tang
2021-03-30  0:50                               ` [MPTCP][PATCH v2 mptcp-next 15/16] selftests: mptcp: enable checksum in mptcp_connect.sh Mat Martineau
2021-03-30  0:40                     ` [MPTCP][PATCH v2 mptcp-next 10/16] mptcp: validate the data checksum Mat Martineau
2021-03-30  0:15               ` [MPTCP][PATCH v2 mptcp-next 07/16] mptcp: add sk parameter for mptcp_parse_option Mat Martineau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).