mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism
@ 2022-09-20 12:52 Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 1/7] add mptcp_stream_connect to protocol.h Dmytro Shytyi
                   ` (6 more replies)
  0 siblings, 7 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

[PATCH v8] includes "client-server" partial support for:
1. MPTCP cookie request from client (seems OK).
2. MPTCP cookie offering from server (seems OK).
3. MPTCP SYN+DATA+COOKIE from client (seems OK).
4. subsequent write + read on the opened socket (seems OK).
===Changes between v7 and v8
- We change from 0impact approach on existing TCP code to
  full reusage of existing and available functions.
- Code is refactored (Max. reuse of existing linux kernel code).
- fastopen.c is reduced to minima.
- Other comments from mailing list are coming in the next version.
===Future work
-Adress the appearance of "MPTCP FIN" as duplicated acks.
-Integrate presented in the last patch selftests. 

Dmytro Shytyi (7):
  add mptcp_stream_connect to protocol.h
  add mptcp_setsockopt_fastopen
  reuse tcp_sendmsg_fastopen()
  mptfo variables for msk, options. Fix loop retrans
  Fix unxpctd val of subflow->map_seq(dscrd packet)
  add skb to mskq in tcp_fastopen_add_skb()
  selftests: mptfo initiator/listener

 include/net/tcp.h                             |  5 +-
 net/ipv4/tcp.c                                | 18 +++-
 net/ipv4/tcp_fastopen.c                       | 55 +++++++++--
 net/ipv4/tcp_input.c                          | 11 ++-
 net/mptcp/Makefile                            |  2 +-
 net/mptcp/fastopen.c                          | 46 +++++++++
 net/mptcp/options.c                           |  9 ++
 net/mptcp/protocol.c                          | 19 ++--
 net/mptcp/protocol.h                          | 14 ++-
 net/mptcp/sockopt.c                           |  3 +
 tools/testing/selftests/net/mptcp/mptfo.sh    | 13 +++
 .../selftests/net/mptcp/mptfo_initiator.c     | 41 ++++++++
 .../selftests/net/mptcp/mptfo_listener.c      | 98 +++++++++++++++++++
 13 files changed, 311 insertions(+), 23 deletions(-)
 create mode 100644 net/mptcp/fastopen.c
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo.sh
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo_initiator.c
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo_listener.c

-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 1/7] add mptcp_stream_connect to protocol.h
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 2/7] add mptcp_setsockopt_fastopen Dmytro Shytyi
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

In the following patches we will call mptcp_stream_connect() from
function tcp_sendmsg_fastopen() in file "net/ipv4/tcp.c", thus make
such symbol visible.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 net/mptcp/protocol.c | 4 ++--
 net/mptcp/protocol.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index c0bf48e3149b..470045793181 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3484,8 +3484,8 @@ static void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
 	__mptcp_do_fallback(msk);
 }
 
-static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
-				int addr_len, int flags)
+int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
+			 int addr_len, int flags)
 {
 	struct mptcp_sock *msk = mptcp_sk(sock->sk);
 	struct mptcp_subflow_context *subflow;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 93c535440a5c..632161b13950 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -837,6 +837,7 @@ void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
 void mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_info *info);
 void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
 bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
+int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags);
 
 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
 {
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 2/7] add mptcp_setsockopt_fastopen
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 1/7] add mptcp_stream_connect to protocol.h Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen() Dmytro Shytyi
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

Add set MPTFO socket option for MPTCP.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 net/mptcp/Makefile   |  2 +-
 net/mptcp/fastopen.c | 32 ++++++++++++++++++++++++++++++++
 net/mptcp/protocol.h |  5 +++++
 net/mptcp/sockopt.c  |  3 +++
 4 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 net/mptcp/fastopen.c

diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
index 8a7f68efa35f..c42ad8609876 100644
--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_MPTCP) += mptcp.o
 
 mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
-	   mib.o pm_netlink.o sockopt.o pm_userspace.o sched.o
+	   mib.o pm_netlink.o sockopt.o pm_userspace.o sched.o fastopen.o
 
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
 obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
new file mode 100644
index 000000000000..9ef49a2d2ea2
--- /dev/null
+++ b/net/mptcp/fastopen.c
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * MPTCP Fast Open Mechanism. Copyright (c) 2021-2022, Dmytro SHYTYI
+ */
+
+#include "protocol.h"
+
+int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
+				      unsigned int optlen)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct net *net = sock_net(sk);
+	int val;
+	int ret;
+
+	ret = 0;
+
+	if (copy_from_sockptr(&val, optval, sizeof(val)))
+		return -EFAULT;
+
+	lock_sock(sk);
+
+	if (val >= 0 && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
+		tcp_fastopen_init_key_once(net);
+		fastopen_queue_tune(sk, val);
+	} else {
+		ret = -EINVAL;
+	}
+
+	release_sock(sk);
+
+	return ret;
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 632161b13950..57596cdfb1f9 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -839,6 +839,11 @@ void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
 bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
 int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags);
 
+// Fast Open Mechanism functions begin
+int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
+				      unsigned int optlen);
+// Fast Open Mechanism functions end
+
 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
 {
 	return READ_ONCE(msk->pm.addr_signal) &
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 423d3826ca1e..f62f0d63b8e6 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -559,6 +559,7 @@ static bool mptcp_supported_sockopt(int level, int optname)
 		case TCP_NOTSENT_LOWAT:
 		case TCP_TX_DELAY:
 		case TCP_INQ:
+		case TCP_FASTOPEN:
 			return true;
 		}
 
@@ -796,6 +797,8 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
 		return mptcp_setsockopt_sol_tcp_nodelay(msk, optval, optlen);
 	case TCP_DEFER_ACCEPT:
 		return mptcp_setsockopt_sol_tcp_defer(msk, optval, optlen);
+	case TCP_FASTOPEN:
+		return mptcp_setsockopt_sol_tcp_fastopen(msk, optval, optlen);
 	}
 
 	return -EOPNOTSUPP;
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 1/7] add mptcp_stream_connect to protocol.h Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 2/7] add mptcp_setsockopt_fastopen Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 14:36   ` Paolo Abeni
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

In the following patches we will reuse modified tcp_sendmsg_fastopen().
We call it from mptcp_sendmsg().

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 include/net/tcp.h    |  3 +++
 net/ipv4/tcp.c       | 18 +++++++++++++-----
 net/mptcp/protocol.c | 11 +++++++++--
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 735e957f7f4b..a7d49e42470a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
 			      struct request_sock *req,
 			      struct tcp_fastopen_cookie *foc,
 			      const struct dst_entry *dst);
+int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+			 int *copied, size_t size,
+			 struct ubuf_info *uarg);
 void tcp_fastopen_init_key_once(struct net *net);
 bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
 			     struct tcp_fastopen_cookie *cookie);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9251c99d3cfd..d10a3cdae220 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -280,6 +280,9 @@
 #include <asm/ioctls.h>
 #include <net/busy_poll.h>
 
+#include <net/mptcp.h>
+#include "../mptcp/protocol.h"
+
 /* Track pending CMSGs. */
 enum {
 	TCP_CMSG_INQ = 1,
@@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
 	}
 }
 
-static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
-				int *copied, size_t size,
-				struct ubuf_info *uarg)
+int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+			 int *copied, size_t size,
+			 struct ubuf_info *uarg)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
@@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
 		}
 	}
 	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
-	err = __inet_stream_connect(sk->sk_socket, uaddr,
-				    msg->msg_namelen, flags, 1);
+	if (!sk_is_mptcp(sk))
+		err = __inet_stream_connect(sk->sk_socket, uaddr,
+					    msg->msg_namelen, flags, 1);
+	else
+		err = mptcp_stream_connect(sk->sk_socket, uaddr,
+					   msg->msg_namelen, msg->msg_flags);
+
 	/* fastopen_req could already be freed in __inet_stream_connect
 	 * if the connection times out or gets rst
 	 */
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 470045793181..8cf307e4e59c 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	long timeo;
 
 	/* we don't support FASTOPEN yet */
-	if (msg->msg_flags & MSG_FASTOPEN)
-		return -EOPNOTSUPP;
+	if (msg->msg_flags & MSG_FASTOPEN) {
+		struct socket *ssock = __mptcp_nmpc_socket(msk);
 
+		if (ssock) {
+			int copied_syn_fastopen = 0;
+
+			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
+			copied += copied_syn_fastopen;
+		}
+	}
 	/* silently ignore everything else */
 	msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL;
 
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
                   ` (2 preceding siblings ...)
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen() Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 14:56   ` Paolo Abeni
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

Introduce mptfo variables for msk and options.
Also fix the infinite retransmissions in the end of second session.

The variable 2nd ack received in struct mptcp_options_received identifies the
received ack on the listener side during 3way handshake in mptfo context
and miningless alone if used alone. It is further used(checked)
in conjunction in the same "if" statement with variable is_mptfo
from struct mptcp_sock.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 net/mptcp/fastopen.c | 14 ++++++++++++++
 net/mptcp/options.c  |  4 ++++
 net/mptcp/protocol.h |  6 +++++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 9ef49a2d2ea2..92885e459f93 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -30,3 +30,17 @@ int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
 
 	return ret;
 }
+
+void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+				   struct mptcp_options_received mp_opt)
+{
+	u64 ack_seq;
+
+	msk->can_ack = true;
+	msk->remote_key = mp_opt.sndr_key;
+	mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
+	ack_seq++;
+	WRITE_ONCE(msk->ack_seq, ack_seq);
+	pr_debug("ack_seq=%llu sndr_key=%llu", msk->ack_seq, mp_opt.sndr_key);
+	atomic64_set(&msk->rcv_wnd_sent, ack_seq);
+}
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 30d289044e71..8852a13cfe62 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -91,6 +91,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
 			ptr += 8;
 		}
 		if (opsize >= TCPOLEN_MPTCP_MPC_ACK) {
+			mp_opt->hns_2nd_ack_rcvd = 1;
 			mp_opt->rcvr_key = get_unaligned_be64(ptr);
 			ptr += 8;
 		}
