1dfc8d060SDmytro Shytyi // SPDX-License-Identifier: GPL-2.0 2dfc8d060SDmytro Shytyi /* MPTCP Fast Open Mechanism 3dfc8d060SDmytro Shytyi * 4dfc8d060SDmytro Shytyi * Copyright (c) 2021-2022, Dmytro SHYTYI 5dfc8d060SDmytro Shytyi */ 6dfc8d060SDmytro Shytyi 7dfc8d060SDmytro Shytyi #include "protocol.h" 8dfc8d060SDmytro Shytyi 936b122baSDmytro Shytyi void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow, 1036b122baSDmytro Shytyi struct request_sock *req) 1136b122baSDmytro Shytyi { 12c0ff6f6dSPaolo Abeni struct sock *sk, *ssk; 1336b122baSDmytro Shytyi struct sk_buff *skb; 1436b122baSDmytro Shytyi struct tcp_sock *tp; 1536b122baSDmytro Shytyi 16c0ff6f6dSPaolo Abeni /* on early fallback the subflow context is deleted by 17c0ff6f6dSPaolo Abeni * subflow_syn_recv_sock() 18c0ff6f6dSPaolo Abeni */ 19c0ff6f6dSPaolo Abeni if (!subflow) 20c0ff6f6dSPaolo Abeni return; 21c0ff6f6dSPaolo Abeni 22c0ff6f6dSPaolo Abeni ssk = subflow->tcp_sock; 23c0ff6f6dSPaolo Abeni sk = subflow->conn; 2436b122baSDmytro Shytyi tp = tcp_sk(ssk); 2536b122baSDmytro Shytyi 2636b122baSDmytro Shytyi subflow->is_mptfo = 1; 2736b122baSDmytro Shytyi 2836b122baSDmytro Shytyi skb = skb_peek(&ssk->sk_receive_queue); 2936b122baSDmytro Shytyi if (WARN_ON_ONCE(!skb)) 3036b122baSDmytro Shytyi return; 3136b122baSDmytro Shytyi 3236b122baSDmytro Shytyi /* dequeue the skb from sk receive queue */ 3336b122baSDmytro Shytyi __skb_unlink(skb, &ssk->sk_receive_queue); 3436b122baSDmytro Shytyi skb_ext_reset(skb); 3536b122baSDmytro Shytyi skb_orphan(skb); 3636b122baSDmytro Shytyi 3736b122baSDmytro Shytyi /* We copy the fastopen data, but that don't belong to the mptcp sequence 3836b122baSDmytro Shytyi * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset() 3936b122baSDmytro Shytyi */ 4036b122baSDmytro Shytyi tp->copied_seq += skb->len; 4136b122baSDmytro Shytyi subflow->ssn_offset += skb->len; 4236b122baSDmytro Shytyi 4336b122baSDmytro Shytyi /* initialize a dummy sequence number, we will update it at MPC 4436b122baSDmytro Shytyi * completion, if needed 4536b122baSDmytro Shytyi */ 4636b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq = -skb->len; 4736b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq = 0; 4836b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->offset = 0; 4936b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp; 5036b122baSDmytro Shytyi 5136b122baSDmytro Shytyi mptcp_data_lock(sk); 5236b122baSDmytro Shytyi 5336b122baSDmytro Shytyi mptcp_set_owner_r(skb, sk); 5436b122baSDmytro Shytyi __skb_queue_tail(&sk->sk_receive_queue, skb); 55eede8e07SPaolo Abeni mptcp_sk(sk)->bytes_received += skb->len; 5636b122baSDmytro Shytyi 5736b122baSDmytro Shytyi sk->sk_data_ready(sk); 5836b122baSDmytro Shytyi 5936b122baSDmytro Shytyi mptcp_data_unlock(sk); 6036b122baSDmytro Shytyi } 6136b122baSDmytro Shytyi 62b45df837SPaolo Abeni void __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow, 63dfc8d060SDmytro Shytyi const struct mptcp_options_received *mp_opt) 64dfc8d060SDmytro Shytyi { 65dfc8d060SDmytro Shytyi struct sock *sk = (struct sock *)msk; 66dfc8d060SDmytro Shytyi struct sk_buff *skb; 67dfc8d060SDmytro Shytyi 68dfc8d060SDmytro Shytyi skb = skb_peek_tail(&sk->sk_receive_queue); 69dfc8d060SDmytro Shytyi if (skb) { 70dfc8d060SDmytro Shytyi WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq); 71*3d2e1b82SMatthieu Baerts (NGI0) pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx\n", sk, 72dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq, 73dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq); 74dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq; 75dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq; 76dfc8d060SDmytro Shytyi } 77dfc8d060SDmytro Shytyi 78*3d2e1b82SMatthieu Baerts (NGI0) pr_debug("msk=%p ack_seq=%llx\n", msk, msk->ack_seq); 79dfc8d060SDmytro Shytyi } 80