Skip to content

Commit dfc8d06

Browse files
shytyikuba-moo
authored andcommitted
mptcp: implement delayed seq generation for passive fastopen
With fastopen in place, the first subflow socket is created before the MPC handshake completes, and we need to properly initialize the sequence numbers at MPC ACK reception. Co-developed-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent b3ea6b2 commit dfc8d06

File tree

6 files changed

+54
-15
lines changed

6 files changed

+54
-15
lines changed

net/mptcp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
obj-$(CONFIG_MPTCP) += mptcp.o
33

44
mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
5-
mib.o pm_netlink.o sockopt.o pm_userspace.o
5+
mib.o pm_netlink.o sockopt.o pm_userspace.o fastopen.o
66

77
obj-$(CONFIG_SYN_COOKIES) += syncookies.o
88
obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o

net/mptcp/fastopen.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* MPTCP Fast Open Mechanism
3+
*
4+
* Copyright (c) 2021-2022, Dmytro SHYTYI
5+
*/
6+
7+
#include "protocol.h"
8+
9+
void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
10+
const struct mptcp_options_received *mp_opt)
11+
{
12+
struct sock *sk = (struct sock *)msk;
13+
struct sk_buff *skb;
14+
15+
mptcp_data_lock(sk);
16+
skb = skb_peek_tail(&sk->sk_receive_queue);
17+
if (skb) {
18+
WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
19+
pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk,
20+
MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
21+
MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
22+
MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
23+
MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
24+
}
25+
26+
pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq);
27+
mptcp_data_unlock(sk);
28+
}

net/mptcp/options.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
939939
subflow->mp_join && (mp_opt->suboptions & OPTIONS_MPTCP_MPJ) &&
940940
!subflow->request_join)
941941
tcp_send_ack(ssk);
942-
goto fully_established;
942+
goto check_notify;
943943
}
944944

945945
/* we must process OoO packets before the first subflow is fully
@@ -950,6 +950,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
950950
if (TCP_SKB_CB(skb)->seq != subflow->ssn_offset + 1) {
951951
if (subflow->mp_join)
952952
goto reset;
953+
if (subflow->is_mptfo && mp_opt->suboptions & OPTION_MPTCP_MPC_ACK)
954+
goto set_fully_established;
953955
return subflow->mp_capable;
954956
}
955957

@@ -961,7 +963,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
961963
*/
962964
subflow->fully_established = 1;
963965
WRITE_ONCE(msk->fully_established, true);
964-
goto fully_established;
966+
goto check_notify;
965967
}
966968

967969
/* If the first established packet does not contain MP_CAPABLE + data
@@ -980,11 +982,12 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
980982
if (mp_opt->deny_join_id0)
981983
WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
982984

985+
set_fully_established:
983986
if (unlikely(!READ_ONCE(msk->pm.server_side)))
984987
pr_warn_once("bogus mpc option on established client sk");
985988
mptcp_subflow_fully_established(subflow, mp_opt);
986989

987-
fully_established:
990+
check_notify:
988991
/* if the subflow is not already linked into the conn_list, we can't
989992
* notify the PM: this subflow is still on the listener queue
990993
* and the PM possibly acquiring the subflow lock could race with

net/mptcp/protocol.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,6 @@ struct mptcp6_sock {
3636
};
3737
#endif
3838

39-
struct mptcp_skb_cb {
40-
u64 map_seq;
41-
u64 end_seq;
42-
u32 offset;
43-
u8 has_rxtstamp:1;
44-
};
45-
46-
#define MPTCP_SKB_CB(__skb) ((struct mptcp_skb_cb *)&((__skb)->cb[0]))
47-
4839
enum {
4940
MPTCP_CMSG_TS = BIT(0),
5041
MPTCP_CMSG_INQ = BIT(1),

net/mptcp/protocol.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@
126126
#define MPTCP_CONNECTED 6
127127
#define MPTCP_RESET_SCHEDULER 7
128128

129+
struct mptcp_skb_cb {
130+
u64 map_seq;
131+
u64 end_seq;
132+
u32 offset;
133+
u8 has_rxtstamp:1;
134+
};
135+
136+
#define MPTCP_SKB_CB(__skb) ((struct mptcp_skb_cb *)&((__skb)->cb[0]))
137+
129138
static inline bool before64(__u64 seq1, __u64 seq2)
130139
{
131140
return (__s64)(seq1 - seq2) < 0;
@@ -471,7 +480,9 @@ struct mptcp_subflow_context {
471480
disposable : 1, /* ctx can be free at ulp release time */
472481
stale : 1, /* unable to snd/rcv data, do not use for xmit */
473482
local_id_valid : 1, /* local_id is correctly initialized */
474-
valid_csum_seen : 1; /* at least one csum validated */
483+
valid_csum_seen : 1, /* at least one csum validated */
484+
is_mptfo : 1, /* subflow is doing TFO */
485+
__unused : 8;
475486
enum mptcp_data_avail data_avail;
476487
u32 remote_nonce;
477488
u64 thmac;
@@ -829,6 +840,9 @@ void mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_
829840
void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
830841
bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
831842

843+
void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
844+
const struct mptcp_options_received *mp_opt);
845+
832846
static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
833847
{
834848
return READ_ONCE(msk->pm.addr_signal) &

net/mptcp/subflow.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,9 @@ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
664664
subflow_set_remote_key(msk, subflow, mp_opt);
665665
subflow->fully_established = 1;
666666
WRITE_ONCE(msk->fully_established, true);
667+
668+
if (subflow->is_mptfo)
669+
mptcp_fastopen_gen_msk_ackseq(msk, subflow, mp_opt);
667670
}
668671

669672
static struct sock *subflow_syn_recv_sock(const struct sock *sk,
@@ -779,7 +782,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
779782
/* with OoO packets we can reach here without ingress
780783
* mpc option
781784
*/
782-
if (mp_opt.suboptions & OPTIONS_MPTCP_MPC)
785+
if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK)
783786
mptcp_subflow_fully_established(ctx, &mp_opt);
784787
} else if (ctx->mp_join) {
785788
struct mptcp_sock *owner;

0 commit comments

Comments
 (0)