@@ -1124,6 +1125,9 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 		return sk->sk_state != TCP_CLOSE;
 
 	if (unlikely(mp_opt.suboptions != OPTION_MPTCP_DSS)) {
+		if (mp_opt.suboptions & OPTIONS_MPTCP_MPC && mp_opt.hns_2nd_ack_rcvd && msk->is_mptfo)
+			mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
+
 		if ((mp_opt.suboptions & OPTION_MPTCP_FASTCLOSE) &&
 		    msk->local_key == mp_opt.rcvr_key) {
 			WRITE_ONCE(msk->rcv_fastclose, true);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 57596cdfb1f9..3b9a349a7080 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -155,7 +155,8 @@ struct mptcp_options_received {
 		echo:1,
 		backup:1,
 		deny_join_id0:1,
-		__unused:2;
+		__unused:1;
+	u8	hns_2nd_ack_rcvd:1;
 	u8	join_id;
 	u64	thmac;
 	u8	hmac[MPTCPOPT_HMAC_LEN];
@@ -282,6 +283,7 @@ struct mptcp_sock {
 	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
 	bool		csum_enabled;
 	bool		allow_infinite_fallback;
+	bool		is_mptfo;
 	u8		mpc_endpoint_id;
 	u8		recvmsg_inq:1,
 			cork:1,
@@ -842,6 +844,8 @@ int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_l
 // Fast Open Mechanism functions begin
 int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
 				      unsigned int optlen);
+void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+				   struct mptcp_options_received mp_opt);
 // Fast Open Mechanism functions end
 
 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet)
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
                   ` (3 preceding siblings ...)
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 16:04   ` Paolo Abeni
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb() Dmytro Shytyi
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
  6 siblings, 1 reply; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

Fix unexpected value of subflow->map_seq (discarded and after
retransmitted 2nd packet(1st after TFO)).
We use mptcp_gen_msk_ackseq_fasopen()
when we know this is the first chunk of data after TFO.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 net/mptcp/options.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 8852a13cfe62..8e937a422909 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -1212,6 +1212,11 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 			mpext->dsn64 = 1;
 			mpext->mpc_map = 1;
 			mpext->data_fin = 0;
+			
+			if (msk->is_mptfo) {
+				mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
+				mpext->data_seq = READ_ONCE(msk->ack_seq);
+			}
 		} else {
 			mpext->data_seq = mp_opt.data_seq;
 			mpext->subflow_seq = mp_opt.subflow_seq;
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb()
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
                   ` (4 preceding siblings ...)
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 16:02   ` Paolo Abeni
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
  6 siblings, 1 reply; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

In the following patches we add skb to msk->receive_queue in the MPTCP
fastopen context.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 include/net/tcp.h       |  2 +-
 net/ipv4/tcp_fastopen.c | 55 +++++++++++++++++++++++++++++++++++------
 net/ipv4/tcp_input.c    | 11 +++++++--
 net/mptcp/protocol.c    |  4 +--
 net/mptcp/protocol.h    |  2 ++
 5 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index a7d49e42470a..6456f90ed9ed 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1749,7 +1749,7 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
 			      void *primary_key, void *backup_key);
 int tcp_fastopen_get_cipher(struct net *net, struct inet_connection_sock *icsk,
 			    u64 *key);
-void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
+void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req);
 struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
 			      struct request_sock *req,
 			      struct tcp_fastopen_cookie *foc,
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 45cc7f1ca296..566706172828 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -3,6 +3,7 @@
 #include <linux/tcp.h>
 #include <linux/rcupdate.h>
 #include <net/tcp.h>
+#include "../mptcp/protocol.h"
 
 void tcp_fastopen_init_key_once(struct net *net)
 {
@@ -166,8 +167,12 @@ static void tcp_fastopen_cookie_gen(struct sock *sk,
 /* If an incoming SYN or SYNACK frame contains a payload and/or FIN,
  * queue this additional data / FIN.
  */
-void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
+void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req)
 {
+	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+	struct tcp_request_sock *tcp_r_sock = tcp_rsk(req);
+	struct sock *socket = mptcp_subflow_ctx(sk)->conn;
+	struct mptcp_sock *msk = mptcp_sk(socket);
 	struct tcp_sock *tp = tcp_sk(sk);
 
 	if (TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)
@@ -194,7 +199,34 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
 	TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
 
 	tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+
+	if (req && tp->syn_fastopen && sk_is_mptcp(sk))
+		tcp_r_sock = tcp_rsk(req);
+	else
+		goto add_skb_to_sk;
+
+	msk->is_mptfo = 1;
+
+	//Solves: WARNING: at 704 _mptcp_move_skbs_from_subflow+0x5d0/0x651
+	tp->copied_seq += tp->rcv_nxt - tcp_r_sock->rcv_isn - 1;
+
+	subflow->map_seq = mptcp_subflow_get_mapped_dsn(subflow);
+
+	//Solves: BAD mapping: ssn=0 map_seq=1 map_data_len=3
+	subflow->ssn_offset = tp->copied_seq - 1;
+
+	skb_orphan(skb);
+	skb->sk = socket;
+	skb->destructor = mptcp_rfree;
+	atomic_add(skb->truesize, &socket->sk_rmem_alloc);
+	msk->rmem_fwd_alloc -= skb->truesize;
+
+	__skb_queue_tail(&msk->receive_queue, skb);
+	atomic64_set(&msk->rcv_wnd_sent, mptcp_subflow_get_mapped_dsn(subflow));
+	goto avoid_add_skb_to_sk;
+add_skb_to_sk:
 	__skb_queue_tail(&sk->sk_receive_queue, skb);
+avoid_add_skb_to_sk:
 	tp->syn_data_acked = 1;
 
 	/* u64_stats_update_begin(&tp->syncp) not needed here,
@@ -283,7 +315,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
 
 	tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
 
-	tcp_fastopen_add_skb(child, skb);
+	tcp_fastopen_add_skb(child, skb, req);
 
 	tcp_rsk(req)->rcv_nxt = tp->rcv_nxt;
 	tp->rcv_wup = tp->rcv_nxt;
@@ -350,17 +382,26 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
 	bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
 	int tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
 	struct tcp_fastopen_cookie valid_foc = { .len = -1 };
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *child;
 	int ret = 0;
 
 	if (foc->len == 0) /* Client requests a cookie */
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD);
 
-	if (!((tcp_fastopen & TFO_SERVER_ENABLE) &&
-	      (syn_data || foc->len >= 0) &&
-	      tcp_fastopen_queue_check(sk))) {
-		foc->len = -1;
-		return NULL;
+	if (tp->syn_fastopen && sk_is_mptcp(sk)) {
+		if (((syn_data || foc->len >= 0) &&
+		     tcp_fastopen_queue_check(sk))) {
+			foc->len = -1;
+			return NULL;
+		}
+	} else {
+		if (!((tcp_fastopen & TFO_SERVER_ENABLE) &&
+		      (syn_data || foc->len >= 0) &&
+		      tcp_fastopen_queue_check(sk))) {
+			foc->len = -1;
+			return NULL;
+		}
 	}
 
 	if (tcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD))
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index bc2ea12221f9..3facccee9dcb 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6134,7 +6134,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
 			--tp->delivered;
 	}
 
-	tcp_fastopen_add_skb(sk, synack);
+	tcp_fastopen_add_skb(sk, synack, NULL);
 
 	return false;
 }
@@ -6954,7 +6954,14 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
 	if (IS_ENABLED(CONFIG_SMC) && want_cookie)
 		tmp_opt.smc_ok = 0;
 
-	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
+	if (foc.len == -1 && sk_is_mptcp(sk)) {
+		tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
+	} else {
+		tmp_opt.tstamp_ok = 0;
+		tcp_rsk(req)->ts_off = 1;
+		tp->syn_fastopen = 1;
+	}
+
 	tcp_openreq_init(req, &tmp_opt, skb, sk);
 	inet_rsk(req)->no_srccheck = inet_sk(sk)->transparent;
 
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 8cf307e4e59c..b2329ef298fd 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -178,7 +178,7 @@ static void __mptcp_rmem_reclaim(struct sock *sk, int amount)
 	__sk_mem_reduce_allocated(sk, amount);
 }
 
-static void mptcp_rmem_uncharge(struct sock *sk, int size)
+void mptcp_rmem_uncharge(struct sock *sk, int size)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
 	int reclaimable;
@@ -191,7 +191,7 @@ static void mptcp_rmem_uncharge(struct sock *sk, int size)
 		__mptcp_rmem_reclaim(sk, reclaimable);
 }
 
-static void mptcp_rfree(struct sk_buff *skb)
+void mptcp_rfree(struct sk_buff *skb)
 {
 	unsigned int len = skb->truesize;
 	struct sock *sk = skb->sk;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 3b9a349a7080..5d86cd7d8dab 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -840,6 +840,8 @@ void mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_
 void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
 bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
 int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags);
+void mptcp_rmem_uncharge(struct sock *sk, int size);
+void mptcp_rfree(struct sk_buff *skb);
 
 // Fast Open Mechanism functions begin
 int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
-- 
2.25.1



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

