162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* MPTCP Fast Open Mechanism 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2021-2022, Dmytro SHYTYI 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include "protocol.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_civoid mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow, 1062306a36Sopenharmony_ci struct request_sock *req) 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci struct sock *sk, *ssk; 1362306a36Sopenharmony_ci struct sk_buff *skb; 1462306a36Sopenharmony_ci struct tcp_sock *tp; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci /* on early fallback the subflow context is deleted by 1762306a36Sopenharmony_ci * subflow_syn_recv_sock() 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci if (!subflow) 2062306a36Sopenharmony_ci return; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci ssk = subflow->tcp_sock; 2362306a36Sopenharmony_ci sk = subflow->conn; 2462306a36Sopenharmony_ci tp = tcp_sk(ssk); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci subflow->is_mptfo = 1; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci skb = skb_peek(&ssk->sk_receive_queue); 2962306a36Sopenharmony_ci if (WARN_ON_ONCE(!skb)) 3062306a36Sopenharmony_ci return; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* dequeue the skb from sk receive queue */ 3362306a36Sopenharmony_ci __skb_unlink(skb, &ssk->sk_receive_queue); 3462306a36Sopenharmony_ci skb_ext_reset(skb); 3562306a36Sopenharmony_ci skb_orphan(skb); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* We copy the fastopen data, but that don't belong to the mptcp sequence 3862306a36Sopenharmony_ci * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset() 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ci tp->copied_seq += skb->len; 4162306a36Sopenharmony_ci subflow->ssn_offset += skb->len; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* initialize a dummy sequence number, we will update it at MPC 4462306a36Sopenharmony_ci * completion, if needed 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->map_seq = -skb->len; 4762306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->end_seq = 0; 4862306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->offset = 0; 4962306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci mptcp_data_lock(sk); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci mptcp_set_owner_r(skb, sk); 5462306a36Sopenharmony_ci __skb_queue_tail(&sk->sk_receive_queue, skb); 5562306a36Sopenharmony_ci mptcp_sk(sk)->bytes_received += skb->len; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci sk->sk_data_ready(sk); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci mptcp_data_unlock(sk); 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_civoid __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow, 6362306a36Sopenharmony_ci const struct mptcp_options_received *mp_opt) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci struct sock *sk = (struct sock *)msk; 6662306a36Sopenharmony_ci struct sk_buff *skb; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci skb = skb_peek_tail(&sk->sk_receive_queue); 6962306a36Sopenharmony_ci if (skb) { 7062306a36Sopenharmony_ci WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq); 7162306a36Sopenharmony_ci pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk, 7262306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq, 7362306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq); 7462306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq; 7562306a36Sopenharmony_ci MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq); 7962306a36Sopenharmony_ci} 80