xref: /linux/net/mptcp/fastopen.c (revision fab183d632628381b466a41479489541ac0e29a0)
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 
mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context * subflow,struct request_sock * req)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 	/* A valid TFO cookie does not guarantee SYN data. */
28 	skb = skb_peek(&ssk->sk_receive_queue);
29 	if (!skb)
30 		return;
31 
32 	subflow->is_mptfo = 1;
33 
34 	/* dequeue the skb from sk receive queue */
35 	__skb_unlink(skb, &ssk->sk_receive_queue);
36 	skb_ext_reset(skb);
37 
38 	mptcp_subflow_lend_fwdmem(subflow, skb);
39 
40 	/* We copy the fastopen data, but that don't belong to the mptcp sequence
41 	 * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
42 	 */
43 	tp->copied_seq += skb->len;
44 	subflow->ssn_offset += skb->len;
45 	has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
46 
47 	/* Only the sequence delta is relevant */
48 	MPTCP_SKB_CB(skb)->map_seq = -skb->len;
49 	MPTCP_SKB_CB(skb)->end_seq = 0;
50 	MPTCP_SKB_CB(skb)->offset = 0;
51 	MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
52 	MPTCP_SKB_CB(skb)->cant_coalesce = 1;
53 
54 	mptcp_data_lock(sk);
55 	DEBUG_NET_WARN_ON_ONCE(sock_owned_by_user_nocheck(sk));
56 
57 	mptcp_borrow_fwdmem(sk, skb);
58 	skb_set_owner_r(skb, sk);
59 	__skb_queue_tail(&sk->sk_receive_queue, skb);
60 	mptcp_sk(sk)->bytes_received += skb->len;
61 
62 	sk->sk_data_ready(sk);
63 
64 	mptcp_data_unlock(sk);
65 }
66