* [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener
  2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
                   ` (5 preceding siblings ...)
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb() Dmytro Shytyi
@ 2022-09-20 12:52 ` Dmytro Shytyi
  2022-09-20 13:17   ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
  2022-09-20 14:40   ` selftests: mptfo initiator/listener: Tests Results MPTCP CI
  6 siblings, 2 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 12:52 UTC (permalink / raw)
  To: mptcp; +Cc: Dmytro Shytyi

MPTFO tests: these are examples of initiator (sendto) and listener,
probably are going to be integrated to the mptcp_connect.* selftests

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
 tools/testing/selftests/net/mptcp/mptfo.sh    | 13 +++
 .../selftests/net/mptcp/mptfo_initiator.c     | 41 ++++++++
 .../selftests/net/mptcp/mptfo_listener.c      | 98 +++++++++++++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo.sh
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo_initiator.c
 create mode 100644 tools/testing/selftests/net/mptcp/mptfo_listener.c

diff --git a/tools/testing/selftests/net/mptcp/mptfo.sh b/tools/testing/selftests/net/mptcp/mptfo.sh
new file mode 100644
index 000000000000..9ed0cb281094
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+#This is an example of environmen that was used to generate wireshark
+sudo ip netns add server
+sudo ip netns add client
+sudo ip link add veth0 type veth peer name veth1
+sudo ip link set veth1 netns server
+sudo ip link set veth0 netns client
+sudo ip netns exec client ip a a 10.10.0.1/24 dev veth0
+sudo ip netns exec server ip a a 10.10.0.2/24 dev veth1
+sudo ip netns exec client ip link set dev  veth0 up
+sudo ip netns exec server ip link set dev  veth1 up
+sudo ip netns exec server bash -c "echo 2 > /proc/sys/net/ipv4/tcp_fastopen"
+sudo ip netns exec client bash -c "echo 1 > /proc/sys/net/ipv4/tcp_fastopen"
diff --git a/tools/testing/selftests/net/mptcp/mptfo_initiator.c b/tools/testing/selftests/net/mptcp/mptfo_initiator.c
new file mode 100644
index 000000000000..e23b88693fb0
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo_initiator.c
@@ -0,0 +1,41 @@
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/tcp.h>
+#include <string.h>
+#include <signal.h>
+
+#define SERVER_PORT 7003
+
+int main(int argc, char *argv[])
+{
+	unsigned char valsyn[3] = "abc";
+	struct sockaddr_in daddr;
+	char *valend = "fff";
+	char *val1 = "zz1";
+	char *val2 = "zz2";
+	char *val3 = "zz3";
+	int sock_fd = -1;
+	int ret;
+
+	memset(&daddr, 0, sizeof(daddr));
+	inet_pton(AF_INET, "10.10.0.2", &daddr.sin_addr);
+	daddr.sin_family = AF_INET;
+	daddr.sin_port = htons(SERVER_PORT);
+
+	sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
+
+	ret = sendto(sock_fd, valsyn, 3, MSG_FASTOPEN, (struct sockaddr *) &daddr, sizeof(daddr));
+	ret = write(sock_fd, val1, 3);
+	ret = write(sock_fd, val2, 3);
+	ret = write(sock_fd, val2, 3);
+	ret = write(sock_fd, val2, 3);
+	ret = write(sock_fd, val3, 3);
+	ret = write(sock_fd, valend, 3);
+
+	close(sock_fd);
+	return EXIT_SUCCESS;
+}
diff --git a/tools/testing/selftests/net/mptcp/mptfo_listener.c b/tools/testing/selftests/net/mptcp/mptfo_listener.c
new file mode 100644
index 000000000000..7e3de8d1d08c
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo_listener.c
@@ -0,0 +1,98 @@
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <linux/in.h>
+#include <netinet/tcp.h>
+
+#define CLIENT_QUEUE_LEN 10
+#define SERVER_PORT 7003
+
+int main(void)
+{
+	int listen_sock_fd = -1, client_sock_fd = -1;
+	char str_addr[INET6_ADDRSTRLEN];
+	struct sockaddr_in server_addr;
+	int ret, flag;
+	int qlen = 5;
+	char ch;
+
+	server_addr.sin_family = AF_INET;
+	inet_pton(AF_INET, "10.10.0.2", &server_addr.sin_addr);
+	server_addr.sin_port = htons(SERVER_PORT);
+
+	/* Create socket for listening (client requests) */
+	listen_sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
+	if (listen_sock_fd == -1) {
+		perror("socket()server");
+		return EXIT_FAILURE;
+	}
+
+	/* Set socket to reuse address */
+	flag = 1;
+	ret = setsockopt(listen_sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
+	if (ret == -1) {
+		perror("setsockopt()");
+		return EXIT_FAILURE;
+	}
+
+	ret = setsockopt(listen_sock_fd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
+	if (ret == -1) {
+		perror("setsockopt()TCP_FASTOPEN");
+		return EXIT_FAILURE;
+	}
+
+	/* Bind address and socket together */
+	ret = bind(listen_sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
+	if (ret == -1) {
+		perror("bind()");
+		close(listen_sock_fd);
+		return EXIT_FAILURE;
+	}
+
+	/* Create listening queue (client requests) */
+	ret = listen(listen_sock_fd, CLIENT_QUEUE_LEN);
+	if (ret == -1) {
+		perror("listen()");
+		close(listen_sock_fd);
+		return EXIT_FAILURE;
+	}
+	perror("Server listening");
+	while (1) {
+		/* Do TCP handshake with client */
+		client_sock_fd = accept(listen_sock_fd,
+				NULL,
+				0);
+		if (client_sock_fd == -1) {
+			perror("accept()");
+			close(listen_sock_fd);
+			return EXIT_FAILURE;
+		} else {
+			perror("ACCEPT_SUCCESS");
+		}
+
+		char rb[1024];
+
+		while (1) {
+			ret = read(client_sock_fd, rb, 3);
+
+			if (ret == -1) {
+				perror("SERVVERread()");
+				close(client_sock_fd);
+				break;
+			} else {
+				fprintf(stderr, "received %c%c%c from client", rb[0], rb[1], rb[2]);
+			}
+			if (rb[0] == 'f' && rb[1] == 'f' && rb[2] == 'f') {
+				close(client_sock_fd);
+				break;
+			}
+
+		}
+	}
+
+	return EXIT_SUCCESS;
+}
-- 
2.25.1



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

* Re: selftests: mptfo initiator/listener: Build Failure
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
@ 2022-09-20 13:17   ` MPTCP CI
  2022-09-20 14:40   ` selftests: mptfo initiator/listener: Tests Results MPTCP CI
  1 sibling, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-09-20 13:17 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://patchwork.kernel.org/project/mptcp/patch/20220920125243.2880-8-dmytro@shytyi.net/
  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/3090294936

Status: failure
Initiator: MPTCPimporter
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/413c19c617ef

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

* Re: [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen() Dmytro Shytyi
@ 2022-09-20 14:36   ` Paolo Abeni
  2022-09-20 15:02     ` Matthieu Baerts
  2022-09-21  4:20     ` Dmytro Shytyi
  0 siblings, 2 replies; 25+ messages in thread
From: Paolo Abeni @ 2022-09-20 14:36 UTC (permalink / raw)
  To: Dmytro Shytyi, mptcp

On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
> In the following patches we will reuse modified tcp_sendmsg_fastopen().
> We call it from mptcp_sendmsg().
> 
> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> ---
>  include/net/tcp.h    |  3 +++
>  net/ipv4/tcp.c       | 18 +++++++++++++-----
>  net/mptcp/protocol.c | 11 +++++++++--
>  3 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 735e957f7f4b..a7d49e42470a 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>  			      struct request_sock *req,
>  			      struct tcp_fastopen_cookie *foc,
>  			      const struct dst_entry *dst);
> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> +			 int *copied, size_t size,
> +			 struct ubuf_info *uarg);
>  void tcp_fastopen_init_key_once(struct net *net);
>  bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
>  			     struct tcp_fastopen_cookie *cookie);
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 9251c99d3cfd..d10a3cdae220 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -280,6 +280,9 @@
>  #include <asm/ioctls.h>
>  #include <net/busy_poll.h>
>  
> +#include <net/mptcp.h>
> +#include "../mptcp/protocol.h"
> +
>  /* Track pending CMSGs. */
>  enum {
>  	TCP_CMSG_INQ = 1,
> @@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
>  	}
>  }
>  
> -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> -				int *copied, size_t size,
> -				struct ubuf_info *uarg)
> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> +			 int *copied, size_t size,
> +			 struct ubuf_info *uarg)
>  {
>  	struct tcp_sock *tp = tcp_sk(sk);
>  	struct inet_sock *inet = inet_sk(sk);
> @@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>  		}
>  	}
>  	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
> -	err = __inet_stream_connect(sk->sk_socket, uaddr,
> -				    msg->msg_namelen, flags, 1);
> +	if (!sk_is_mptcp(sk))
> +		err = __inet_stream_connect(sk->sk_socket, uaddr,
> +					    msg->msg_namelen, flags, 1);
> +	else
> +		err = mptcp_stream_connect(sk->sk_socket, uaddr,
> +					   msg->msg_namelen, msg->msg_flags);


I guess the goal of the above change is let mptcp_stream_connect()
update the msk socket status, is that correct?

However there are a few problems with lock: you must acquite the
subflow socket lock before calling tcp_sendmsg_fastopen() - or will see
subflow state corruption - but that in turn will cause a deadlock as 
 mptcp_stream_connect() acquires the msk socket lock and then the
subflow socket lock.

I think it's better leave the tcp_sendmsg_fastopen() body unchanged...

