| // SPDX-License-Identifier: GPL-2.0 | |
| /* MPTCP Fast Open Mechanism | |
| * | |
| * Copyright (c) 2021-2022, Dmytro SHYTYI | |
| */ | |
| #include "protocol.h" | |
| void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow, | |
| struct request_sock *req) | |
| { | |
| struct sock *sk, *ssk; | |
| struct sk_buff *skb; | |
| struct tcp_sock *tp; | |
| /* on early fallback the subflow context is deleted by | |
| * subflow_syn_recv_sock() | |
| */ | |
| if (!subflow) | |
| return; | |
| ssk = subflow->tcp_sock; | |
| sk = subflow->conn; | |
| tp = tcp_sk(ssk); | |
| subflow->is_mptfo = 1; | |
| skb = skb_peek(&ssk->sk_receive_queue); | |
| if (WARN_ON_ONCE(!skb)) | |
| return; | |
| /* dequeue the skb from sk receive queue */ | |
| __skb_unlink(skb, &ssk->sk_receive_queue); | |
| skb_ext_reset(skb); | |
| mptcp_subflow_lend_fwdmem(subflow, skb); | |
| /* We copy the fastopen data, but that don't belong to the mptcp sequence | |
| * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset() | |
| */ | |
| tp->copied_seq += skb->len; | |
| subflow->ssn_offset += skb->len; | |
| /* Only the sequence delta is relevant */ | |
| MPTCP_SKB_CB(skb)->map_seq = -skb->len; | |
| MPTCP_SKB_CB(skb)->end_seq = 0; | |
| MPTCP_SKB_CB(skb)->offset = 0; | |
| MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp; | |
| MPTCP_SKB_CB(skb)->cant_coalesce = 1; | |
| mptcp_data_lock(sk); | |
| DEBUG_NET_WARN_ON_ONCE(sock_owned_by_user_nocheck(sk)); | |
| mptcp_borrow_fwdmem(sk, skb); | |
| skb_set_owner_r(skb, sk); | |
| __skb_queue_tail(&sk->sk_receive_queue, skb); | |
| mptcp_sk(sk)->bytes_received += skb->len; | |
| sk->sk_data_ready(sk); | |
| mptcp_data_unlock(sk); | |
| } |