From patchwork Wed Feb 5 02:06:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mat Martineau X-Patchwork-Id: 1233648 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.01.org (client-ip=198.145.21.10; helo=ml01.01.org; envelope-from=mptcp-bounces@lists.01.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48C4gx186kz9sS9 for ; Wed, 5 Feb 2020 13:07:07 +1100 (AEDT) Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1B1101007B17B; Tue, 4 Feb 2020 18:10:21 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=mathew.j.martineau@linux.intel.com; receiver= Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E06D61007B1F8 for ; Tue, 4 Feb 2020 18:10:19 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Feb 2020 18:07:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,404,1574150400"; d="scan'208";a="219952211" Received: from mjmartin-nuc02.mjmartin-nuc02 (HELO mjmartin-nuc02.sea.intel.com) ([10.251.20.42]) by orsmga007.jf.intel.com with ESMTP; 04 Feb 2020 18:07:01 -0800 From: Mat Martineau To: mptcp@lists.01.org Cc: Mat Martineau Date: Tue, 4 Feb 2020 18:06:46 -0800 Message-Id: <20200205020648.72997-2-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200205020648.72997-1-mathew.j.martineau@linux.intel.com> References: <20200205020648.72997-1-mathew.j.martineau@linux.intel.com> MIME-Version: 1.0 Message-ID-Hash: P23P2SFDYMLV3MH2LDFLP3K5ICP4KYGX X-Message-ID-Hash: P23P2SFDYMLV3MH2LDFLP3K5ICP4KYGX X-MailFrom: mathew.j.martineau@linux.intel.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.1.1 Precedence: list Subject: [MPTCP] [RFC PATCH 1/3] mptcp: Check connection state before attempting send List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: MPTCP should wait for an active connection or skip sending depending on the connection state, as TCP does. This happens before the possible passthrough to a regular TCP sendmsg because the subflow's socket type (MPTCP or TCP fallback) is not known until the connection is complete. Signed-off-by: Mat Martineau --- net/mptcp/protocol.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index ae5494a8f60e..e856bde01ebf 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -572,6 +572,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) return -EOPNOTSUPP; lock_sock(sk); + + timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); + + if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { + ret = sk_stream_wait_connect(sk, &timeo); + if (ret) + goto out; + } + ssock = __mptcp_tcp_fallback(msk); if (unlikely(ssock)) { fallback: @@ -580,8 +589,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) return ret >= 0 ? ret + copied : (copied ? copied : ret); } - timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); - mptcp_clean_una(sk); __mptcp_flush_join_list(msk); From patchwork Wed Feb 5 02:06:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mat Martineau X-Patchwork-Id: 1233650 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.01.org (client-ip=198.145.21.10; helo=ml01.01.org; envelope-from=mptcp-bounces@lists.01.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48C4gx3Tqnz9sSR for ; Wed, 5 Feb 2020 13:07:07 +1100 (AEDT) Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2233A100780A5; Tue, 4 Feb 2020 18:10:22 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=mathew.j.martineau@linux.intel.com; receiver= Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0610B1007B1F8 for ; Tue, 4 Feb 2020 18:10:20 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Feb 2020 18:07:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,404,1574150400"; d="scan'208";a="219952213" Received: from mjmartin-nuc02.mjmartin-nuc02 (HELO mjmartin-nuc02.sea.intel.com) ([10.251.20.42]) by orsmga007.jf.intel.com with ESMTP; 04 Feb 2020 18:07:01 -0800 From: Mat Martineau To: mptcp@lists.01.org Cc: Mat Martineau Date: Tue, 4 Feb 2020 18:06:47 -0800 Message-Id: <20200205020648.72997-3-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200205020648.72997-1-mathew.j.martineau@linux.intel.com> References: <20200205020648.72997-1-mathew.j.martineau@linux.intel.com> MIME-Version: 1.0 Message-ID-Hash: 2JNBXYH4VYE3ELPBBM27J2BDK6B4RXM3 X-Message-ID-Hash: 2JNBXYH4VYE3ELPBBM27J2BDK6B4RXM3 X-MailFrom: mathew.j.martineau@linux.intel.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.1.1 Precedence: list Subject: [MPTCP] [RFC PATCH 2/3] mptcp: Use per-subflow storage for DATA_FIN sequence number List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Instead of reading the MPTCP-level sequence number when sending DATA_FIN, store the data in the subflow so it can be safely accessed when the subflow TCP headers are written to the packet without the MPTCP-level lock held. This also allows the MPTCP-level socket to close individual subflows without closing the MPTCP connection. Signed-off-by: Mat Martineau --- net/mptcp/options.c | 5 ++--- net/mptcp/protocol.c | 20 +++++++++++++++++--- net/mptcp/protocol.h | 2 ++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 97d2328fbb52..476959dc6253 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -411,7 +411,7 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, */ ext->use_map = 1; ext->dsn64 = 1; - ext->data_seq = mptcp_sk(subflow->conn)->write_seq; + ext->data_seq = subflow->data_fin_tx_seq; ext->subflow_seq = 0; ext->data_len = 1; } else { @@ -453,8 +453,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, if (mpext) opts->ext_copy = *mpext; - if (skb && tcp_fin && - subflow->conn->sk_state != TCP_ESTABLISHED) + if (skb && tcp_fin && subflow->data_fin_tx_enable) mptcp_write_data_fin(subflow, &opts->ext_copy); ret = true; } diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index e856bde01ebf..c6b5c82aee97 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1086,7 +1086,8 @@ static void mptcp_cancel_work(struct sock *sk) sock_put(sk); } -static void mptcp_subflow_shutdown(struct sock *ssk, int how) +static void mptcp_subflow_shutdown(struct sock *ssk, int how, + bool data_fin_tx_enable, u64 data_fin_tx_seq) { lock_sock(ssk); @@ -1099,6 +1100,14 @@ static void mptcp_subflow_shutdown(struct sock *ssk, int how) tcp_disconnect(ssk, O_NONBLOCK); break; default: + if (data_fin_tx_enable) { + struct mptcp_subflow_context *subflow; + + subflow = mptcp_subflow_ctx(ssk); + subflow->data_fin_tx_seq = data_fin_tx_seq; + subflow->data_fin_tx_enable = 1; + } + ssk->sk_shutdown |= how; tcp_shutdown(ssk, how); break; @@ -1115,6 +1124,7 @@ static void __mptcp_close(struct sock *sk, long timeout) struct mptcp_subflow_context *subflow, *tmp; struct mptcp_sock *msk = mptcp_sk(sk); LIST_HEAD(conn_list); + u64 data_fin_tx_seq; mptcp_token_destroy(msk->token); inet_sk_state_store(sk, TCP_CLOSE); @@ -1125,11 +1135,15 @@ static void __mptcp_close(struct sock *sk, long timeout) __mptcp_clear_xmit(sk); + data_fin_tx_seq = msk->write_seq; + release_sock(sk); list_for_each_entry_safe(subflow, tmp, &conn_list, node) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + subflow->data_fin_tx_seq = data_fin_tx_seq; + subflow->data_fin_tx_enable = 1; __mptcp_close_ssk(sk, ssk, subflow, timeout); } @@ -1211,7 +1225,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err, *err = -ENOBUFS; local_bh_enable(); release_sock(sk); - mptcp_subflow_shutdown(newsk, SHUT_RDWR + 1); + mptcp_subflow_shutdown(newsk, SHUT_RDWR + 1, 0, 0); tcp_close(newsk, 0); return NULL; } @@ -1730,7 +1744,7 @@ static int mptcp_shutdown(struct socket *sock, int how) mptcp_for_each_subflow(msk, subflow) { struct sock *tcp_sk = mptcp_subflow_tcp_sock(subflow); - mptcp_subflow_shutdown(tcp_sk, how); + mptcp_subflow_shutdown(tcp_sk, how, 1, msk->write_seq); } out_unlock: diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 3fbb33deb764..94fb8f586a95 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -228,9 +228,11 @@ struct mptcp_subflow_context { backup : 1, data_avail : 1, rx_eof : 1, + data_fin_tx_enable : 1, can_ack : 1; /* only after processing the remote a key */ u32 remote_nonce; u64 thmac; + u64 data_fin_tx_seq; u32 local_nonce; u32 remote_token; u8 hmac[MPTCPOPT_HMAC_LEN];