> +
>  	/* fastopen_req could already be freed in __inet_stream_connect
>  	 * if the connection times out or gets rst
>  	 */
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 470045793181..8cf307e4e59c 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
>  	long timeo;
>  
>  	/* we don't support FASTOPEN yet */
> -	if (msg->msg_flags & MSG_FASTOPEN)
> -		return -EOPNOTSUPP;
> +	if (msg->msg_flags & MSG_FASTOPEN) {
> +		struct socket *ssock = __mptcp_nmpc_socket(msk);

... acquire the subflow socket lock here...

>  
> +		if (ssock) {
> +			int copied_syn_fastopen = 0;
> +
> +			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
> +			copied += copied_syn_fastopen;
> +		}

... and additionally handle the sock state update here. Possibly you
can encapsulate all the fastopen code in a new function - say
__mptcp_sendmsg_fastopen(), as it will be called under the msk socket
lock.


Side note: you should enter the fastopen branch even when 
inet_sk(ssock->sk)->defer_connect is set

Cheers,

Paolo


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

* Re: selftests: mptfo initiator/listener: Tests Results
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
  2022-09-20 13:17   ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
@ 2022-09-20 14:40   ` MPTCP CI
  1 sibling, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-09-20 14:40 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal:
  - Unstable: 2 failed test(s): selftest_mptcp_join selftest_mptfo 🔴:
  - Task: https://cirrus-ci.com/task/5895896842895360
  - Summary: https://api.cirrus-ci.com/v1/artifact/task/5895896842895360/summary/summary.txt

- KVM Validation: debug:
  - Unstable: 1 failed test(s): selftest_mptfo 🔴:
  - Task: https://cirrus-ci.com/task/5332946889474048
  - Summary: https://api.cirrus-ci.com/v1/artifact/task/5332946889474048/summary/summary.txt

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/413c19c617ef


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-debug

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

* Re: [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
@ 2022-09-20 14:56   ` Paolo Abeni
  2022-09-21  4:15     ` Dmytro Shytyi
  0 siblings, 1 reply; 25+ messages in thread
From: Paolo Abeni @ 2022-09-20 14:56 UTC (permalink / raw)
  To: Dmytro Shytyi, mptcp

On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
> Introduce mptfo variables for msk and options.
> Also fix the infinite retransmissions in the end of second session.

I think the above sentence belongs more the changelog than to the
commit message itself.

> The variable 2nd ack received in struct mptcp_options_received identifies the
> received ack on the listener side during 3way handshake in mptfo context
> and miningless alone if used alone. It is further used(checked)
> in conjunction in the same "if" statement with variable is_mptfo
> from struct mptcp_sock.
> 
> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> ---
>  net/mptcp/fastopen.c | 14 ++++++++++++++
>  net/mptcp/options.c  |  4 ++++
>  net/mptcp/protocol.h |  6 +++++-
>  3 files changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
> index 9ef49a2d2ea2..92885e459f93 100644
> --- a/net/mptcp/fastopen.c
> +++ b/net/mptcp/fastopen.c
> @@ -30,3 +30,17 @@ int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
>  
>  	return ret;
>  }
> +
> +void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
> +				   struct mptcp_options_received mp_opt)
> +{
> +	u64 ack_seq;
> +
> +	msk->can_ack = true;
> +	msk->remote_key = mp_opt.sndr_key;

likely the above two statements need WRITE_ONCE() annotation.

Additionally it's better to add some safeguards here:
- ssk should be in TCP_SYN_RECV state - to be verified, it's guess and
I haven't check it yet.
- msk should be in the same state of the ssk subflow.

> +	mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
> +	ack_seq++;
> +	WRITE_ONCE(msk->ack_seq, ack_seq);
> +	pr_debug("ack_seq=%llu sndr_key=%llu", msk->ack_seq, mp_opt.sndr_key);
> +	atomic64_set(&msk->rcv_wnd_sent, ack_seq);
> +}
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 30d289044e71..8852a13cfe62 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -91,6 +91,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
>  			ptr += 8;
>  		}
>  		if (opsize >= TCPOLEN_MPTCP_MPC_ACK) {
> +			mp_opt->hns_2nd_ack_rcvd = 1;

Not needed, see below...

>  			mp_opt->rcvr_key = get_unaligned_be64(ptr);
>  			ptr += 8;
>  		}
> @@ -1124,6 +1125,9 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
>  		return sk->sk_state != TCP_CLOSE;
>  
>  	if (unlikely(mp_opt.suboptions != OPTION_MPTCP_DSS)) {
> +		if (mp_opt.suboptions & OPTIONS_MPTCP_MPC && mp_opt.hns_2nd_ack_rcvd && msk->is_mptfo)

You can simply check for:

		if (mp_opt.suboptions & OPTIONS_MPTCP_MPC_ACK) && msk->is_mptfo)

> +			mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
> +
>  		if ((mp_opt.suboptions & OPTION_MPTCP_FASTCLOSE) &&
>  		    msk->local_key == mp_opt.rcvr_key) {
>  			WRITE_ONCE(msk->rcv_fastclose, true);
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 57596cdfb1f9..3b9a349a7080 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -155,7 +155,8 @@ struct mptcp_options_received {
>  		echo:1,
>  		backup:1,
>  		deny_join_id0:1,
> -		__unused:2;
> +		__unused:1;
> +	u8	hns_2nd_ack_rcvd:1;

... again not needed, see above ;)

>  	u8	join_id;
>  	u64	thmac;
>  	u8	hmac[MPTCPOPT_HMAC_LEN];
> @@ -282,6 +283,7 @@ struct mptcp_sock {
>  	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
>  	bool		csum_enabled;
>  	bool		allow_infinite_fallback;
> +	bool		is_mptfo;
>  	u8		mpc_endpoint_id;
>  	u8		recvmsg_inq:1,
>  			cork:1,
> @@ -842,6 +844,8 @@ int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_l
>  // Fast Open Mechanism functions begin
>  int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
>  				      unsigned int optlen);
> +void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
> +				   struct mptcp_options_received mp_opt);
>  // Fast Open Mechanism functions end
>  
>  static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)


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

* Re: [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 14:36   ` Paolo Abeni
@ 2022-09-20 15:02     ` Matthieu Baerts
  2022-09-20 15:10       ` Dmytro Shytyi
  2022-09-20 15:12       ` Paolo Abeni
  2022-09-21  4:20     ` Dmytro Shytyi
  1 sibling, 2 replies; 25+ messages in thread
From: Matthieu Baerts @ 2022-09-20 15:02 UTC (permalink / raw)
  To: Paolo Abeni, Dmytro Shytyi, mptcp

Hi Paolo, Dmytro,

On 20/09/2022 16:36, Paolo Abeni wrote:
> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>> In the following patches we will reuse modified tcp_sendmsg_fastopen().
>> We call it from mptcp_sendmsg().
>>
>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>> ---
>>  include/net/tcp.h    |  3 +++
>>  net/ipv4/tcp.c       | 18 +++++++++++++-----
>>  net/mptcp/protocol.c | 11 +++++++++--
>>  3 files changed, 25 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index 735e957f7f4b..a7d49e42470a 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>>  			      struct request_sock *req,
>>  			      struct tcp_fastopen_cookie *foc,
>>  			      const struct dst_entry *dst);
>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> +			 int *copied, size_t size,
>> +			 struct ubuf_info *uarg);
>>  void tcp_fastopen_init_key_once(struct net *net);
>>  bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
>>  			     struct tcp_fastopen_cookie *cookie);
>> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
>> index 9251c99d3cfd..d10a3cdae220 100644
>> --- a/net/ipv4/tcp.c
>> +++ b/net/ipv4/tcp.c
>> @@ -280,6 +280,9 @@
>>  #include <asm/ioctls.h>
>>  #include <net/busy_poll.h>
>>  
>> +#include <net/mptcp.h>
>> +#include "../mptcp/protocol.h"
>> +
>>  /* Track pending CMSGs. */
>>  enum {
>>  	TCP_CMSG_INQ = 1,
>> @@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
>>  	}
>>  }
>>  
>> -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> -				int *copied, size_t size,
>> -				struct ubuf_info *uarg)
>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> +			 int *copied, size_t size,
>> +			 struct ubuf_info *uarg)
>>  {
>>  	struct tcp_sock *tp = tcp_sk(sk);
>>  	struct inet_sock *inet = inet_sk(sk);
>> @@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>  		}
>>  	}
>>  	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
>> -	err = __inet_stream_connect(sk->sk_socket, uaddr,
>> -				    msg->msg_namelen, flags, 1);
>> +	if (!sk_is_mptcp(sk))
>> +		err = __inet_stream_connect(sk->sk_socket, uaddr,
>> +					    msg->msg_namelen, flags, 1);
>> +	else
>> +		err = mptcp_stream_connect(sk->sk_socket, uaddr,
>> +					   msg->msg_namelen, msg->msg_flags);
> 
> 
> I guess the goal of the above change is let mptcp_stream_connect()
> update the msk socket status, is that correct?
> 
> However there are a few problems with lock: you must acquite the
> subflow socket lock before calling tcp_sendmsg_fastopen() - or will see
> subflow state corruption - but that in turn will cause a deadlock as 
>  mptcp_stream_connect() acquires the msk socket lock and then the
> subflow socket lock.
> 
> I think it's better leave the tcp_sendmsg_fastopen() body unchanged...
> 
>> +
>>  	/* fastopen_req could already be freed in __inet_stream_connect
>>  	 * if the connection times out or gets rst
>>  	 */
>> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
>> index 470045793181..8cf307e4e59c 100644
>> --- a/net/mptcp/protocol.c
>> +++ b/net/mptcp/protocol.c
>> @@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
>>  	long timeo;
>>  
>>  	/* we don't support FASTOPEN yet */
>> -	if (msg->msg_flags & MSG_FASTOPEN)
>> -		return -EOPNOTSUPP;
>> +	if (msg->msg_flags & MSG_FASTOPEN) {
>> +		struct socket *ssock = __mptcp_nmpc_socket(msk);
> 
> ... acquire the subflow socket lock here...
> 
>>  
>> +		if (ssock) {
>> +			int copied_syn_fastopen = 0;
>> +
>> +			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
>> +			copied += copied_syn_fastopen;
>> +		}
> 
> ... and additionally handle the sock state update here. Possibly you
> can encapsulate all the fastopen code in a new function - say
> __mptcp_sendmsg_fastopen(), as it will be called under the msk socket
> lock.
> 
> 
> Side note: you should enter the fastopen branch even when 
> inet_sk(ssock->sk)->defer_connect is set

I think we should better discuss about that at the next meeting because
all items you are asking here is what Benjamin did in [1]:

https://patchwork.kernel.org/project/mptcp/patch/20220908133829.3410092-4-benjamin.hesmans@tessares.net/

The work from Dmytro helped Benjamin to start looking at that and
propose another approach. Before the meeting, we can look at creating a
series focussed on the sending part taking patches from both Benjamin
and Dmytro using Benjamin's approach if that's OK. Of course both Dmytro
and Benjamin will be credited to have worked on that.

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

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

* Re: [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 15:02     ` Matthieu Baerts
@ 2022-09-20 15:10       ` Dmytro Shytyi
  2022-09-20 15:12       ` Paolo Abeni
  1 sibling, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-20 15:10 UTC (permalink / raw)
  To: Matthieu Baerts, Paolo Abeni, mptcp

Hi Matthieu,

My previous patches had locks in this function (mptcp_sendmsg()) also 
and code was generated much earlier.

If you add locks in the mptcp _sendmsg() in current context it will lead 
to deadlock.

I temporarly avoided adding locks as I need to carefully think about this.


Best,

Dmytro.

On 9/20/2022 5:02 PM, Matthieu Baerts wrote:
> Hi Paolo, Dmytro,
>
> On 20/09/2022 16:36, Paolo Abeni wrote:
>> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>>> In the following patches we will reuse modified tcp_sendmsg_fastopen().
>>> We call it from mptcp_sendmsg().
>>>
>>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>>> ---
>>>   include/net/tcp.h    |  3 +++
>>>   net/ipv4/tcp.c       | 18 +++++++++++++-----
>>>   net/mptcp/protocol.c | 11 +++++++++--
>>>   3 files changed, 25 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>> index 735e957f7f4b..a7d49e42470a 100644
>>> --- a/include/net/tcp.h
>>> +++ b/include/net/tcp.h
>>> @@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>>>   			      struct request_sock *req,
>>>   			      struct tcp_fastopen_cookie *foc,
>>>   			      const struct dst_entry *dst);
>>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>> +			 int *copied, size_t size,
>>> +			 struct ubuf_info *uarg);
>>>   void tcp_fastopen_init_key_once(struct net *net);
>>>   bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
>>>   			     struct tcp_fastopen_cookie *cookie);
>>> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
>>> index 9251c99d3cfd..d10a3cdae220 100644
>>> --- a/net/ipv4/tcp.c
>>> +++ b/net/ipv4/tcp.c
>>> @@ -280,6 +280,9 @@
>>>   #include <asm/ioctls.h>
>>>   #include <net/busy_poll.h>
>>>   
>>> +#include <net/mptcp.h>
>>> +#include "../mptcp/protocol.h"
>>> +
>>>   /* Track pending CMSGs. */
>>>   enum {
>>>   	TCP_CMSG_INQ = 1,
>>> @@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
>>>   	}
>>>   }
>>>   
>>> -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>> -				int *copied, size_t size,
>>> -				struct ubuf_info *uarg)
>>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>> +			 int *copied, size_t size,
>>> +			 struct ubuf_info *uarg)
>>>   {
>>>   	struct tcp_sock *tp = tcp_sk(sk);
>>>   	struct inet_sock *inet = inet_sk(sk);
>>> @@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>>   		}
>>>   	}
>>>   	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
>>> -	err = __inet_stream_connect(sk->sk_socket, uaddr,
>>> -				    msg->msg_namelen, flags, 1);
>>> +	if (!sk_is_mptcp(sk))
>>> +		err = __inet_stream_connect(sk->sk_socket, uaddr,
>>> +					    msg->msg_namelen, flags, 1);
>>> +	else
>>> +		err = mptcp_stream_connect(sk->sk_socket, uaddr,
>>> +					   msg->msg_namelen, msg->msg_flags);
>>
>> I guess the goal of the above change is let mptcp_stream_connect()
>> update the msk socket status, is that correct?
>>
>> However there are a few problems with lock: you must acquite the
>> subflow socket lock before calling tcp_sendmsg_fastopen() - or will see
>> subflow state corruption - but that in turn will cause a deadlock as
>>   mptcp_stream_connect() acquires the msk socket lock and then the
>> subflow socket lock.
>>
>> I think it's better leave the tcp_sendmsg_fastopen() body unchanged...
>>
>>> +
>>>   	/* fastopen_req could already be freed in __inet_stream_connect
>>>   	 * if the connection times out or gets rst
>>>   	 */
>>> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
>>> index 470045793181..8cf307e4e59c 100644
>>> --- a/net/mptcp/protocol.c
>>> +++ b/net/mptcp/protocol.c
>>> @@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
>>>   	long timeo;
>>>   
>>>   	/* we don't support FASTOPEN yet */
>>> -	if (msg->msg_flags & MSG_FASTOPEN)
>>> -		return -EOPNOTSUPP;
>>> +	if (msg->msg_flags & MSG_FASTOPEN) {
>>> +		struct socket *ssock = __mptcp_nmpc_socket(msk);
>> ... acquire the subflow socket lock here...
>>
>>>   
>>> +		if (ssock) {
>>> +			int copied_syn_fastopen = 0;
>>> +
>>> +			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
>>> +			copied += copied_syn_fastopen;
>>> +		}
>> ... and additionally handle the sock state update here. Possibly you
>> can encapsulate all the fastopen code in a new function - say
>> __mptcp_sendmsg_fastopen(), as it will be called under the msk socket
>> lock.
>>
>>
>> Side note: you should enter the fastopen branch even when
>> inet_sk(ssock->sk)->defer_connect is set
> I think we should better discuss about that at the next meeting because
> all items you are asking here is what Benjamin did in [1]:
>
> https://patchwork.kernel.org/project/mptcp/patch/20220908133829.3410092-4-benjamin.hesmans@tessares.net/
>
> The work from Dmytro helped Benjamin to start looking at that and
> propose another approach. Before the meeting, we can look at creating a
> series focussed on the sending part taking patches from both Benjamin
> and Dmytro using Benjamin's approach if that's OK. Of course both Dmytro
> and Benjamin will be credited to have worked on that.
>
> Cheers,
> Matt

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

* Re: [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 15:02     ` Matthieu Baerts
  2022-09-20 15:10       ` Dmytro Shytyi
@ 2022-09-20 15:12       ` Paolo Abeni
  1 sibling, 0 replies; 25+ messages in thread
From: Paolo Abeni @ 2022-09-20 15:12 UTC (permalink / raw)
  To: Matthieu Baerts, Dmytro Shytyi, mptcp

On Tue, 2022-09-20 at 17:02 +0200, Matthieu Baerts wrote:
> Hi Paolo, Dmytro,
> 
> On 20/09/2022 16:36, Paolo Abeni wrote:
> > On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
> > > In the following patches we will reuse modified tcp_sendmsg_fastopen().
> > > We call it from mptcp_sendmsg().
> > > 
> > > Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> > > ---
> > >  include/net/tcp.h    |  3 +++
> > >  net/ipv4/tcp.c       | 18 +++++++++++++-----
> > >  net/mptcp/protocol.c | 11 +++++++++--
> > >  3 files changed, 25 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/include/net/tcp.h b/include/net/tcp.h
> > > index 735e957f7f4b..a7d49e42470a 100644
> > > --- a/include/net/tcp.h
> > > +++ b/include/net/tcp.h
> > > @@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
> > >  			      struct request_sock *req,
> > >  			      struct tcp_fastopen_cookie *foc,
> > >  			      const struct dst_entry *dst);
> > > +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> > > +			 int *copied, size_t size,
> > > +			 struct ubuf_info *uarg);
> > >  void tcp_fastopen_init_key_once(struct net *net);
> > >  bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
> > >  			     struct tcp_fastopen_cookie *cookie);
> > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> > > index 9251c99d3cfd..d10a3cdae220 100644
> > > --- a/net/ipv4/tcp.c
> > > +++ b/net/ipv4/tcp.c
> > > @@ -280,6 +280,9 @@
> > >  #include <asm/ioctls.h>
> > >  #include <net/busy_poll.h>
> > >  
> > > +#include <net/mptcp.h>
> > > +#include "../mptcp/protocol.h"
> > > +
> > >  /* Track pending CMSGs. */
> > >  enum {
> > >  	TCP_CMSG_INQ = 1,
> > > @@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
> > >  	}
> > >  }
> > >  
> > > -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> > > -				int *copied, size_t size,
> > > -				struct ubuf_info *uarg)
> > > +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> > > +			 int *copied, size_t size,
> > > +			 struct ubuf_info *uarg)
> > >  {
> > >  	struct tcp_sock *tp = tcp_sk(sk);
> > >  	struct inet_sock *inet = inet_sk(sk);
> > > @@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> > >  		}
> > >  	}
> > >  	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
> > > -	err = __inet_stream_connect(sk->sk_socket, uaddr,
> > > -				    msg->msg_namelen, flags, 1);
> > > +	if (!sk_is_mptcp(sk))
> > > +		err = __inet_stream_connect(sk->sk_socket, uaddr,
> > > +					    msg->msg_namelen, flags, 1);
> > > +	else
> > > +		err = mptcp_stream_connect(sk->sk_socket, uaddr,
> > > +					   msg->msg_namelen, msg->msg_flags);
> > 
> > 
> > I guess the goal of the above change is let mptcp_stream_connect()
> > update the msk socket status, is that correct?
> > 
> > However there are a few problems with lock: you must acquite the
> > subflow socket lock before calling tcp_sendmsg_fastopen() - or will see
> > subflow state corruption - but that in turn will cause a deadlock as 
> >  mptcp_stream_connect() acquires the msk socket lock and then the
> > subflow socket lock.
> > 
> > I think it's better leave the tcp_sendmsg_fastopen() body unchanged...
> > 
> > > +
> > >  	/* fastopen_req could already be freed in __inet_stream_connect
> > >  	 * if the connection times out or gets rst
> > >  	 */
> > > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> > > index 470045793181..8cf307e4e59c 100644
> > > --- a/net/mptcp/protocol.c
> > > +++ b/net/mptcp/protocol.c
> > > @@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
> > >  	long timeo;
> > >  
> > >  	/* we don't support FASTOPEN yet */
> > > -	if (msg->msg_flags & MSG_FASTOPEN)
> > > -		return -EOPNOTSUPP;
> > > +	if (msg->msg_flags & MSG_FASTOPEN) {
> > > +		struct socket *ssock = __mptcp_nmpc_socket(msk);
> > 
> > ... acquire the subflow socket lock here...
> > 
> > >  
> > > +		if (ssock) {
> > > +			int copied_syn_fastopen = 0;
> > > +
> > > +			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
> > > +			copied += copied_syn_fastopen;
> > > +		}
> > 
> > ... and additionally handle the sock state update here. Possibly you
> > can encapsulate all the fastopen code in a new function - say
> > __mptcp_sendmsg_fastopen(), as it will be called under the msk socket
> > lock.
> > 
> > 
> > Side note: you should enter the fastopen branch even when 
> > inet_sk(ssock->sk)->defer_connect is set
> 
> I think we should better discuss about that at the next meeting because
> all items you are asking here is what Benjamin did in [1]:
> 
> https://patchwork.kernel.org/project/mptcp/patch/20220908133829.3410092-4-benjamin.hesmans@tessares.net/

Almost. The above lacks the msk socket state update.

Cheers,

Paolo


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

* Re: [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb()
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb() Dmytro Shytyi
@ 2022-09-20 16:02   ` Paolo Abeni
  2022-09-21  4:09     ` Dmytro Shytyi
  0 siblings, 1 reply; 25+ messages in thread
From: Paolo Abeni @ 2022-09-20 16:02 UTC (permalink / raw)
  To: Dmytro Shytyi, mptcp

On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
> In the following patches we add skb to msk->receive_queue in the MPTCP
> fastopen context.
> 
> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> ---
>  include/net/tcp.h       |  2 +-
>  net/ipv4/tcp_fastopen.c | 55 +++++++++++++++++++++++++++++++++++------
>  net/ipv4/tcp_input.c    | 11 +++++++--
>  net/mptcp/protocol.c    |  4 +--
>  net/mptcp/protocol.h    |  2 ++
>  5 files changed, 62 insertions(+), 12 deletions(-)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index a7d49e42470a..6456f90ed9ed 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1749,7 +1749,7 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
>  			      void *primary_key, void *backup_key);
>  int tcp_fastopen_get_cipher(struct net *net, struct inet_connection_sock *icsk,
>  			    u64 *key);
> -void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
> +void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req);
>  struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>  			      struct request_sock *req,
>  			      struct tcp_fastopen_cookie *foc,
> diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
> index 45cc7f1ca296..566706172828 100644
> --- a/net/ipv4/tcp_fastopen.c
> +++ b/net/ipv4/tcp_fastopen.c
> @@ -3,6 +3,7 @@
>  #include <linux/tcp.h>
>  #include <linux/rcupdate.h>
>  #include <net/tcp.h>
> +#include "../mptcp/protocol.h"
>  
>  void tcp_fastopen_init_key_once(struct net *net)
>  {
> @@ -166,8 +167,12 @@ static void tcp_fastopen_cookie_gen(struct sock *sk,
>  /* If an incoming SYN or SYNACK frame contains a payload and/or FIN,
>   * queue this additional data / FIN.
>   */
> -void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
> +void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req)
>  {
> +	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
> +	struct tcp_request_sock *tcp_r_sock = tcp_rsk(req);
> +	struct sock *socket = mptcp_subflow_ctx(sk)->conn;
> +	struct mptcp_sock *msk = mptcp_sk(socket);
>  	struct tcp_sock *tp = tcp_sk(sk);
>  
>  	if (TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)
> @@ -194,7 +199,34 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
>  	TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
>  
>  	tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
> +
> +	if (req && tp->syn_fastopen && sk_is_mptcp(sk))
> +		tcp_r_sock = tcp_rsk(req);
> +	else
> +		goto add_skb_to_sk;
> +
> +	msk->is_mptfo = 1;
> +
> +	//Solves: WARNING: at 704 _mptcp_move_skbs_from_subflow+0x5d0/0x651
> +	tp->copied_seq += tp->rcv_nxt - tcp_r_sock->rcv_isn - 1;
> +
> +	subflow->map_seq = mptcp_subflow_get_mapped_dsn(subflow);
> +
> +	//Solves: BAD mapping: ssn=0 map_seq=1 map_data_len=3
> +	subflow->ssn_offset = tp->copied_seq - 1;
> +
> +	skb_orphan(skb);
> +	skb->sk = socket;
> +	skb->destructor = mptcp_rfree;
> +	atomic_add(skb->truesize, &socket->sk_rmem_alloc);
> +	msk->rmem_fwd_alloc -= skb->truesize;
> +
> +	__skb_queue_tail(&msk->receive_queue, skb);
> +	atomic64_set(&msk->rcv_wnd_sent, mptcp_subflow_get_mapped_dsn(subflow));
> +	goto avoid_add_skb_to_sk;

AFAICS the above:

- mark the passive socket as an TFO one.
- set the mapping the DSS mapping for the TFO syn data
- bypass the usual MPTCP receive path

I think we can do all the above elsewhere, with no need to touch the
tcp code in an IMHO cleaner way, something alike the following (mostly
pseudo code, only ipv4 example, the ipv6 part should be added, too):

---
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index c7d49fb6e7bd..4e23fa9f0083 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -307,6 +307,28 @@ static struct dst_entry *subflow_v4_route_req(const struct sock *sk,
 	return NULL;
 }
 
+static int subflow_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
+				  struct flowi *fl,
+				  struct request_sock *req,
+				  struct tcp_fastopen_cookie *foc,
+				  enum tcp_synack_type synack_type,
+				  struct sk_buff *syn_skb)
+{
+	if (synack_type == TCP_SYNACK_FASTOPEN) {
+		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+
+		<mark subflow/msk as "mptfo">
+		<evenutally clear tstamp_ok, as needed depending on cookie size>
+		<dequeue the skb from sk receive queue>
+		<set the skb mapping>
+		<acquire the msk data lock>
+		<move skb into msk receive queue>
+		<call msk data_ready>
+		<release the msk data lock>
+	}
+	return tcp_request_sock_ipv4_ops.send_synack(sk, dst, fl, req, foc, synack_type, syn_skb);
+}
+
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
 static struct dst_entry *subflow_v6_route_req(const struct sock *sk,
 					      struct sk_buff *skb,
@@ -1939,6 +1960,7 @@ void __init mptcp_subflow_init(void)
 
 	subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
 	subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
+	subflow_request_sock_ipv4_ops.send_synack = subflow_v4_send_synack;
 
 	subflow_specific = ipv4_specific;
 	subflow_specific.conn_request = subflow_v4_conn_request;





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

* Re: [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet)
  2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
@ 2022-09-20 16:04   ` Paolo Abeni
  2022-09-21  4:12     ` Dmytro Shytyi
  0 siblings, 1 reply; 25+ messages in thread
From: Paolo Abeni @ 2022-09-20 16:04 UTC (permalink / raw)
  To: Dmytro Shytyi, mptcp

On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
> Fix unexpected value of subflow->map_seq (discarded and after
> retransmitted 2nd packet(1st after TFO)).

The above is confusing, it looks like the previous patches 
intentionally added a bug that is fixed here. If so it's better re-
order the series, moving this one early-on.

> We use mptcp_gen_msk_ackseq_fasopen()
> when we know this is the first chunk of data after TFO.
> 
> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> ---
>  net/mptcp/options.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 8852a13cfe62..8e937a422909 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -1212,6 +1212,11 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
>  			mpext->dsn64 = 1;
>  			mpext->mpc_map = 1;
>  			mpext->data_fin = 0;
> +			
> +			if (msk->is_mptfo) {
> +				mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
> +				mpext->data_seq = READ_ONCE(msk->ack_seq);
> +			}

With the changes suggested on the next patch the above chunk should not
be needed.

In any case I think it's better to properly keep msk->ack_seq unchanged
after that the TFO syn data landed into the msk receive queue, instead
of resetting it later.

Cheers,

Paolo


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

* Re: [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb()
  2022-09-20 16:02   ` Paolo Abeni
@ 2022-09-21  4:09     ` Dmytro Shytyi
  0 siblings, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-21  4:09 UTC (permalink / raw)
  To: Paolo Abeni, mptcp

Thank you Paolo for this interesting comment with great approach.

Version 9 of mptfo is coming with implemented and working 
"subflow_v4_send_synack()"


On 9/20/2022 6:02 PM, Paolo Abeni wrote:
> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>> In the following patches we add skb to msk->receive_queue in the MPTCP
>> fastopen context.
>>
>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>> ---
>>   include/net/tcp.h       |  2 +-
>>   net/ipv4/tcp_fastopen.c | 55 +++++++++++++++++++++++++++++++++++------
>>   net/ipv4/tcp_input.c    | 11 +++++++--
>>   net/mptcp/protocol.c    |  4 +--
>>   net/mptcp/protocol.h    |  2 ++
>>   5 files changed, 62 insertions(+), 12 deletions(-)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index a7d49e42470a..6456f90ed9ed 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1749,7 +1749,7 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
>>   			      void *primary_key, void *backup_key);
>>   int tcp_fastopen_get_cipher(struct net *net, struct inet_connection_sock *icsk,
>>   			    u64 *key);
>> -void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
>> +void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req);
>>   struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>>   			      struct request_sock *req,
>>   			      struct tcp_fastopen_cookie *foc,
>> diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
>> index 45cc7f1ca296..566706172828 100644
>> --- a/net/ipv4/tcp_fastopen.c
>> +++ b/net/ipv4/tcp_fastopen.c
>> @@ -3,6 +3,7 @@
>>   #include <linux/tcp.h>
>>   #include <linux/rcupdate.h>
>>   #include <net/tcp.h>
>> +#include "../mptcp/protocol.h"
>>   
>>   void tcp_fastopen_init_key_once(struct net *net)
>>   {
>> @@ -166,8 +167,12 @@ static void tcp_fastopen_cookie_gen(struct sock *sk,
>>   /* If an incoming SYN or SYNACK frame contains a payload and/or FIN,
>>    * queue this additional data / FIN.
>>    */
>> -void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
>> +void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request_sock *req)
>>   {
>> +	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
>> +	struct tcp_request_sock *tcp_r_sock = tcp_rsk(req);
>> +	struct sock *socket = mptcp_subflow_ctx(sk)->conn;
>> +	struct mptcp_sock *msk = mptcp_sk(socket);
>>   	struct tcp_sock *tp = tcp_sk(sk);
>>   
>>   	if (TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)
>> @@ -194,7 +199,34 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb)
>>   	TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
>>   
>>   	tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
>> +
>> +	if (req && tp->syn_fastopen && sk_is_mptcp(sk))
>> +		tcp_r_sock = tcp_rsk(req);
>> +	else
>> +		goto add_skb_to_sk;
>> +
>> +	msk->is_mptfo = 1;
>> +
>> +	//Solves: WARNING: at 704 _mptcp_move_skbs_from_subflow+0x5d0/0x651
>> +	tp->copied_seq += tp->rcv_nxt - tcp_r_sock->rcv_isn - 1;
>> +
>> +	subflow->map_seq = mptcp_subflow_get_mapped_dsn(subflow);
>> +
>> +	//Solves: BAD mapping: ssn=0 map_seq=1 map_data_len=3
>> +	subflow->ssn_offset = tp->copied_seq - 1;
>> +
>> +	skb_orphan(skb);
>> +	skb->sk = socket;
>> +	skb->destructor = mptcp_rfree;
>> +	atomic_add(skb->truesize, &socket->sk_rmem_alloc);
>> +	msk->rmem_fwd_alloc -= skb->truesize;
>> +
>> +	__skb_queue_tail(&msk->receive_queue, skb);
>> +	atomic64_set(&msk->rcv_wnd_sent, mptcp_subflow_get_mapped_dsn(subflow));
>> +	goto avoid_add_skb_to_sk;
> AFAICS the above:
>
> - mark the passive socket as an TFO one.
> - set the mapping the DSS mapping for the TFO syn data
> - bypass the usual MPTCP receive path
>
> I think we can do all the above elsewhere, with no need to touch the
> tcp code in an IMHO cleaner way, something alike the following (mostly
> pseudo code, only ipv4 example, the ipv6 part should be added, too):
>
> ---
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index c7d49fb6e7bd..4e23fa9f0083 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -307,6 +307,28 @@ static struct dst_entry *subflow_v4_route_req(const struct sock *sk,
>   	return NULL;
>   }
>   
> +static int subflow_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
> +				  struct flowi *fl,
> +				  struct request_sock *req,
> +				  struct tcp_fastopen_cookie *foc,
> +				  enum tcp_synack_type synack_type,
> +				  struct sk_buff *syn_skb)
> +{
> +	if (synack_type == TCP_SYNACK_FASTOPEN) {
> +		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
> +
> +		<mark subflow/msk as "mptfo">
> +		<evenutally clear tstamp_ok, as needed depending on cookie size>
> +		<dequeue the skb from sk receive queue>
> +		<set the skb mapping>
> +		<acquire the msk data lock>
> +		<move skb into msk receive queue>
> +		<call msk data_ready>
> +		<release the msk data lock>
> +	}
> +	return tcp_request_sock_ipv4_ops.send_synack(sk, dst, fl, req, foc, synack_type, syn_skb);
> +}
> +
>   #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>   static struct dst_entry *subflow_v6_route_req(const struct sock *sk,
>   					      struct sk_buff *skb,
> @@ -1939,6 +1960,7 @@ void __init mptcp_subflow_init(void)
>   
>   	subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
>   	subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
> +	subflow_request_sock_ipv4_ops.send_synack = subflow_v4_send_synack;
>   
>   	subflow_specific = ipv4_specific;
>   	subflow_specific.conn_request = subflow_v4_conn_request;
>
>
>
>

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

* Re: [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet)
  2022-09-20 16:04   ` Paolo Abeni
@ 2022-09-21  4:12     ` Dmytro Shytyi
  0 siblings, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-21  4:12 UTC (permalink / raw)
  To: Paolo Abeni, mptcp

In v9 I dropped the previous patch and keep only this. I propose to have 
a look at v9 when I will submit it.

Thanks,

Dmytro.

On 9/20/2022 6:04 PM, Paolo Abeni wrote:
> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>> Fix unexpected value of subflow->map_seq (discarded and after
>> retransmitted 2nd packet(1st after TFO)).
> The above is confusing, it looks like the previous patches
> intentionally added a bug that is fixed here. If so it's better re-
> order the series, moving this one early-on.
>
>> We use mptcp_gen_msk_ackseq_fasopen()
>> when we know this is the first chunk of data after TFO.
>>
>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>> ---
>>   net/mptcp/options.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>> index 8852a13cfe62..8e937a422909 100644
>> --- a/net/mptcp/options.c
>> +++ b/net/mptcp/options.c
>> @@ -1212,6 +1212,11 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
>>   			mpext->dsn64 = 1;
>>   			mpext->mpc_map = 1;
>>   			mpext->data_fin = 0;
>> +			
>> +			if (msk->is_mptfo) {
>> +				mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
>> +				mpext->data_seq = READ_ONCE(msk->ack_seq);
>> +			}
> With the changes suggested on the next patch the above chunk should not
> be needed.
>
> In any case I think it's better to properly keep msk->ack_seq unchanged
> after that the TFO syn data landed into the msk receive queue, instead
> of resetting it later.
>
> Cheers,
>
> Paolo
>

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

* Re: [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans
  2022-09-20 14:56   ` Paolo Abeni
@ 2022-09-21  4:15     ` Dmytro Shytyi
  0 siblings, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-21  4:15 UTC (permalink / raw)
  To: Paolo Abeni, mptcp


On 9/20/2022 4:56 PM, Paolo Abeni wrote:
> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>> Introduce mptfo variables for msk and options.
>> Also fix the infinite retransmissions in the end of second session.
> I think the above sentence belongs more the changelog than to the
> commit message itself.

Fixed in v9.


>> The variable 2nd ack received in struct mptcp_options_received identifies the
>> received ack on the listener side during 3way handshake in mptfo context
>> and miningless alone if used alone. It is further used(checked)
>> in conjunction in the same "if" statement with variable is_mptfo
>> from struct mptcp_sock.
>>
>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>> ---
>>   net/mptcp/fastopen.c | 14 ++++++++++++++
>>   net/mptcp/options.c  |  4 ++++
>>   net/mptcp/protocol.h |  6 +++++-
>>   3 files changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
>> index 9ef49a2d2ea2..92885e459f93 100644
>> --- a/net/mptcp/fastopen.c
>> +++ b/net/mptcp/fastopen.c
>> @@ -30,3 +30,17 @@ int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
>>   
>>   	return ret;
>>   }
>> +
>> +void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
>> +				   struct mptcp_options_received mp_opt)
>> +{
>> +	u64 ack_seq;
>> +
>> +	msk->can_ack = true;
>> +	msk->remote_key = mp_opt.sndr_key;
> likely the above two statements need WRITE_ONCE() annotation.

I have added in v9 WRITE_ONCE() to the above two statements.


> Additionally it's better to add some safeguards here:
> - ssk should be in TCP_SYN_RECV state - to be verified, it's guess and
> I haven't check it yet.
> - msk should be in the same state of the ssk subflow.
>
>> +	mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
>> +	ack_seq++;
>> +	WRITE_ONCE(msk->ack_seq, ack_seq);
>> +	pr_debug("ack_seq=%llu sndr_key=%llu", msk->ack_seq, mp_opt.sndr_key);
>> +	atomic64_set(&msk->rcv_wnd_sent, ack_seq);
>> +}
>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>> index 30d289044e71..8852a13cfe62 100644
>> --- a/net/mptcp/options.c
>> +++ b/net/mptcp/options.c
>> @@ -91,6 +91,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
>>   			ptr += 8;
>>   		}
>>   		if (opsize >= TCPOLEN_MPTCP_MPC_ACK) {
>> +			mp_opt->hns_2nd_ack_rcvd = 1;
> Not needed, see below...


Removed in v9

>>   			mp_opt->rcvr_key = get_unaligned_be64(ptr);
>>   			ptr += 8;
>>   		}
>> @@ -1124,6 +1125,9 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
>>   		return sk->sk_state != TCP_CLOSE;
>>   
>>   	if (unlikely(mp_opt.suboptions != OPTION_MPTCP_DSS)) {
>> +		if (mp_opt.suboptions & OPTIONS_MPTCP_MPC && mp_opt.hns_2nd_ack_rcvd && msk->is_mptfo)
> You can simply check for:
>
> 		if (mp_opt.suboptions & OPTIONS_MPTCP_MPC_ACK) && msk->is_mptfo)


