xref: /openbmc/linux/net/mptcp/fastopen.c (revision 36b122baf6a8bd46b4a591f12f4ed17b22257408)
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 
9*36b122baSDmytro Shytyi void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
10*36b122baSDmytro Shytyi 					      struct request_sock *req)
11*36b122baSDmytro Shytyi {
12*36b122baSDmytro Shytyi 	struct sock *ssk = subflow->tcp_sock;
13*36b122baSDmytro Shytyi 	struct sock *sk = subflow->conn;
14*36b122baSDmytro Shytyi 	struct sk_buff *skb;
15*36b122baSDmytro Shytyi 	struct tcp_sock *tp;
16*36b122baSDmytro Shytyi 
17*36b122baSDmytro Shytyi 	tp = tcp_sk(ssk);
18*36b122baSDmytro Shytyi 
19*36b122baSDmytro Shytyi 	subflow->is_mptfo = 1;
20*36b122baSDmytro Shytyi 
21*36b122baSDmytro Shytyi 	skb = skb_peek(&ssk->sk_receive_queue);
22*36b122baSDmytro Shytyi 	if (WARN_ON_ONCE(!skb))
23*36b122baSDmytro Shytyi 		return;
24*36b122baSDmytro Shytyi 
25*36b122baSDmytro Shytyi 	/* dequeue the skb from sk receive queue */
26*36b122baSDmytro Shytyi 	__skb_unlink(skb, &ssk->sk_receive_queue);
27*36b122baSDmytro Shytyi 	skb_ext_reset(skb);
28*36b122baSDmytro Shytyi 	skb_orphan(skb);
29*36b122baSDmytro Shytyi 
30*36b122baSDmytro Shytyi 	/* We copy the fastopen data, but that don't belong to the mptcp sequence
31*36b122baSDmytro Shytyi 	 * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
32*36b122baSDmytro Shytyi 	 */
33*36b122baSDmytro Shytyi 	tp->copied_seq += skb->len;
34*36b122baSDmytro Shytyi 	subflow->ssn_offset += skb->len;
35*36b122baSDmytro Shytyi 
36*36b122baSDmytro Shytyi 	/* initialize a dummy sequence number, we will update it at MPC
37*36b122baSDmytro Shytyi 	 * completion, if needed
38*36b122baSDmytro Shytyi 	 */
39*36b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->map_seq = -skb->len;
40*36b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->end_seq = 0;
41*36b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->offset = 0;
42*36b122baSDmytro Shytyi 	MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
43*36b122baSDmytro Shytyi 
44*36b122baSDmytro Shytyi 	mptcp_data_lock(sk);
45*36b122baSDmytro Shytyi 
46*36b122baSDmytro Shytyi 	mptcp_set_owner_r(skb, sk);
47*36b122baSDmytro Shytyi 	__skb_queue_tail(&sk->sk_receive_queue, skb);
48*36b122baSDmytro Shytyi 
49*36b122baSDmytro Shytyi 	sk->sk_data_ready(sk);
50*36b122baSDmytro Shytyi 
51*36b122baSDmytro Shytyi 	mptcp_data_unlock(sk);
52*36b122baSDmytro Shytyi }
53*36b122baSDmytro Shytyi 
54dfc8d060SDmytro Shytyi void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
55dfc8d060SDmytro Shytyi 				   const struct mptcp_options_received *mp_opt)
56dfc8d060SDmytro Shytyi {
57dfc8d060SDmytro Shytyi 	struct sock *sk = (struct sock *)msk;
58dfc8d060SDmytro Shytyi 	struct sk_buff *skb;
59dfc8d060SDmytro Shytyi 
60dfc8d060SDmytro Shytyi 	mptcp_data_lock(sk);
61dfc8d060SDmytro Shytyi 	skb = skb_peek_tail(&sk->sk_receive_queue);
62dfc8d060SDmytro Shytyi 	if (skb) {
63dfc8d060SDmytro Shytyi 		WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
64dfc8d060SDmytro Shytyi 		pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk,
65dfc8d060SDmytro Shytyi 			 MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
66dfc8d060SDmytro Shytyi 			 MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
67dfc8d060SDmytro Shytyi 		MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
68dfc8d060SDmytro Shytyi 		MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
69dfc8d060SDmytro Shytyi 	}
70dfc8d060SDmytro Shytyi 
71dfc8d060SDmytro Shytyi 	pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq);
72dfc8d060SDmytro Shytyi 	mptcp_data_unlock(sk);
73dfc8d060SDmytro Shytyi }
74