* [RFC PATCH mptcp-next v6 1/9] Add separate fastopen.c file.
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
@ 2022-09-15 23:55 ` Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 2/9] Initiator: MSG_FASTOPEN sendto(). request cookie Dmytro Shytyi
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:55 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Add separate *.c file. Function prototypes are coming to protocol.h
(Suggestion of @palbeni (JUN 17))
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/Makefile | 2 +-
net/mptcp/fastopen.c | 5 +++++
2 files changed, 6 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..0c9ef6f5d528
--- /dev/null
+++ b/net/mptcp/fastopen.c
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * MPTCP Fast Open Mechanism. Copyright (c) 2021-2022, Dmytro SHYTYI
+ */
+
+#include "protocol.h"
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 2/9] Initiator: MSG_FASTOPEN sendto(). request cookie
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 1/9] Add separate fastopen.c file Dmytro Shytyi
@ 2022-09-15 23:55 ` Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 3/9] rfree(), rmem_uncharge() prototypes to protocol.h Dmytro Shytyi
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:55 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Initiator: MSG_FASTOPEN in sendto triggers the mptcp_sendsmg_fastopen.
It requests a MPTFO cookie.
Suggestion @palbeni(JAN 17): 'split the patch in several small one'.
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/fastopen.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
net/mptcp/protocol.c | 4 ++--
net/mptcp/protocol.h | 6 ++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 0c9ef6f5d528..9974508e0f4c 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -3,3 +3,53 @@
*/
#include "protocol.h"
+
+int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+ size_t len, struct mptcp_sock *msk,
+ size_t *copied)
+{
+ const struct iphdr *iph;
+ struct ubuf_info *uarg;
+ struct sockaddr *uaddr;
+ struct sk_buff *skb;
+ struct tcp_sock *tp;
+ struct socket *ssk;
+ int ret;
+
+ ssk = __mptcp_nmpc_socket(msk);
+ if (unlikely(!ssk))
+ goto out_EFAULT;
+ skb = tcp_stream_alloc_skb(ssk->sk, 0, ssk->sk->sk_allocation, true);
+ if (unlikely(!skb))
+ goto out_EFAULT;
+ iph = ip_hdr(skb);
+ if (unlikely(!iph))
+ goto out_EFAULT;
+ uarg = msg_zerocopy_realloc(sk, len, skb_zcopy(skb));
+ if (unlikely(!uarg))
+ goto out_EFAULT;
+ uaddr = msg->msg_name;
+
+ tp = tcp_sk(ssk->sk);
+ if (unlikely(!tp))
+ goto out_EFAULT;
+ if (!tp->fastopen_req)
+ tp->fastopen_req = kzalloc(sizeof(*tp->fastopen_req),
+ ssk->sk->sk_allocation);
+
+ if (unlikely(!tp->fastopen_req))
+ goto out_EFAULT;
+ tp->fastopen_req->data = msg;
+ tp->fastopen_req->size = len;
+ tp->fastopen_req->uarg = uarg;
+
+ /* requests a cookie */
+ ret = mptcp_stream_connect(sk->sk_socket, uaddr,
+ msg->msg_namelen, msg->msg_flags);
+ if (!ret)
+ *copied = len;
+ return ret;
+out_EFAULT:
+ ret = -EFAULT;
+ return ret;
+}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 55442df8fb97..6bbf1b86465d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1672,9 +1672,9 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
int ret = 0;
long timeo;
- /* we don't support FASTOPEN yet */
+ /* we don't fully support FASTOPEN yet */
if (msg->msg_flags & MSG_FASTOPEN)
- return -EOPNOTSUPP;
+ ret = mptcp_sendmsg_fastopen(sk, msg, len, msk, &copied);
/* silently ignore everything else */
msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 1bc9f6e77ddd..ad51910f1cc9 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -836,6 +836,12 @@ 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);
+// Fast Open Mechanism functions begin
+int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+ size_t len, struct mptcp_sock *msk,
+ size_t *copied);
+// Fast Open Mechanism functions end
+
static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
{
return READ_ONCE(msk->pm.addr_signal) &
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 3/9] rfree(), rmem_uncharge() prototypes to protocol.h
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 1/9] Add separate fastopen.c file Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 2/9] Initiator: MSG_FASTOPEN sendto(). request cookie Dmytro Shytyi
@ 2022-09-15 23:55 ` Dmytro Shytyi
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 4/9] Initiator: add locks() to mptcp_sendmsg_fastopen Dmytro Shytyi
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:55 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
These 2 functions required the mptcp_fastopen_add_skb() that is not in
protocol.c. Thus we export them to *.h and reuse in fastopen.c
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/protocol.c | 4 ++--
net/mptcp/protocol.h | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 6bbf1b86465d..ba50aa88d5d8 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 ad51910f1cc9..5cd14eacd1d6 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -835,6 +835,9 @@ 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);
+void mptcp_rmem_uncharge(struct sock *sk, int size);
+void mptcp_rfree(struct sk_buff *skb);
// Fast Open Mechanism functions begin
int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 4/9] Initiator: add locks() to mptcp_sendmsg_fastopen.
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (2 preceding siblings ...)
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 3/9] rfree(), rmem_uncharge() prototypes to protocol.h Dmytro Shytyi
@ 2022-09-15 23:55 ` Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 5/9] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:55 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Suggestion of @mmartineau : 'add locks' is implemented in this patch
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/fastopen.c | 42 ++++++++++++++++++++++++++++++++++++++++--
net/mptcp/protocol.c | 4 ++--
net/mptcp/protocol.h | 5 +++++
net/mptcp/sockopt.c | 3 +++
4 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 9974508e0f4c..436e773d798a 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -16,6 +16,7 @@ int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
struct socket *ssk;
int ret;
+ lock_sock((struct sock *)msk);
ssk = __mptcp_nmpc_socket(msk);
if (unlikely(!ssk))
goto out_EFAULT;
@@ -30,26 +31,63 @@ int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
goto out_EFAULT;
uaddr = msg->msg_name;
+ lock_sock(ssk->sk);
+
tp = tcp_sk(ssk->sk);
if (unlikely(!tp))
- goto out_EFAULT;
+ goto out_lock_EFAULT;
if (!tp->fastopen_req)
tp->fastopen_req = kzalloc(sizeof(*tp->fastopen_req),
ssk->sk->sk_allocation);
if (unlikely(!tp->fastopen_req))
- goto out_EFAULT;
+ goto out_lock_EFAULT;
tp->fastopen_req->data = msg;
tp->fastopen_req->size = len;
tp->fastopen_req->uarg = uarg;
+ release_sock(ssk->sk);
+ release_sock((struct sock *)msk);
+
/* requests a cookie */
ret = mptcp_stream_connect(sk->sk_socket, uaddr,
msg->msg_namelen, msg->msg_flags);
if (!ret)
*copied = len;
return ret;
+
+out_lock_EFAULT:
+ release_sock(ssk->sk);
out_EFAULT:
+ release_sock((struct sock *)msk);
ret = -EFAULT;
return ret;
}
+
+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.c b/net/mptcp/protocol.c
index ba50aa88d5d8..357767a84c57 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3474,8 +3474,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 5cd14eacd1d6..2a4b6dfb6f8f 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -838,11 +838,16 @@ 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);
+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_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
size_t len, struct mptcp_sock *msk,
size_t *copied);
+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)
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] 11+ messages in thread
* [RFC PATCH mptcp-next v6 5/9] Fix unxpctd val of subflow->map_seq(dscrd packet)
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (3 preceding siblings ...)
2022-09-15 23:55 ` [RFC PATCH mptcp-next v6 4/9] Initiator: add locks() to mptcp_sendmsg_fastopen Dmytro Shytyi
@ 2022-09-15 23:56 ` Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 6/9] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:56 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
This fixes the unexpected value of subflow->map_seq for the
second packet that leads to packet discard and further
retransmit.
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/subflow.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index c7d49fb6e7bd..075c61d1d37f 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1077,8 +1077,10 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
/* will validate the next map after consuming the current one */
goto validate_csum;
}
-
- subflow->map_seq = map_seq;
+ if (msk->is_mptfo)
+ subflow->map_seq = READ_ONCE(msk->ack_seq);
+ else
+ subflow->map_seq = map_seq;
subflow->map_subflow_seq = mpext->subflow_seq;
subflow->map_data_len = data_len;
subflow->map_valid = 1;
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 6/9] mptfo variables for msk, options. Fix loop retrans
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (4 preceding siblings ...)
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 5/9] Fix unxpctd val of subflow->map_seq(dscrd packet) Dmytro Shytyi
@ 2022-09-15 23:56 ` Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 7/9] Listener: Add received skb to msk Dmytro Shytyi
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:56 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Introduce mptfo variables for msk and options.
Also fixe the infinite retransmissions in the end of second session.
Suggestion @palbeni (SEP 1) during the meting to 'look at data_ack'
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/fastopen.c | 16 ++++++++++++++++
net/mptcp/options.c | 3 +++
net/mptcp/protocol.h | 6 +++++-
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 436e773d798a..149a4b1d3dac 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -91,3 +91,19 @@ int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
return ret;
}
+
+void mptcp_treat_hshake_ack_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+ struct mptcp_options_received mp_opt)
+{
+ u64 ack_seq;
+
+ if (mp_opt.suboptions & OPTIONS_MPTCP_MPC && mp_opt.is_mptfo && msk->is_mptfo) {
+ 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..185b069e57f4 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->is_mptfo = 1;
mp_opt->rcvr_key = get_unaligned_be64(ptr);
ptr += 8;
}
@@ -1124,6 +1125,8 @@ 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)) {
+ mptcp_treat_hshake_ack_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 2a4b6dfb6f8f..c364616c2d56 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;
+ is_mptfo:1,
+ __unused: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,
@@ -848,6 +850,8 @@ int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
size_t *copied);
int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
unsigned int optlen);
+void mptcp_treat_hshake_ack_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] 11+ messages in thread
* [RFC PATCH mptcp-next v6 7/9] Listener: Add received skb to msk
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (5 preceding siblings ...)
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 6/9] mptfo variables for msk, options. Fix loop retrans Dmytro Shytyi
@ 2022-09-15 23:56 ` Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 8/9] mptcp_fastopen_add_skb() helpers (skb to msk) Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 9/9] selftests: mptfo initiator/listener Dmytro Shytyi
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:56 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Add the received skb on the listener side to msk and set flag mptfo to 1
to treat some parts only in MPTFO case.
This function is called from the functions presented in the one of the
patch of this serie (mptcp_add_skb helpers).
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/fastopen.c | 65 ++++++++++++++++++++++++++++++++++++++++++++
net/mptcp/protocol.h | 43 +++++++++++++++++++++++++++++
net/mptcp/subflow.c | 2 +-
3 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 149a4b1d3dac..7070d2a966c9 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -107,3 +107,68 @@ void mptcp_treat_hshake_ack_fastopen(struct mptcp_sock *msk, struct mptcp_subflo
atomic64_set(&msk->rcv_wnd_sent, ack_seq);
}
}
+
+void mptcp_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)
+ return;
+
+ skb = skb_clone(skb, GFP_ATOMIC);
+ if (!skb)
+ return;
+
+ skb_dst_drop(skb);
+
+ tp->segs_in = 0;
+ tcp_segs_in(tp, skb);
+ __skb_pull(skb, tcp_hdrlen(skb));
+ sk_forced_mem_schedule(sk, skb->truesize);
+
+ TCP_SKB_CB(skb)->seq++;
+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN;
+
+ tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+
+ 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;
+
+ TCP_SKB_CB(skb)->seq += tp->rcv_nxt - tcp_r_sock->rcv_isn - 1;
+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
+
+ TCP_SKB_CB(skb)->seq += tp->rcv_nxt - tcp_r_sock->rcv_isn - 1;
+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
+
+ 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_ext_reset(skb);
+
+ //mptcp_set_owner_r begin
+ skb_orphan(skb);
+ skb->sk = socket;
+ skb->destructor = mptcp_rfree;
+ atomic_add(skb->truesize, &socket->sk_rmem_alloc);
+ msk->rmem_fwd_alloc -= skb->truesize;
+ //mptcp_set owner_r end
+
+ __skb_queue_tail(&msk->receive_queue, skb);
+
+ atomic64_set(&msk->rcv_wnd_sent, mptcp_subflow_get_mapped_dsn(subflow));
+
+ tp->syn_data_acked = 1;
+
+ tp->bytes_received = skb->len;
+
+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
+ tcp_fin(sk);
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index c364616c2d56..815d1bc6c6f2 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -852,6 +852,49 @@ int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockptr_t optval,
unsigned int optlen);
void mptcp_treat_hshake_ack_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
struct mptcp_options_received mp_opt);
+void mptcp_treat_3d_ack_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+ struct mptcp_options_received mp_opt);
+void mptcp_treat_3d_ack_fastopen(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+ struct mptcp_options_received mp_opt);
+void mptcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req);
+void mptcp_reqsk_record_syn(const struct sock *sk,
+ struct request_sock *req,
+ const struct sk_buff *skb);
+void mptcp_ecn_create_request(struct request_sock *req,
+ const struct sk_buff *skb,
+ const struct sock *listen_sk,
+ const struct dst_entry *dst);
+void mptcp_openreq_init(struct request_sock *req,
+ const struct tcp_options_received *rx_opt,
+ struct sk_buff *skb, const struct sock *sk);
+struct sock *mptcp_fastopen_create_child(struct sock *sk,
+ struct sk_buff *skb,
+ struct request_sock *req);
+bool mptcp_fastopen_queue_check(struct sock *sk);
+bool mptcp_fastopen_cookie_gen_cipher(struct request_sock *req,
+ struct sk_buff *syn,
+ const siphash_key_t *key,
+ struct tcp_fastopen_cookie *foc);
+void mptcp_fastopen_cookie_gen(struct sock *sk,
+ struct request_sock *req,
+ struct sk_buff *syn,
+ struct tcp_fastopen_cookie *foc);
+int mptcp_fastopen_cookie_gen_check(struct sock *sk,
+ struct request_sock *req,
+ struct sk_buff *syn,
+ struct tcp_fastopen_cookie *orig,
+ struct tcp_fastopen_cookie *valid_foc);
+bool mptcp_fastopen_no_cookie(const struct sock *sk,
+ const struct dst_entry *dst,
+ int flag);
+struct sock *mptcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req,
+ struct tcp_fastopen_cookie *foc,
+ const struct dst_entry *dst);
+int mptcp_conn_request(struct request_sock_ops *rsk_ops,
+ const struct tcp_request_sock_ops *af_ops,
+ struct sock *sk, struct sk_buff *skb);
// Fast Open Mechanism functions end
static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 075c61d1d37f..ff5fe4ff3d21 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -542,7 +542,7 @@ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
goto drop;
- return tcp_conn_request(&mptcp_subflow_request_sock_ops,
+ return mptcp_conn_request(&mptcp_subflow_request_sock_ops,
&subflow_request_sock_ipv4_ops,
sk, skb);
drop:
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 8/9] mptcp_fastopen_add_skb() helpers (skb to msk)
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (6 preceding siblings ...)
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 7/9] Listener: Add received skb to msk Dmytro Shytyi
@ 2022-09-15 23:56 ` Dmytro Shytyi
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 9/9] selftests: mptfo initiator/listener Dmytro Shytyi
8 siblings, 0 replies; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:56 UTC (permalink / raw)
To: mptcp; +Cc: Dmytro Shytyi
Set of helpers for mptcp_skb_add(). Some functions are inspired from tcp
fastopen.c file. This chain helps to add “skb” to “&msk->sk_receive_queue”
(“subflow_v4_conn_request”->”mptcp_conn_request”->”mptcp_try_fastopen”->
”mptcp_fastopen_create_child”->”mptcp_fastopen_add_skb”)
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
net/mptcp/fastopen.c | 379 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 379 insertions(+)
diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c
index 7070d2a966c9..815bae37097a 100644
--- a/net/mptcp/fastopen.c
+++ b/net/mptcp/fastopen.c
@@ -172,3 +172,382 @@ void mptcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb, struct request
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
tcp_fin(sk);
}
+
+struct sock *mptcp_fastopen_create_child(struct sock *sk,
+ struct sk_buff *skb,
+ struct request_sock *req)
+{
+ struct request_sock_queue *r_sock_queue = &inet_csk(sk)->icsk_accept_queue;
+ struct tcp_sock *tp;
+ struct sock *child_sock;
+ bool own_req;
+
+ child_sock = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
+ NULL, &own_req);
+ if (!child_sock)
+ return NULL;
+
+ spin_lock(&r_sock_queue->fastopenq.lock);
+ r_sock_queue->fastopenq.qlen++;
+ spin_unlock(&r_sock_queue->fastopenq.lock);
+
+ tp = tcp_sk(child_sock);
+
+ rcu_assign_pointer(tp->fastopen_rsk, req);
+ tcp_rsk(req)->tfo_listener = true;
+
+ tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
+ tp->max_window = tp->snd_wnd;
+
+ inet_csk_reset_xmit_timer(child_sock, ICSK_TIME_RETRANS,
+ TCP_TIMEOUT_INIT, TCP_RTO_MAX);
+
+ refcount_set(&req->rsk_refcnt, 2);
+
+ tcp_init_transfer(child_sock, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB, skb);
+
+ tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+
+ mptcp_fastopen_add_skb(child_sock, skb, req);
+
+ tcp_rsk(req)->rcv_nxt = tp->rcv_nxt;
+ tp->rcv_wup = tp->rcv_nxt;
+
+ return child_sock;
+}
+
+bool mptcp_fastopen_queue_check(struct sock *sk)
+{
+ struct fastopen_queue *fo_queue;
+ struct request_sock *req_sock;
+
+ fo_queue = &inet_csk(sk)->icsk_accept_queue.fastopenq;
+ if (fo_queue->max_qlen == 0)
+ return false;
+
+ if (fo_queue->qlen >= fo_queue->max_qlen) {
+ spin_lock(&fo_queue->lock);
+ req_sock = fo_queue->rskq_rst_head;
+ if (!req_sock || time_after(req_sock->rsk_timer.expires, jiffies)) {
+ spin_unlock(&fo_queue->lock);
+ return false;
+ }
+ fo_queue->rskq_rst_head = req_sock->dl_next;
+ fo_queue->qlen--;
+ spin_unlock(&fo_queue->lock);
+ reqsk_put(req_sock);
+ }
+ return true;
+}
+
+bool mptcp_fastopen_cookie_gen_cipher(struct request_sock *req,
+ struct sk_buff *syn,
+ const siphash_key_t *key,
+ struct tcp_fastopen_cookie *foc)
+{
+ if (req->rsk_ops->family == AF_INET) {
+ const struct iphdr *iph = ip_hdr(syn);
+
+ foc->val[0] = cpu_to_le64(siphash(&iph->saddr,
+ sizeof(iph->saddr) +
+ sizeof(iph->daddr),
+ key));
+ foc->len = TCP_FASTOPEN_COOKIE_SIZE;
+ return true;
+ }
+
+ return false;
+}
+
+void mptcp_fastopen_cookie_gen(struct sock *sk,
+ struct request_sock *req,
+ struct sk_buff *syn,
+ struct tcp_fastopen_cookie *foc)
+{
+ struct tcp_fastopen_context *ctx;
+
+ rcu_read_lock();
+ ctx = tcp_fastopen_get_ctx(sk);
+ if (ctx)
+ mptcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[0], foc);
+ rcu_read_unlock();
+}
+
+int mptcp_fastopen_cookie_gen_check(struct sock *sk,
+ struct request_sock *req,
+ struct sk_buff *syn,
+ struct tcp_fastopen_cookie *orig,
+ struct tcp_fastopen_cookie *valid_foc)
+{
+ struct tcp_fastopen_cookie mptcp_search_foc = { .len = -1 };
+ struct tcp_fastopen_cookie *mptcp_foc = valid_foc;
+ struct tcp_fastopen_context *mptcp_fo_ctx;
+ int i, ret = 0;
+
+ rcu_read_lock();
+ mptcp_fo_ctx = tcp_fastopen_get_ctx(sk);
+ if (!mptcp_fo_ctx)
+ goto out;
+ for (i = 0; i < tcp_fastopen_context_len(mptcp_fo_ctx); i++) {
+ mptcp_fastopen_cookie_gen_cipher(req, syn, &mptcp_fo_ctx->key[i], mptcp_foc);
+ if (tcp_fastopen_cookie_match(mptcp_foc, orig)) {
+ ret = i + 1;
+ goto out;
+ }
+ mptcp_foc = &mptcp_search_foc;
+ }
+out:
+ rcu_read_unlock();
+ return ret;
+}
+
+bool mptcp_fastopen_no_cookie(const struct sock *sk,
+ const struct dst_entry *dst,
+ int flag)
+{
+ return (sock_net(sk)->ipv4.sysctl_tcp_fastopen & flag) ||
+ tcp_sk(sk)->fastopen_no_cookie ||
+ (dst && dst_metric(dst, RTAX_FASTOPEN_NO_COOKIE));
+}
+
+struct sock *mptcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req,
+ struct tcp_fastopen_cookie *foc,
+ const struct dst_entry *dst)
+{
+ bool syn_data_status = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
+ struct tcp_fastopen_cookie valid_mptcp_foc = { .len = -1 };
+ struct sock *child_sock;
+ int ret = 0;
+
+ if ((syn_data_status || foc->len >= 0) &&
+ mptcp_fastopen_queue_check(sk)) {
+ foc->len = -1;
+ return NULL;
+ }
+
+ if (mptcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD))
+ goto fastopen;
+
+ if (foc->len == 0) {
+ mptcp_fastopen_cookie_gen(sk, req, skb, &valid_mptcp_foc);
+ } else if (foc->len > 0) {
+ ret = mptcp_fastopen_cookie_gen_check(sk, req, skb, foc,
+ &valid_mptcp_foc);
+ if (ret) {
+fastopen:
+ child_sock = mptcp_fastopen_create_child(sk, skb, req);
+ if (child_sock) {
+ if (ret == 2) {
+ valid_mptcp_foc.exp = foc->exp;
+ *foc = valid_mptcp_foc;
+ } else {
+ foc->len = -1;
+ }
+ return child_sock;
+ }
+ }
+ }
+ valid_mptcp_foc.exp = foc->exp;
+ *foc = valid_mptcp_foc;
+ return NULL;
+}
+
+int mptcp_conn_request(struct request_sock_ops *rsk_ops,
+ const struct tcp_request_sock_ops *af_ops,
+ struct sock *sk, struct sk_buff *skb)
+{
+ struct tcp_fastopen_cookie mptcp_foc = { .len = -1 };
+ struct tcp_options_received tmp_opt_rcvd;
+ __u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;
+ struct tcp_sock *tp_sock = tcp_sk(sk);
+ struct sock *mptcp_fo_sk = NULL;
+ struct net *net = sock_net(sk);
+ struct request_sock *req_sock;
+ bool want_cookie = false;
+ struct dst_entry *dst;
+ struct flowi fl;
+
+ if (sk_acceptq_is_full(sk))
+ goto drop;
+
+ req_sock = inet_reqsk_alloc(rsk_ops, sk, !want_cookie);
+ if (!req_sock)
+ goto drop;
+
+ req_sock->syncookie = want_cookie;
+ tcp_rsk(req_sock)->af_specific = af_ops;
+ tcp_rsk(req_sock)->ts_off = 1;
+ tcp_rsk(req_sock)->is_mptcp = 1;
+
+ tcp_clear_options(&tmp_opt_rcvd);
+ tmp_opt_rcvd.mss_clamp = af_ops->mss_clamp;
+ tmp_opt_rcvd.user_mss = tp_sock->rx_opt.user_mss;
+ tcp_parse_options(sock_net(sk), skb, &tmp_opt_rcvd, 0,
+ want_cookie ? NULL : &mptcp_foc);
+
+ if (want_cookie && !tmp_opt_rcvd.saw_tstamp)
+ tcp_clear_options(&tmp_opt_rcvd);
+
+ if (IS_ENABLED(CONFIG_SMC) && want_cookie)
+ tmp_opt_rcvd.smc_ok = 0;
+
+ tmp_opt_rcvd.tstamp_ok = 0;
+ mptcp_openreq_init(req_sock, &tmp_opt_rcvd, skb, sk);
+ inet_rsk(req_sock)->no_srccheck = inet_sk(sk)->transparent;
+
+ inet_rsk(req_sock)->ir_iif = inet_request_bound_dev_if(sk, skb);
+
+ dst = af_ops->route_req(sk, skb, &fl, req_sock);
+ if (!dst)
+ goto drop_and_free;
+
+ if (tmp_opt_rcvd.tstamp_ok)
+ tcp_rsk(req_sock)->ts_off = af_ops->init_ts_off(net, skb);
+
+ if (!want_cookie && !isn) {
+ if (!net->ipv4.sysctl_tcp_syncookies &&
+ (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+ (net->ipv4.sysctl_max_syn_backlog >> 2)) &&
+ !tcp_peer_is_proven(req_sock, dst)) {
+ goto drop_and_release;
+ }
+
+ isn = af_ops->init_seq(skb);
+ }
+
+ mptcp_ecn_create_request(req_sock, skb, sk, dst);
+
+ if (want_cookie) {
+ isn = cookie_init_sequence(af_ops, sk, skb, &req_sock->mss);
+ if (!tmp_opt_rcvd.tstamp_ok)
+ inet_rsk(req_sock)->ecn_ok = 0;
+ }
+
+ tcp_rsk(req_sock)->snt_isn = isn;
+ tcp_rsk(req_sock)->txhash = net_tx_rndhash();
+ tcp_rsk(req_sock)->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
+
+ tcp_openreq_init_rwin(req_sock, sk, dst);
+ sk_rx_queue_set(req_to_sk(req_sock), skb);
+ if (!want_cookie) {
+ mptcp_reqsk_record_syn(sk, req_sock, skb);
+ mptcp_fo_sk = mptcp_try_fastopen(sk, skb, req_sock, &mptcp_foc, dst);
+ }
+ if (mptcp_fo_sk) {
+ af_ops->send_synack(mptcp_fo_sk, dst, &fl, req_sock,
+ &mptcp_foc, TCP_SYNACK_FASTOPEN, skb);
+ if (!inet_csk_reqsk_queue_add(sk, req_sock, mptcp_fo_sk)) {
+ reqsk_fastopen_remove(mptcp_fo_sk, req_sock, false);
+ bh_unlock_sock(mptcp_fo_sk);
+ sock_put(mptcp_fo_sk);
+ goto drop_and_free;
+ }
+ sk->sk_data_ready(sk);
+ bh_unlock_sock(mptcp_fo_sk);
+ sock_put(mptcp_fo_sk);
+ } else {
+ tcp_rsk(req_sock)->tfo_listener = false;
+ if (!want_cookie) {
+ req_sock->timeout = tcp_timeout_init((struct sock *)req_sock);
+ inet_csk_reqsk_queue_hash_add(sk, req_sock, req_sock->timeout);
+ }
+ af_ops->send_synack(sk, dst, &fl, req_sock, &mptcp_foc,
+ !want_cookie ? TCP_SYNACK_NORMAL :
+ TCP_SYNACK_COOKIE,
+ skb);
+ if (want_cookie) {
+ reqsk_free(req_sock);
+ return 0;
+ }
+ }
+ reqsk_put(req_sock);
+ return 0;
+
+drop_and_release:
+ dst_release(dst);
+drop_and_free:
+ __reqsk_free(req_sock);
+drop:
+ tcp_listendrop(sk);
+ return 0;
+}
+
+void mptcp_reqsk_record_syn(const struct sock *sk,
+ struct request_sock *req,
+ const struct sk_buff *skb)
+{
+ if (tcp_sk(sk)->save_syn) {
+ u32 length = skb_network_header_len(skb) + tcp_hdrlen(skb);
+ struct saved_syn *svd_syn;
+ u32 mac_headerlen;
+ void *base;
+
+ if (tcp_sk(sk)->save_syn == 2) {
+ base = skb_mac_header(skb);
+ mac_headerlen = skb_mac_header_len(skb);
+ length += mac_headerlen;
+ } else {
+ base = skb_network_header(skb);
+ mac_headerlen = 0;
+ }
+
+ svd_syn = kmalloc(struct_size(svd_syn, data, length),
+ GFP_ATOMIC);
+ if (svd_syn) {
+ svd_syn->mac_hdrlen = mac_headerlen;
+ svd_syn->network_hdrlen = skb_network_header_len(skb);
+ svd_syn->tcp_hdrlen = tcp_hdrlen(skb);
+ memcpy(svd_syn->data, base, length);
+ req->saved_syn = svd_syn;
+ }
+ }
+}
+
+void mptcp_ecn_create_request(struct request_sock *req,
+ const struct sk_buff *skb,
+ const struct sock *listen_sk,
+ const struct dst_entry *dst)
+{
+ const struct tcphdr *thdr = tcp_hdr(skb);
+ const struct net *net = sock_net(listen_sk);
+ bool thdr_ecn = thdr->ece && thdr->cwr;
+ bool ect_stat, ecn_okay;
+ u32 ecn_okay_dst;
+
+ if (!thdr_ecn)
+ return;
+
+ ect_stat = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield);
+ ecn_okay_dst = dst_feature(dst, DST_FEATURE_ECN_MASK);
+ ecn_okay = net->ipv4.sysctl_tcp_ecn || ecn_okay_dst;
+
+ if (((!ect_stat || thdr->res1) && ecn_okay) || tcp_ca_needs_ecn(listen_sk) ||
+ (ecn_okay_dst & DST_FEATURE_ECN_CA) ||
+ tcp_bpf_ca_needs_ecn((struct sock *)req))
+ inet_rsk(req)->ecn_ok = 1;
+}
+
+void mptcp_openreq_init(struct request_sock *req,
+ const struct tcp_options_received *rx_opt,
+ struct sk_buff *skb, const struct sock *sk)
+{
+ struct inet_request_sock *ireq = inet_rsk(req);
+
+ req->rsk_rcv_wnd = 0;
+ tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
+ tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+ tcp_rsk(req)->snt_synack = 0;
+ tcp_rsk(req)->last_oow_ack_time = 0;
+ req->mss = rx_opt->mss_clamp;
+ req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0;
+ ireq->tstamp_ok = rx_opt->tstamp_ok;
+ ireq->sack_ok = rx_opt->sack_ok;
+ ireq->snd_wscale = rx_opt->snd_wscale;
+ ireq->wscale_ok = rx_opt->wscale_ok;
+ ireq->acked = 0;
+ ireq->ecn_ok = 0;
+ ireq->ir_rmt_port = tcp_hdr(skb)->source;
+ ireq->ir_num = ntohs(tcp_hdr(skb)->dest);
+ ireq->ir_mark = inet_request_mark(sk, skb);
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH mptcp-next v6 9/9] selftests: mptfo initiator/listener
2022-09-15 23:55 [RFC PATCH mptcp-next v6 0/9] mptcp: Fast Open Mechanism Dmytro Shytyi
` (7 preceding siblings ...)
2022-09-15 23:56 ` [RFC PATCH mptcp-next v6 8/9] mptcp_fastopen_add_skb() helpers (skb to msk) Dmytro Shytyi
@ 2022-09-15 23:56 ` Dmytro Shytyi
2022-09-16 1:35 ` selftests: mptfo initiator/listener: Build Failure MPTCP CI
8 siblings, 1 reply; 11+ messages in thread
From: Dmytro Shytyi @ 2022-09-15 23:56 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] 11+ messages in thread