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