xref: /linux/net/mptcp/fastopen.c (revision 985d4a55e64e43bd86eeb896b81ceba453301989)
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 	bool has_rxtstamp;
16 
17 	/* on early fallback the subflow context is deleted by
18 	 * subflow_syn_recv_sock()
19 	 */
20 	if (!subflow)
21 		return;
22 
23 	ssk = subflow->tcp_sock;
24 	sk = subflow->conn;
25 	tp = tcp_sk(ssk);
26 
27 	subflow->is_mptfo = 1;
28 
29 	skb = skb_peek(&ssk->sk_receive_queue);
30 	if (WARN_ON_ONCE(!skb))
31 		return;
32 
33 	/* dequeue the skb from sk receive queue */
34 	__skb_unlink(skb, &ssk->sk_receive_queue);
35 	skb_ext_reset(skb);
36 
37 	mptcp_subflow_lend_fwdmem(subflow, skb);
38 
39 	/* We copy the fastopen data, but that don't belong to the mptcp sequence
40 	 * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
41 	 */
42 	tp->copied_seq += skb->len;
43 	subflow->ssn_offset += skb->len;
44 	has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
45 
46 	/* Only the sequence delta is relevant */
47 	MPTCP_SKB_CB(skb)->map_seq = -skb->len;
48 	MPTCP_SKB_CB(skb)->end_seq = 0;
49 	MPTCP_SKB_CB(skb)->offset = 0;
50 	MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
51 	MPTCP_SKB_CB(skb)->cant_coalesce = 1;
52 
53 	mptcp_data_lock(sk);
54 	DEBUG_NET_WARN_ON_ONCE(sock_owned_by_user_nocheck(sk));
55 
56 	mptcp_borrow_fwdmem(sk, skb);
57 	skb_set_owner_r(skb, sk);
58 	__skb_queue_tail(&sk->sk_receive_queue, skb);
59 	mptcp_sk(sk)->bytes_received += skb->len;
60 
61 	sk->sk_data_ready(sk);
62 
63 	mptcp_data_unlock(sk);
64 }
65