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 9*36b122baSDmytro Shytyi void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow, 10*36b122baSDmytro Shytyi struct request_sock *req) 11*36b122baSDmytro Shytyi { 12*36b122baSDmytro Shytyi struct sock *ssk = subflow->tcp_sock; 13*36b122baSDmytro Shytyi struct sock *sk = subflow->conn; 14*36b122baSDmytro Shytyi struct sk_buff *skb; 15*36b122baSDmytro Shytyi struct tcp_sock *tp; 16*36b122baSDmytro Shytyi 17*36b122baSDmytro Shytyi tp = tcp_sk(ssk); 18*36b122baSDmytro Shytyi 19*36b122baSDmytro Shytyi subflow->is_mptfo = 1; 20*36b122baSDmytro Shytyi 21*36b122baSDmytro Shytyi skb = skb_peek(&ssk->sk_receive_queue); 22*36b122baSDmytro Shytyi if (WARN_ON_ONCE(!skb)) 23*36b122baSDmytro Shytyi return; 24*36b122baSDmytro Shytyi 25*36b122baSDmytro Shytyi /* dequeue the skb from sk receive queue */ 26*36b122baSDmytro Shytyi __skb_unlink(skb, &ssk->sk_receive_queue); 27*36b122baSDmytro Shytyi skb_ext_reset(skb); 28*36b122baSDmytro Shytyi skb_orphan(skb); 29*36b122baSDmytro Shytyi 30*36b122baSDmytro Shytyi /* We copy the fastopen data, but that don't belong to the mptcp sequence 31*36b122baSDmytro Shytyi * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset() 32*36b122baSDmytro Shytyi */ 33*36b122baSDmytro Shytyi tp->copied_seq += skb->len; 34*36b122baSDmytro Shytyi subflow->ssn_offset += skb->len; 35*36b122baSDmytro Shytyi 36*36b122baSDmytro Shytyi /* initialize a dummy sequence number, we will update it at MPC 37*36b122baSDmytro Shytyi * completion, if needed 38*36b122baSDmytro Shytyi */ 39*36b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq = -skb->len; 40*36b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq = 0; 41*36b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->offset = 0; 42*36b122baSDmytro Shytyi MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp; 43*36b122baSDmytro Shytyi 44*36b122baSDmytro Shytyi mptcp_data_lock(sk); 45*36b122baSDmytro Shytyi 46*36b122baSDmytro Shytyi mptcp_set_owner_r(skb, sk); 47*36b122baSDmytro Shytyi __skb_queue_tail(&sk->sk_receive_queue, skb); 48*36b122baSDmytro Shytyi 49*36b122baSDmytro Shytyi sk->sk_data_ready(sk); 50*36b122baSDmytro Shytyi 51*36b122baSDmytro Shytyi mptcp_data_unlock(sk); 52*36b122baSDmytro Shytyi } 53*36b122baSDmytro Shytyi 54dfc8d060SDmytro Shytyi void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow, 55dfc8d060SDmytro Shytyi const struct mptcp_options_received *mp_opt) 56dfc8d060SDmytro Shytyi { 57dfc8d060SDmytro Shytyi struct sock *sk = (struct sock *)msk; 58dfc8d060SDmytro Shytyi struct sk_buff *skb; 59dfc8d060SDmytro Shytyi 60dfc8d060SDmytro Shytyi mptcp_data_lock(sk); 61dfc8d060SDmytro Shytyi skb = skb_peek_tail(&sk->sk_receive_queue); 62dfc8d060SDmytro Shytyi if (skb) { 63dfc8d060SDmytro Shytyi WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq); 64dfc8d060SDmytro Shytyi pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk, 65dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq, 66dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq); 67dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq; 68dfc8d060SDmytro Shytyi MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq; 69dfc8d060SDmytro Shytyi } 70dfc8d060SDmytro Shytyi 71dfc8d060SDmytro Shytyi pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq); 72dfc8d060SDmytro Shytyi mptcp_data_unlock(sk); 73dfc8d060SDmytro Shytyi } 74