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