All of lore.kernel.org
 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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-21  2:05   ` kernel test robot
  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, 2 replies; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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
  2022-09-21  2:05   ` kernel test robot
  1 sibling, 2 replies; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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-21  2:05   ` kernel test robot
  1 sibling, 0 replies; 22+ messages in thread
From: kernel test robot @ 2022-09-21  2:05 UTC (permalink / raw)
  To: Dmytro Shytyi; +Cc: llvm, kbuild-all

Hi Dmytro,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on mptcp/export]
[cannot apply to shuah-kselftest/next linus/master v6.0-rc6 next-20220920]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmytro-Shytyi/mptcp-Fast-Open-Mechanism/20220920-205817
base:   https://github.com/multipath-tcp/mptcp_net-next.git export
config: s390-randconfig-r035-20220921 (https://download.01.org/0day-ci/archive/20220921/202209210945.AC7D79Qb-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/0196a0ed5930975013f9dc240d52b0b10e849b98
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Dmytro-Shytyi/mptcp-Fast-Open-Mechanism/20220920-205817
        git checkout 0196a0ed5930975013f9dc240d52b0b10e849b98
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash net/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from net/ipv4/tcp.c:252:
   In file included from include/linux/inet_diag.h:5:
   In file included from include/net/netlink.h:6:
   In file included from include/linux/netlink.h:7:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
                                                             ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
   #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
                                                        ^
   In file included from net/ipv4/tcp.c:252:
   In file included from include/linux/inet_diag.h:5:
   In file included from include/net/netlink.h:6:
   In file included from include/linux/netlink.h:7:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
   #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
                                                        ^
   In file included from net/ipv4/tcp.c:252:
   In file included from include/linux/inet_diag.h:5:
   In file included from include/net/netlink.h:6:
   In file included from include/linux/netlink.h:7:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:250:8: error: redefinition of 'mptcp_sock'
   struct mptcp_sock {
          ^
   include/net/mptcp.h:315:8: note: previous definition is here
   struct mptcp_sock { };
          ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:321:10: note: expanded from macro '__native_word'
           (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
                   ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:321:39: note: expanded from macro '__native_word'
           (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
                                                ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:322:10: note: expanded from macro '__native_word'
            sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
                   ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:322:38: note: expanded from macro '__native_word'
            sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
                                               ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:48: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                                         ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:65: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                    ^
   include/linux/compiler_types.h:310:13: note: expanded from macro '__unqual_scalar_typeof'
                   _Generic((x),                                           \
                             ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:65: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                    ^
   include/linux/compiler_types.h:317:15: note: expanded from macro '__unqual_scalar_typeof'
                            default: (x)))
                                      ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:67: error: no member named 'rmem_released' in 'struct mptcp_sock'
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                                                              ~~~~~~~~~~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:72: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                           ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:336:41: error: invalid operands to binary expression ('int' and 'void')
           return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:321:10: note: expanded from macro '__native_word'
           (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
                   ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:321:39: note: expanded from macro '__native_word'
           (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
                                                ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:322:10: note: expanded from macro '__native_word'
            sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
                   ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                            ^
   include/linux/compiler_types.h:322:38: note: expanded from macro '__native_word'
            sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
                                               ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:49:33: note: expanded from macro 'READ_ONCE'
           compiletime_assert_rwonce_type(x);                              \
                                          ^
   include/asm-generic/rwonce.h:36:48: note: expanded from macro 'compiletime_assert_rwonce_type'
           compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),  \
                                                         ^
   include/linux/compiler_types.h:354:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:342:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:334:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:65: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                    ^
   include/linux/compiler_types.h:310:13: note: expanded from macro '__unqual_scalar_typeof'
                   _Generic((x),                                           \
                             ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:65: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                    ^
   include/linux/compiler_types.h:317:15: note: expanded from macro '__unqual_scalar_typeof'
                            default: (x)))
                                      ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:24: error: no member named 'first_pending' in 'struct mptcp_sock'
           return READ_ONCE(msk->first_pending);
                            ~~~  ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
           __READ_ONCE(x);                                                 \
                       ^
   include/asm-generic/rwonce.h:44:72: note: expanded from macro '__READ_ONCE'
   #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
                                                                           ^
   In file included from net/ipv4/tcp.c:284:
>> net/ipv4/../mptcp/protocol.h:348:9: error: returning 'void' from a function with incompatible result type 'struct mptcp_data_frag *'
           return READ_ONCE(msk->first_pending);
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/asm-generic/rwonce.h:47:28: note: expanded from macro 'READ_ONCE'
   #define READ_ONCE(x)                                                    \
                                                                           ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   12 warnings and 20 errors generated.


vim +/mptcp_sock +250 net/ipv4/../mptcp/protocol.h

18b683bff89d46 Paolo Abeni      2020-03-27  248  
f870fa0b576884 Mat Martineau    2020-01-21  249  /* MPTCP connection sock */
f870fa0b576884 Mat Martineau    2020-01-21 @250  struct mptcp_sock {
f870fa0b576884 Mat Martineau    2020-01-21  251  	/* inet_connection_sock must be the first member */
f870fa0b576884 Mat Martineau    2020-01-21  252  	struct inet_connection_sock sk;
cec37a6e41aae7 Peter Krystad    2020-01-21  253  	u64		local_key;
cec37a6e41aae7 Peter Krystad    2020-01-21  254  	u64		remote_key;
6d0060f600adfd Mat Martineau    2020-01-21  255  	u64		write_seq;
eaa2ffabfc3558 Paolo Abeni      2020-11-16  256  	u64		snd_nxt;
6d0060f600adfd Mat Martineau    2020-01-21  257  	u64		ack_seq;
f3589be0c420a3 Paolo Abeni      2022-05-04  258  	atomic64_t	rcv_wnd_sent;
3721b9b64676b3 Mat Martineau    2020-07-28  259  	u64		rcv_data_fin_seq;
6511882cdd82d6 Paolo Abeni      2021-10-26  260  	int		rmem_fwd_alloc;
d5f49190def61c Paolo Abeni      2020-09-14  261  	struct sock	*last_snd;
d5f49190def61c Paolo Abeni      2020-09-14  262  	int		snd_burst;
ea4ca586b16ff2 Paolo Abeni      2020-11-19  263  	int		old_wspace;
1e1d9d6f119c55 Paolo Abeni      2021-08-13  264  	u64		recovery_snd_nxt;	/* in recovery mode accept up to this seq;
1e1d9d6f119c55 Paolo Abeni      2021-08-13  265  						 * recovery related fields are under data_lock
1e1d9d6f119c55 Paolo Abeni      2021-08-13  266  						 * protection
1e1d9d6f119c55 Paolo Abeni      2021-08-13  267  						 */
7439d687b79cbb Paolo Abeni      2020-11-27  268  	u64		snd_una;
7439d687b79cbb Paolo Abeni      2020-11-27  269  	u64		wnd_end;
b51f9b80c032e1 Paolo Abeni      2020-03-27  270  	unsigned long	timer_ival;
79c0949e9a09f6 Peter Krystad    2020-01-21  271  	u32		token;
879526030c8b5e Paolo Abeni      2020-11-27  272  	int		rmem_released;
648ef4b88673da Mat Martineau    2020-01-21  273  	unsigned long	flags;
e9d09baca67625 Paolo Abeni      2022-01-06  274  	unsigned long	cb_flags;
e9d09baca67625 Paolo Abeni      2022-01-06  275  	unsigned long	push_pending;
1e1d9d6f119c55 Paolo Abeni      2021-08-13  276  	bool		recovery;		/* closing subflow write queue reinjected */
d22f4988ffecbe Christoph Paasch 2020-01-21  277  	bool		can_ack;
b93df08ccda326 Paolo Abeni      2020-07-23  278  	bool		fully_established;
3721b9b64676b3 Mat Martineau    2020-07-28  279  	bool		rcv_data_fin;
7279da6145bbb2 Mat Martineau    2020-07-28  280  	bool		snd_data_fin_enable;
50c504a20a754c Florian Westphal 2020-12-10  281  	bool		rcv_fastclose;
37198e93ced707 Davide Caratti   2020-10-06  282  	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
752e906732c694 Geliang Tang     2021-06-17  283  	bool		csum_enabled;
0530020a7c8f22 Geliang Tang     2022-04-22  284  	bool		allow_infinite_fallback;
3ad14f54bd7448 Paolo Abeni      2022-07-11  285  	u8		mpc_endpoint_id;
4f6e14bd19d6de Maxim Galaganov  2021-12-03  286  	u8		recvmsg_inq:1,
4f6e14bd19d6de Maxim Galaganov  2021-12-03  287  			cork:1,
4f6e14bd19d6de Maxim Galaganov  2021-12-03  288  			nodelay:1;
80992017150b4e Paolo Abeni      2020-02-26  289  	struct work_struct work;
ab174ad8ef7627 Paolo Abeni      2020-09-14  290  	struct sk_buff  *ooo_last_skb;
ab174ad8ef7627 Paolo Abeni      2020-09-14  291  	struct rb_root  out_of_order_queue;
879526030c8b5e Paolo Abeni      2020-11-27  292  	struct sk_buff_head receive_queue;
cec37a6e41aae7 Peter Krystad    2020-01-21  293  	struct list_head conn_list;
18b683bff89d46 Paolo Abeni      2020-03-27  294  	struct list_head rtx_queue;
f0e6a4cf11f164 Paolo Abeni      2020-11-16  295  	struct mptcp_data_frag *first_pending;
ec3edaa7ca6ce0 Peter Krystad    2020-03-27  296  	struct list_head join_list;
f870fa0b576884 Mat Martineau    2020-01-21  297  	struct socket	*subflow; /* outgoing connect/listener/!mp_capable */
8ab183deb26a3b Paolo Abeni      2020-01-21  298  	struct sock	*first;
1b1c7a0ef7f323 Peter Krystad    2020-03-27  299  	struct mptcp_pm_data	pm;
a6deddbeb5662f Geliang Tang     2022-09-20  300  	struct mptcp_sched_ops	*sched;
a6b118febbab3f Florian Westphal 2020-06-30  301  	struct {
a6b118febbab3f Florian Westphal 2020-06-30  302  		u32	space;	/* bytes copied in last measurement window */
a6b118febbab3f Florian Westphal 2020-06-30  303  		u32	copied; /* bytes copied in this measurement window */
a6b118febbab3f Florian Westphal 2020-06-30  304  		u64	time;	/* start time of measurement window */
a6b118febbab3f Florian Westphal 2020-06-30  305  		u64	rtt_us; /* last maximum rtt of subflows */
a6b118febbab3f Florian Westphal 2020-06-30  306  	} rcvq_space;
df00b087da24c0 Florian Westphal 2021-04-15  307  
df00b087da24c0 Florian Westphal 2021-04-15  308  	u32 setsockopt_seq;
20b5759f21cf53 Paolo Abeni      2021-05-25  309  	char		ca_name[TCP_CA_NAME_MAX];
6aeed9045071f2 Paolo Abeni      2022-06-27  310  	struct mptcp_sock	*dl_next;
f870fa0b576884 Mat Martineau    2020-01-21  311  };
f870fa0b576884 Mat Martineau    2020-01-21  312  
879526030c8b5e Paolo Abeni      2020-11-27  313  #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock)
879526030c8b5e Paolo Abeni      2020-11-27  314  #define mptcp_data_unlock(sk) spin_unlock_bh(&(sk)->sk_lock.slock)
879526030c8b5e Paolo Abeni      2020-11-27  315  
cec37a6e41aae7 Peter Krystad    2020-01-21  316  #define mptcp_for_each_subflow(__msk, __subflow)			\
cec37a6e41aae7 Peter Krystad    2020-01-21  317  	list_for_each_entry(__subflow, &((__msk)->conn_list), node)
5efbf6f7f076c6 Matthieu Baerts  2022-09-06  318  #define mptcp_for_each_subflow_safe(__msk, __subflow, __tmp)			\
5efbf6f7f076c6 Matthieu Baerts  2022-09-06  319  	list_for_each_entry_safe(__subflow, __tmp, &((__msk)->conn_list), node)
cec37a6e41aae7 Peter Krystad    2020-01-21  320  
3abc05d9ef6fe9 Florian Westphal 2021-02-04  321  static inline void msk_owned_by_me(const struct mptcp_sock *msk)
3abc05d9ef6fe9 Florian Westphal 2021-02-04  322  {
3abc05d9ef6fe9 Florian Westphal 2021-02-04  323  	sock_owned_by_me((const struct sock *)msk);
3abc05d9ef6fe9 Florian Westphal 2021-02-04  324  }
3abc05d9ef6fe9 Florian Westphal 2021-02-04  325  
f870fa0b576884 Mat Martineau    2020-01-21  326  static inline struct mptcp_sock *mptcp_sk(const struct sock *sk)
f870fa0b576884 Mat Martineau    2020-01-21  327  {
f870fa0b576884 Mat Martineau    2020-01-21  328  	return (struct mptcp_sock *)sk;
f870fa0b576884 Mat Martineau    2020-01-21  329  }
f870fa0b576884 Mat Martineau    2020-01-21  330  
ce599c516386f0 Paolo Abeni      2021-07-09  331  /* the msk socket don't use the backlog, also account for the bulk
ce599c516386f0 Paolo Abeni      2021-07-09  332   * free memory
ce599c516386f0 Paolo Abeni      2021-07-09  333   */
ce599c516386f0 Paolo Abeni      2021-07-09  334  static inline int __mptcp_rmem(const struct sock *sk)
ce599c516386f0 Paolo Abeni      2021-07-09  335  {
ce599c516386f0 Paolo Abeni      2021-07-09 @336  	return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
ce599c516386f0 Paolo Abeni      2021-07-09  337  }
ce599c516386f0 Paolo Abeni      2021-07-09  338  
ea4ca586b16ff2 Paolo Abeni      2020-11-19  339  static inline int __mptcp_space(const struct sock *sk)
ea4ca586b16ff2 Paolo Abeni      2020-11-19  340  {
ce599c516386f0 Paolo Abeni      2021-07-09  341  	return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf) - __mptcp_rmem(sk));
ea4ca586b16ff2 Paolo Abeni      2020-11-19  342  }
ea4ca586b16ff2 Paolo Abeni      2020-11-19  343  
f0e6a4cf11f164 Paolo Abeni      2020-11-16  344  static inline struct mptcp_data_frag *mptcp_send_head(const struct sock *sk)
f0e6a4cf11f164 Paolo Abeni      2020-11-16  345  {
f0e6a4cf11f164 Paolo Abeni      2020-11-16  346  	const struct mptcp_sock *msk = mptcp_sk(sk);
f0e6a4cf11f164 Paolo Abeni      2020-11-16  347  
f0e6a4cf11f164 Paolo Abeni      2020-11-16 @348  	return READ_ONCE(msk->first_pending);
f0e6a4cf11f164 Paolo Abeni      2020-11-16  349  }
f0e6a4cf11f164 Paolo Abeni      2020-11-16  350  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread

end of thread, other threads:[~2022-09-21  4:20 UTC | newest]

Thread overview: 22+ 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-21  2:05   ` kernel test robot
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.