From nobody Fri Mar 29 05:31:37 2024 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:a02:b119:0:0:0:0:0 with SMTP id r25csp1603728jah; Sat, 15 Jan 2022 16:13:15 -0800 (PST) X-Google-Smtp-Source: ABdhPJxyi86ZM2ETIoXYdMPnQ3M3YIm+monT4wdtL0lkkFFHt3qNO6frCGQY3coMDEnX23BtbnJE X-Received: by 2002:a05:6214:629:: with SMTP id a9mr1019475qvx.110.1642291995453; Sat, 15 Jan 2022 16:13:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1642291995; cv=pass; d=google.com; s=arc-20160816; b=fceEcHUvNOoGb8BJCcIWKY8eCAmWPCnozg/B/W4Lvub6XujucR/kHumr6Ii+jxnMoc cc/F5A++NTYQc90B5UUafrEgkfH4QH2ExzlayegvnrV+bI7YhAEzNt9Cjqz+4R665Vtv cOJ5h35YaYi6h/FAeO4dtQ5a3W8x5mVnW4lcqnGIdt/WHcgvhhk4G1VzlgZd/CxA4yZp oNODDoocsV4UxV2lBTdh4R47nCm6nAH1ngMWnNaq4xZHiVKVIGF/CGtWKbwOwbiPut6O zBbF06530/QADcMeaDOaUbJf39iug9UwI/NqEWF1mhEmTD4cyVZDSQTNOfJvBxqyMiih 8ckw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:subject:message-id:cc:to :from:dkim-signature; bh=0ET53qKKaZutSx6wVRwxFnbTzLwm420kyaKFvHN1dM8=; b=LNbKUVaJMe6GIL7+JnkEHii+7fYJCarWYq8K6vD/qT/4oyZyW0YBA9k/YX7dhbV8KH HeR0h0rU/b5mMm6Ut4GMSU9jo5UA9Abn7osf+3e+oQ9bEQvleKRF54B9nCgInmoqIG/8 Y3JQuPKBuhyzZHQ3QKPDzvxa0rwHTJcTsnBnS7byIsu/VS4M1uKL1BRvWGpnu6VP7B3t 2cVO6LjdCUDno7+g9bHRLTni807E6wkSsdb97vPwt930lj8HoEEeqi2YJATBK6bzAUXL o2Zguj0Q8cB/+/l40F0oHshDgHS3gHUaM2X/hoCP+YsSBZ9X0exJuMiNbo17lJQFUjKS zyTA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@shytyi.net header.s=hs header.b="A6/03jsI"; arc=pass (i=1 spf=pass spfdomain=shytyi.net dkim=pass dkdomain=shytyi.net dmarc=pass fromdomain=shytyi.net>); spf=pass (google.com: domain of mptcp+bounces-3172-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 2604:1380:1:3600::1 as permitted sender) smtp.mailfrom="mptcp+bounces-3172-wpasupplicant.patchew=gmail.com@lists.linux.dev" Return-Path: Received: from ewr.edge.kernel.org (ewr.edge.kernel.org. [2604:1380:1:3600::1]) by mx.google.com with ESMTPS id p129si3684702qke.506.2022.01.15.16.13.15 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 15 Jan 2022 16:13:15 -0800 (PST) Received-SPF: pass (google.com: domain of mptcp+bounces-3172-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 2604:1380:1:3600::1 as permitted sender) client-ip=2604:1380:1:3600::1; Authentication-Results: mx.google.com; dkim=pass header.i=@shytyi.net header.s=hs header.b="A6/03jsI"; arc=pass (i=1 spf=pass spfdomain=shytyi.net dkim=pass dkdomain=shytyi.net dmarc=pass fromdomain=shytyi.net>); spf=pass (google.com: domain of mptcp+bounces-3172-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 2604:1380:1:3600::1 as permitted sender) smtp.mailfrom="mptcp+bounces-3172-wpasupplicant.patchew=gmail.com@lists.linux.dev" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ewr.edge.kernel.org (Postfix) with ESMTPS id BA5161C0B3F for ; Sun, 16 Jan 2022 00:13:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 53B1C2CA0; Sun, 16 Jan 2022 00:13:13 +0000 (UTC) X-Original-To: mptcp@lists.linux.dev Received: from sender11-of-o51.zoho.eu (sender11-of-o51.zoho.eu [31.186.226.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F33EF2C9C for ; Sun, 16 Jan 2022 00:13:10 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; t=1642291982; cv=none; d=zohomail.eu; s=zohoarc; b=PExaWF5gO3QIqZKjBS+6rA30XipDLNRTiwKL7v1i1UC2idPVGaG5zYWudsfc7MCN+bhs6kKq+dnFP1BzvCAQ27VlJnWwWaDtHBjpVxK7OVWWZyqlgX/T3Oa9OQJq0cIiodMuVJFRQS1XHmyzID4ihYHY8vMPolhOKqtIjbzPHRE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.eu; s=zohoarc; t=1642291982; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:MIME-Version:Message-ID:Subject:To; bh=0ET53qKKaZutSx6wVRwxFnbTzLwm420kyaKFvHN1dM8=; b=NDZIz6kVUa0OI85GbLRFxmWT/NxK9R7KoSnucfM6reYuP8GhYIF1aepWTjjAHLxZzO/rqvzprS+Pgf0Y37hDk1y791k7VtsgqMeg83iQsFQERLcn+KRDK/TsnaqD7nxVonWSMjCy5fRUYQn/IQ3oWz6G6MoKK257ibomnP8Knfg= ARC-Authentication-Results: i=1; mx.zohomail.eu; dkim=pass header.i=shytyi.net; spf=pass smtp.mailfrom=dmytro@shytyi.net; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1642291982; s=hs; d=shytyi.net; i=dmytro@shytyi.net; h=From:To:Cc:Message-ID:Subject:Date:MIME-Version:Content-Transfer-Encoding:Content-Type; bh=0ET53qKKaZutSx6wVRwxFnbTzLwm420kyaKFvHN1dM8=; b=A6/03jsIVYt33KQNwYYX+ctzWp/hTo38Mh5vLZ+APEwa0LP+haDBbrPGIuJ7kmY1 U86EQRPjh2VAvHmj7sjsyhuoOnnHdFPVPrtxi9CKs7xPFcnKHRnGkYLbseBaPP6f62R 8tLeYU2vOot4AjwB71aqwbxWwyXhS7kujYYVkwMM= Received: from doris.lan (vps-f3afed4e.vps.ovh.net [198.244.151.99]) by mx.zoho.eu with SMTPS id 1642291981921111.24901383148847; Sun, 16 Jan 2022 01:13:01 +0100 (CET) From: Dmytro SHYTYI To: mptcp@lists.linux.dev Cc: Dmytro SHYTYI Message-ID: <20220116001259.203319-1-dmytro@shytyi.net> Subject: [PATCH net-next v2] net: mptcp, Fast Open Mechanism Date: Sun, 16 Jan 2022 00:12:59 +0000 X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMailClient: External Content-Type: text/plain; charset="utf-8" This set of patches will bring "Fast Open" Option support to MPTCP. The aim of Fast Open Mechanism is to eliminate one round trip time from a TCP conversation by allowing data to be included as part of the SYN segment that initiates the connection. IETF RFC 8684: Appendix B. TCP Fast Open and MPTCP. [PATCH v2] includes "client-server" partial support for : 1. MPTCP cookie request from client. 2. MPTCP cookie offering from server. 3. MPTCP SYN+DATA+COOKIE from client. 4. subsequent write + read on the opened socket. This patch is Work In Progress and an early draft shared due community request. Signed-off-by: Dmytro SHYTYI Reported-by: Dan Carpenter Reported-by: kernel test robot --- include/linux/tcp.h | 7 ++++ net/ipv4/inet_connection_sock.c | 3 +- net/ipv4/tcp_fastopen.c | 42 +++++++++++++++++++---- net/ipv4/tcp_input.c | 16 +++++---- net/mptcp/protocol.c | 59 ++++++++++++++++++++++++++++++--- net/mptcp/sockopt.c | 40 ++++++++++++++++++++++ net/mptcp/subflow.c | 14 ++++++++ 7 files changed, 162 insertions(+), 19 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 48d8a363319e..d7092234d442 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -54,7 +54,14 @@ static inline unsigned int tcp_optlen(const struct sk_bu= ff *skb) /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ + +#if IS_ENABLED(CONFIG_MPTCP) +#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by MPTCP impl. */ +#else #define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ +#endif + + =20 /* TCP Fast Open Cookie as stored in memory */ struct tcp_fastopen_cookie { diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_soc= k.c index f7fea3a7c5e6..4b4159c0258d 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -501,7 +501,8 @@ struct sock *inet_csk_accept(struct sock *sk, int flags= , int *err, bool kern) req =3D reqsk_queue_remove(queue, sk); newsk =3D req->sk; =20 - if (sk->sk_protocol =3D=3D IPPROTO_TCP && + if ((sk->sk_protocol =3D=3D IPPROTO_TCP || + sk->sk_protocol =3D=3D IPPROTO_MPTCP) && tcp_rsk(req)->tfo_listener) { spin_lock_bh(&queue->fastopenq.lock); if (tcp_rsk(req)->tfo_listener) { diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index fdbcf2a6d08e..d26378983ed7 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -119,15 +119,26 @@ static bool __tcp_fastopen_cookie_gen_cipher(struct r= equest_sock *req, const siphash_key_t *key, struct tcp_fastopen_cookie *foc) { +#if IS_ENABLED(CONFIG_MPTCP) + BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE !=3D sizeof(u32)); +#else BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE !=3D sizeof(u64)); +#endif =20 if (req->rsk_ops->family =3D=3D AF_INET) { const struct iphdr *iph =3D ip_hdr(syn); =20 +#if IS_ENABLED(CONFIG_MPTCP) + foc->val[0] =3D cpu_to_le32(siphash(&iph->saddr, + sizeof(iph->saddr) + + sizeof(iph->daddr), + key)); +#else foc->val[0] =3D cpu_to_le64(siphash(&iph->saddr, sizeof(iph->saddr) + sizeof(iph->daddr), key)); +#endif foc->len =3D TCP_FASTOPEN_COOKIE_SIZE; return true; } @@ -149,6 +160,7 @@ static bool __tcp_fastopen_cookie_gen_cipher(struct req= uest_sock *req, /* Generate the fastopen cookie by applying SipHash to both the source and * destination addresses. */ +/* static void tcp_fastopen_cookie_gen(struct sock *sk, struct request_sock *req, struct sk_buff *syn, @@ -162,6 +174,7 @@ static void tcp_fastopen_cookie_gen(struct sock *sk, __tcp_fastopen_cookie_gen_cipher(req, syn, &ctx->key[0], foc); rcu_read_unlock(); } +*/ =20 /* If an incoming SYN or SYNACK frame contains a payload and/or FIN, * queue this additional data / FIN. @@ -291,12 +304,12 @@ static struct sock *tcp_fastopen_create_child(struct = sock *sk, */ return child; } - +/* static bool tcp_fastopen_queue_check(struct sock *sk) { struct fastopen_queue *fastopenq; =20 - /* Make sure the listener has enabled fastopen, and we don't + * Make sure the listener has enabled fastopen, and we don't * exceed the max # of pending TFO requests allowed before trying * to validating the cookie in order to avoid burning CPU cycles * unnecessarily. @@ -305,7 +318,7 @@ static bool tcp_fastopen_queue_check(struct sock *sk) * processing a cookie request is that clients can't differentiate * between qlen overflow causing Fast Open to be disabled * temporarily vs a server not supporting Fast Open at all. - */ + * fastopenq =3D &inet_csk(sk)->icsk_accept_queue.fastopenq; if (fastopenq->max_qlen =3D=3D 0) return false; @@ -327,7 +340,7 @@ static bool tcp_fastopen_queue_check(struct sock *sk) } return true; } - +*/ static bool tcp_fastopen_no_cookie(const struct sock *sk, const struct dst_entry *dst, int flag) @@ -346,28 +359,43 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct= sk_buff *skb, struct tcp_fastopen_cookie *foc, const struct dst_entry *dst) { + /* bool syn_data =3D TCP_SKB_CB(skb)->end_seq !=3D TCP_SKB_CB(skb)->seq + 1; int tcp_fastopen =3D sock_net(sk)->ipv4.sysctl_tcp_fastopen; + */ struct tcp_fastopen_cookie valid_foc =3D { .len =3D -1 }; struct sock *child; int ret =3D 0; =20 if (foc->len =3D=3D 0) /* Client requests a cookie */ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD); - +/* if (!((tcp_fastopen & TFO_SERVER_ENABLE) && (syn_data || foc->len >=3D 0) && tcp_fastopen_queue_check(sk))) { foc->len =3D -1; return NULL; } - +*/ if (tcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD)) goto fastopen; =20 if (foc->len =3D=3D 0) { /* Client requests a cookie. */ - tcp_fastopen_cookie_gen(sk, req, skb, &valid_foc); + //tcp_fastopen_cookie_gen(sk, req, skb, &valid_foc); + + struct tcp_fastopen_context *ctx; + struct iphdr *iph =3D ip_hdr(skb); + + tcp_fastopen_init_key_once(sock_net(sk)); + ctx =3D tcp_fastopen_get_ctx(sk); + + valid_foc.val[0] =3D cpu_to_le32(siphash(&iph->saddr, + sizeof(iph->saddr) + + sizeof(iph->daddr), + &ctx->key[0])); + valid_foc.len =3D TCP_FASTOPEN_COOKIE_SIZE; + } else if (foc->len > 0) { ret =3D tcp_fastopen_cookie_gen_check(sk, req, skb, foc, &valid_foc); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 246ab7b5e857..915570132014 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5908,7 +5908,6 @@ void tcp_rcv_established(struct sock *sk, struct sk_b= uff *skb) } else { tcp_update_wl(tp, TCP_SKB_CB(skb)->seq); } - __tcp_ack_snd_check(sk, 0); no_ack: if (eaten) @@ -6229,9 +6228,10 @@ static int tcp_rcv_synsent_state_process(struct sock= *sk, struct sk_buff *skb, } if (fastopen_fail) return -1; - if (sk->sk_write_pending || - icsk->icsk_accept_queue.rskq_defer_accept || - inet_csk_in_pingpong_mode(sk)) { + + if ((sk->sk_write_pending || + icsk->icsk_accept_queue.rskq_defer_accept || + inet_csk_in_pingpong_mode(sk)) && !th->syn) { /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * @@ -6243,9 +6243,10 @@ static int tcp_rcv_synsent_state_process(struct sock= *sk, struct sk_buff *skb, tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, TCP_DELACK_MAX, TCP_RTO_MAX); - discard: tcp_drop(sk, skb); + tcp_send_ack(sk); + return 0; } else { tcp_send_ack(sk); @@ -6425,6 +6426,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_= buff *skb) tcp_urg(sk, skb, th); __kfree_skb(skb); tcp_data_snd_check(sk); + return 0; } =20 @@ -6901,7 +6903,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, */ pr_drop_req(req, ntohs(tcp_hdr(skb)->source), rsk_ops->family); - goto drop_and_release; + //goto drop_and_release; } =20 isn =3D af_ops->init_seq(skb); @@ -6954,7 +6956,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, reqsk_put(req); return 0; =20 -drop_and_release: +//drop_and_release: dst_release(dst); drop_and_free: __reqsk_free(req); diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index cd6b11c9b54d..3020a9c95a31 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -52,6 +52,8 @@ static struct percpu_counter mptcp_sockets_allocated; =20 static void __mptcp_destroy_sock(struct sock *sk); static void __mptcp_check_send_data_fin(struct sock *sk); +static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uadd= r, + int addr_len, int flags); =20 DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); static struct net_device mptcp_napi_dev; @@ -1677,6 +1679,53 @@ static void __mptcp_subflow_push_pending(struct sock= *sk, struct sock *ssk) } } =20 +static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, + size_t len, struct mptcp_sock *msk, size_t copied) +{ + const struct iphdr *iph; + struct ubuf_info *uarg; + struct sockaddr *uaddr; + struct sk_buff *skb; + struct tcp_sock *tp; + struct socket *ssk; + int ret; + + ssk =3D __mptcp_nmpc_socket(msk); + if (unlikely(!ssk)) + goto out_EFAULT; + skb =3D sk_stream_alloc_skb(ssk->sk, 0, ssk->sk->sk_allocation, true); + if (unlikely(!skb)) + goto out_EFAULT; + iph =3D ip_hdr(skb); + if (unlikely(!iph)) + goto out_EFAULT; + uarg =3D msg_zerocopy_realloc(sk, len, skb_zcopy(skb)); + if (unlikely(!uarg)) + goto out_EFAULT; + uaddr =3D msg->msg_name; + + tp =3D tcp_sk(ssk->sk); + if (unlikely(!tp)) + goto out_EFAULT; + if (!tp->fastopen_req) + tp->fastopen_req =3D kzalloc(sizeof(*tp->fastopen_req), ssk->sk->sk_allo= cation); + + if (unlikely(!tp->fastopen_req)) + goto out_EFAULT; + tp->fastopen_req->data =3D msg; + tp->fastopen_req->size =3D len; + tp->fastopen_req->uarg =3D uarg; + + /* requests a cookie */ + ret =3D mptcp_stream_connect(sk->sk_socket, uaddr, + msg->msg_namelen, msg->msg_flags); + + return ret; +out_EFAULT: + ret =3D -EFAULT; + return ret; +} + static void mptcp_set_nospace(struct sock *sk) { /* enable autotune */ @@ -1694,9 +1743,9 @@ static int mptcp_sendmsg(struct sock *sk, struct msgh= dr *msg, size_t len) int ret =3D 0; long timeo; =20 - /* we don't support FASTOPEN yet */ + /* we don't fully support FASTOPEN yet */ if (msg->msg_flags & MSG_FASTOPEN) - return -EOPNOTSUPP; + ret =3D mptcp_sendmsg_fastopen(sk, msg, len, msk, copied); =20 /* silently ignore everything else */ msg->msg_flags &=3D MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL; @@ -2482,10 +2531,10 @@ static void mptcp_worker(struct work_struct *work) =20 if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags)) __mptcp_close_subflow(msk); - + /* if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) __mptcp_retrans(sk); - + */ unlock: release_sock(sk); sock_put(sk); @@ -2589,6 +2638,8 @@ void mptcp_subflow_shutdown(struct sock *sk, struct s= ock *ssk, int how) case TCP_SYN_SENT: tcp_disconnect(ssk, O_NONBLOCK); break; + case TCP_ESTABLISHED: + break; default: if (__mptcp_check_fallback(mptcp_sk(sk))) { pr_debug("Fallback"); diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 0f1e661c2032..0e471e31e72a 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -539,6 +539,7 @@ static bool mptcp_supported_sockopt(int level, int optn= ame) case TCP_TIMESTAMP: case TCP_NOTSENT_LOWAT: case TCP_TX_DELAY: + case TCP_FASTOPEN: return true; } =20 @@ -598,6 +599,43 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct = mptcp_sock *msk, sockptr_t return ret; } =20 +static int mptcp_setsockopt_sol_tcp_fastopen(struct mptcp_sock *msk, sockp= tr_t optval, + unsigned int optlen) +{ + struct mptcp_subflow_context *subflow; + struct sock *sk =3D (struct sock *)msk; + struct net *net =3D sock_net(sk); + int val; + int ret; + + ret =3D 0; + + if (copy_from_sockptr(&val, optval, sizeof(val))) + return -EFAULT; + + lock_sock(sk); + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + + lock_sock(ssk); + + if (val >=3D 0 && ((1 << sk->sk_state) & (TCPF_CLOSE | + TCPF_LISTEN))) { + tcp_fastopen_init_key_once(net); + fastopen_queue_tune(sk, val); + } else { + ret =3D -EINVAL; + } + + release_sock(ssk); + } + + release_sock(sk); + + return ret; +} + static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, sockptr_t optval, unsigned int optlen) { @@ -606,6 +644,8 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *= msk, int optname, return -EOPNOTSUPP; case TCP_CONGESTION: return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen); + case TCP_FASTOPEN: + return mptcp_setsockopt_sol_tcp_fastopen(msk, optval, optlen); } =20 return -EOPNOTSUPP; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 6172f380dfb7..82976b31f2f2 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -966,6 +966,7 @@ static enum mapping_status get_mapping_status(struct so= ck *ssk, trace_get_mapping_status(mpext); =20 data_len =3D mpext->data_len; + if (data_len =3D=3D 0) { MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX); return MAPPING_INVALID; @@ -1024,6 +1025,7 @@ static enum mapping_status get_mapping_status(struct = sock *ssk, /* If this skb data are fully covered by the current mapping, * the new map would need caching, which is not supported */ + if (skb_is_fully_mapped(ssk, skb)) { MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSNOMATCH); return MAPPING_INVALID; @@ -1044,6 +1046,7 @@ static enum mapping_status get_mapping_status(struct = sock *ssk, subflow->map_data_csum =3D csum_unfold(mpext->csum); =20 /* Cfr RFC 8684 Section 3.3.0 */ + if (unlikely(subflow->map_csum_reqd !=3D csum_reqd)) return MAPPING_INVALID; =20 @@ -1180,9 +1183,19 @@ static bool subflow_check_data_avail(struct sock *ss= k) } =20 if (subflow->mp_join || subflow->fully_established) { + skb =3D skb_peek(&ssk->sk_receive_queue); + subflow->map_valid =3D 1; + subflow->map_seq =3D READ_ONCE(msk->ack_seq); + subflow->map_data_len =3D skb->len; + subflow->map_subflow_seq =3D tcp_sk(ssk)->copied_seq - subflow->ssn_offs= et; + + WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_DATA_AVAIL); + return true; + /* fatal protocol error, close the socket. * subflow_error_report() will introduce the appropriate barriers */ + /* ssk->sk_err =3D EBADMSG; tcp_set_state(ssk, TCP_CLOSE); subflow->reset_transient =3D 0; @@ -1190,6 +1203,7 @@ static bool subflow_check_data_avail(struct sock *ssk) tcp_send_active_reset(ssk, GFP_ATOMIC); WRITE_ONCE(subflow->data_avail, 0); return false; + */ } =20 __mptcp_do_fallback(msk); --=20 2.25.1