Removed in v9

>> +			mptcp_gen_msk_ackseq_fastopen(msk, subflow, mp_opt);
>> +
>>   		if ((mp_opt.suboptions & OPTION_MPTCP_FASTCLOSE) &&
>>   		    msk->local_key == mp_opt.rcvr_key) {
>>   			WRITE_ONCE(msk->rcv_fastclose, true);
>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>> index 57596cdfb1f9..3b9a349a7080 100644
>> --- a/net/mptcp/protocol.h
>> +++ b/net/mptcp/protocol.h
>> @@ -155,7 +155,8 @@ struct mptcp_options_received {
>>   		echo:1,
>>   		backup:1,
>>   		deny_join_id0:1,
>> -		__unused:2;
>> +		__unused:1;
>> +	u8	hns_2nd_ack_rcvd:1;
> ... again not needed, see above ;)
Removed in v9
>>   	u8	join_id;
>>   	u64	thmac;
>>   	u8	hmac[MPTCPOPT_HMAC_LEN];
>> @@ -282,6 +283,7 @@ struct mptcp_sock {
>>   	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
>>   	bool		csum_enabled;
>>   	bool		allow_infinite_fallback;
>> +	bool		is_mptfo;
>>   	u8		mpc_endpoint_id;
>>   	u8		recvmsg_inq:1,
>>   			cork:1,
>> @@ -842,6 +844,8 @@ int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_l
>>   // Fast Open Mechanism functions begin
>>   int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
>>   				      unsigned int optlen);
>> +void mptcp_gen_msk_ackseq_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
>> +				   struct mptcp_options_received mp_opt);
>>   // Fast Open Mechanism functions end
>>   
>>   static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)

