xref: /linux/net/mptcp/fastopen.c (revision e4a0fa47)
1dfc8d060SDmytro Shytyi // SPDX-License-Identifier: GPL-2.0
2dfc8d060SDmytro Shytyi /* MPTCP Fast Open Mechanism
3dfc8d060SDmytro Shytyi  *
4dfc8d060SDmytro Shytyi  * Copyright (c) 2021-2022, Dmytro SHYTYI
5dfc8d060SDmytro Shytyi  */
6dfc8d060SDmytro Shytyi 
7dfc8d060SDmytro Shytyi #include "protocol.h"
8dfc8d060SDmytro Shytyi 
mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context * subflow,struct request_sock * req)936b122baSDmytro Shytyi void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
1036b122baSDmytro Shytyi 					      struct request_sock *req)
1136b122baSDmytro Shytyi {
12c0ff6f6dSPaolo Abeni 	struct sock *sk, *ssk;
1336b122baSDmytro Shytyi 	struct sk_buff *skb;
1436b122baSDmytro Shytyi 	struct tcp_sock *tp;
1536b122baSDmytro Shytyi 
16c0ff6f6dSPaolo Abeni 	/* on early fallback the subflow context is deleted by
17c0ff6f6dSPaolo Abeni 	 * subflow_syn_recv_sock()
18c0ff6f6dSPaolo Abeni 	 */
19c0ff6f6dSPaolo Abeni 	if (!subflow)
20c0ff6f6dSPaolo Abeni 		return;
21c0ff6f6dSPaolo Abeni 
22c0ff6f6dSPaolo Abeni 	ssk = subflow->tcp_sock;
23c0ff6f6dSPaolo Abeni 	sk = subflow->conn;
2436b122baSDmytro Shytyi 	tp = tcp_sk(ssk);
2536b122baSDmytro Shytyi 
2636b122baSDmytro Shytyi 	subflow->is_mptfo = 1;
2736b122baSDmytro Shytyi 
2836b122baSDmytro Shytyi 	skb = skb_peek(&ssk->sk_receive_queue);
2936b122baSDmytro Shytyi 	if (WARN_ON_ONCE(!skb))
3036b122baSDmytro Shytyi 		return;
3136b122baSDmytro Shytyi 
3236b122baSDmytro Shytyi 	/* dequeue the skb from sk receive queue */
3336b122baSDmytro Shytyi 	__skb_unlink(skb, &ssk->sk_receive_queue);
3436b122baSDmytro Shytyi 	skb_ext_reset(skb);
3536b122baSDmytro Shytyi 	skb_orphan(skb);
3636b122baSDmytro Shytyi 
3736b122baSDmytro Shytyi 	/* We copy the fastopen data, but that don't belong to the mptcp sequence
3836b122baSDmytro Shytyi 	 * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
3936b122baSDmytro Shytyi 	 */
4036b122baSDmytro Shytyi 	tp->copied_seq += skb->len;
4136b122baSDmytro Shytyi 	subflow->ssn_offset += skb->len;
4236b122baSDmytro Shytyi 
4336b122baSDmytro Shytyi 	/* initialize a dummy sequence number, we will update it at MPC
4436b122baSDmytro Shytyi 	 * completion, if needed
4536b122baSDmytro Shytyi 	 */
4636b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->map_seq = -skb->len;
4736b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->end_seq = 0;
4836b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->offset = 0;
4936b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
5036b122baSDmytro Shytyi 
5136b122baSDmytro Shytyi 	mptcp_data_lock(sk);
5236b122baSDmytro Shytyi 
5336b122baSDmytro Shytyi 	mptcp_set_owner_r(skb, sk);
5436b122baSDmytro Shytyi 	__skb_queue_tail(&sk->sk_receive_queue, skb);
55bf0e9610SPaolo Abeni 	mptcp_sk(sk)->bytes_received += skb->len;
5636b122baSDmytro Shytyi 
5736b122baSDmytro Shytyi 	sk->sk_data_ready(sk);
5836b122baSDmytro Shytyi 
5936b122baSDmytro Shytyi 	mptcp_data_unlock(sk);
6036b122baSDmytro Shytyi }
6136b122baSDmytro Shytyi 
__mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock * msk,struct mptcp_subflow_context * subflow,const struct mptcp_options_received * mp_opt)62*e4a0fa47SPaolo Abeni void __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
63dfc8d060SDmytro Shytyi 				     const struct mptcp_options_received *mp_opt)
64dfc8d060SDmytro Shytyi {
65dfc8d060SDmytro Shytyi 	struct sock *sk = (struct sock *)msk;
66dfc8d060SDmytro Shytyi 	struct sk_buff *skb;
67dfc8d060SDmytro Shytyi 
68dfc8d060SDmytro Shytyi 	skb = skb_peek_tail(&sk->sk_receive_queue);
69dfc8d060SDmytro Shytyi 	if (skb) {
70dfc8d060SDmytro Shytyi 		WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
71dfc8d060SDmytro Shytyi 		pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk,
72dfc8d060SDmytro Shytyi 			 MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
73dfc8d060SDmytro Shytyi 			 MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
74dfc8d060SDmytro Shytyi 		MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
75dfc8d060SDmytro Shytyi 		MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
76dfc8d060SDmytro Shytyi 	}
77dfc8d060SDmytro Shytyi 
78dfc8d060SDmytro Shytyi 	pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq);
79dfc8d060SDmytro Shytyi }
80