Best,

Dmytro.


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

* Re: [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen()
  2022-09-20 14:36   ` Paolo Abeni
  2022-09-20 15:02     ` Matthieu Baerts
@ 2022-09-21  4:20     ` Dmytro Shytyi
  1 sibling, 0 replies; 25+ messages in thread
From: Dmytro Shytyi @ 2022-09-21  4:20 UTC (permalink / raw)
  To: Paolo Abeni, mptcp


On 9/20/2022 4:36 PM, Paolo Abeni wrote:
> On Tue, 2022-09-20 at 14:52 +0200, Dmytro Shytyi wrote:
>> In the following patches we will reuse modified tcp_sendmsg_fastopen().
>> We call it from mptcp_sendmsg().
>>
>> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
>> ---
>>   include/net/tcp.h    |  3 +++
>>   net/ipv4/tcp.c       | 18 +++++++++++++-----
>>   net/mptcp/protocol.c | 11 +++++++++--
>>   3 files changed, 25 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index 735e957f7f4b..a7d49e42470a 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1754,6 +1754,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
>>   			      struct request_sock *req,
>>   			      struct tcp_fastopen_cookie *foc,
>>   			      const struct dst_entry *dst);
>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> +			 int *copied, size_t size,
>> +			 struct ubuf_info *uarg);
>>   void tcp_fastopen_init_key_once(struct net *net);
>>   bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
>>   			     struct tcp_fastopen_cookie *cookie);
>> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
>> index 9251c99d3cfd..d10a3cdae220 100644
>> --- a/net/ipv4/tcp.c
>> +++ b/net/ipv4/tcp.c
>> @@ -280,6 +280,9 @@
>>   #include <asm/ioctls.h>
>>   #include <net/busy_poll.h>
>>   
>> +#include <net/mptcp.h>
>> +#include "../mptcp/protocol.h"
>> +
>>   /* Track pending CMSGs. */
>>   enum {
>>   	TCP_CMSG_INQ = 1,
>> @@ -1162,9 +1165,9 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
>>   	}
>>   }
>>   
>> -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> -				int *copied, size_t size,
>> -				struct ubuf_info *uarg)
>> +int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>> +			 int *copied, size_t size,
>> +			 struct ubuf_info *uarg)
>>   {
>>   	struct tcp_sock *tp = tcp_sk(sk);
>>   	struct inet_sock *inet = inet_sk(sk);
>> @@ -1197,8 +1200,13 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
>>   		}
>>   	}
>>   	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
>> -	err = __inet_stream_connect(sk->sk_socket, uaddr,
>> -				    msg->msg_namelen, flags, 1);
>> +	if (!sk_is_mptcp(sk))
>> +		err = __inet_stream_connect(sk->sk_socket, uaddr,
>> +					    msg->msg_namelen, flags, 1);
>> +	else
>> +		err = mptcp_stream_connect(sk->sk_socket, uaddr,
>> +					   msg->msg_namelen, msg->msg_flags);
>
> I guess the goal of the above change is let mptcp_stream_connect()
> update the msk socket status, is that correct?
>
> However there are a few problems with lock: you must acquite the
> subflow socket lock before calling tcp_sendmsg_fastopen() - or will see
> subflow state corruption - but that in turn will cause a deadlock as
>   mptcp_stream_connect() acquires the msk socket lock and then the
> subflow socket lock.
>
> I think it's better leave the tcp_sendmsg_fastopen() body unchanged...


In v9 I still modify the tcp_sendmsg_fastopen() a little bit with adding 
some locks.

>> +
>>   	/* fastopen_req could already be freed in __inet_stream_connect
>>   	 * if the connection times out or gets rst
>>   	 */
>> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
>> index 470045793181..8cf307e4e59c 100644
>> --- a/net/mptcp/protocol.c
>> +++ b/net/mptcp/protocol.c
>> @@ -1673,9 +1673,16 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
>>   	long timeo;
>>   
>>   	/* we don't support FASTOPEN yet */
>> -	if (msg->msg_flags & MSG_FASTOPEN)
>> -		return -EOPNOTSUPP;
>> +	if (msg->msg_flags & MSG_FASTOPEN) {
>> +		struct socket *ssock = __mptcp_nmpc_socket(msk);
> ... acquire the subflow socket lock here...
Some locks are acquired in v9.
>>   
>> +		if (ssock) {
>> +			int copied_syn_fastopen = 0;
>> +
>> +			ret = tcp_sendmsg_fastopen(ssock->sk, msg, &copied_syn_fastopen, len, NULL);
>> +			copied += copied_syn_fastopen;
>> +		}
> ... and additionally handle the sock state update here. Possibly you
> can encapsulate all the fastopen code in a new function - say
> __mptcp_sendmsg_fastopen(), as it will be called under the msk socket
> lock.
>
>
> Side note: you should enter the fastopen branch even when
> inet_sk(ssock->sk)->defer_connect is set

I tried to add this (defer_connect) in v9, but didn't check if it works.


> Cheers,
>
> Paolo

Best,

Dmytro.


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

* Re: selftests: mptfo initiator/listener: Build Failure
  2022-10-01  3:15 [RFC PATCH mptcp-next v13 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
@ 2022-10-06 12:51 ` MPTCP CI
  0 siblings, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-10-06 12:51 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://patchwork.kernel.org/project/mptcp/patch/20221001031502.29152-8-dmytro@shytyi.net/
  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/3197013753

Status: failure
Initiator: MPTCPimporter
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/7c22bca6e0ab

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

* Re: selftests: mptfo initiator/listener: Build Failure
  2022-09-27 22:53 [RFC PATCH mptcp-next v12 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
@ 2022-09-27 23:23 ` MPTCP CI
  0 siblings, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-09-27 23:23 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://patchwork.kernel.org/project/mptcp/patch/20220927225341.14165-8-dmytro@shytyi.net/
  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/3139594634

Status: failure
Initiator: MPTCPimporter
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/4285eae5e20b

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

* Re: selftests: mptfo initiator/listener: Build Failure
  2022-09-21 12:55 [RFC PATCH mptcp-next v9 6/6] selftests: mptfo initiator/listener Dmytro Shytyi
@ 2022-09-21 13:38 ` MPTCP CI
  0 siblings, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-09-21 13:38 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://patchwork.kernel.org/project/mptcp/patch/20220921125558.19483-7-dmytro@shytyi.net/
  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/3098139757

Status: failure
Initiator: MPTCPimporter
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/5eb61bb88e80

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

* Re: selftests: mptfo initiator/listener: Build Failure
  2022-09-15 23:56 [RFC PATCH mptcp-next v6 9/9] selftests: mptfo initiator/listener Dmytro Shytyi
@ 2022-09-16  1:35 ` MPTCP CI
  0 siblings, 0 replies; 25+ messages in thread
From: MPTCP CI @ 2022-09-16  1:35 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: mptcp

Hi Dmytro,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://patchwork.kernel.org/project/mptcp/patch/20220915235604.26018-10-dmytro@shytyi.net/
  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/3064785105

Status: failure
Initiator: MPTCPimporter
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/a04a47ac6e30

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (Tessares)

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

end of thread, other threads:[~2022-10-06 12:51 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-20 12:52 [RFC PATCH mptcp-next v8 0/7] mptcp: Fast Open Mechanism Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 1/7] add mptcp_stream_connect to protocol.h Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 2/7] add mptcp_setsockopt_fastopen Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 3/7] reuse tcp_sendmsg_fastopen() Dmytro Shytyi
2022-09-20 14:36   ` Paolo Abeni
2022-09-20 15:02     ` Matthieu Baerts
2022-09-20 15:10       ` Dmytro Shytyi
2022-09-20 15:12       ` Paolo Abeni
2022-09-21  4:20     ` Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 4/7] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
2022-09-20 14:56   ` Paolo Abeni
2022-09-21  4:15     ` Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 5/7] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
2022-09-20 16:04   ` Paolo Abeni
2022-09-21  4:12     ` Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 6/7] add skb to mskq in tcp_fastopen_add_skb() Dmytro Shytyi
2022-09-20 16:02   ` Paolo Abeni
2022-09-21  4:09     ` Dmytro Shytyi
2022-09-20 12:52 ` [RFC PATCH mptcp-next v8 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
2022-09-20 13:17   ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
2022-09-20 14:40   ` selftests: mptfo initiator/listener: Tests Results MPTCP CI
  -- strict thread matches above, loose matches on Subject: below --
2022-10-01  3:15 [RFC PATCH mptcp-next v13 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
2022-10-06 12:51 ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
2022-09-27 22:53 [RFC PATCH mptcp-next v12 7/7] selftests: mptfo initiator/listener Dmytro Shytyi
2022-09-27 23:23 ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
2022-09-21 12:55 [RFC PATCH mptcp-next v9 6/6] selftests: mptfo initiator/listener Dmytro Shytyi
2022-09-21 13:38 ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
2022-09-15 23:56 [RFC PATCH mptcp-next v6 9/9] selftests: mptfo initiator/listener Dmytro Shytyi
2022-09-16  1:35 ` selftests: mptfo initiator/listener: Build Failure MPTCP CI

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).