From patchwork Tue Dec 3 12:35:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Abeni X-Patchwork-Id: 1203674 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=2001:19d0:306:5::1; helo=ml01.01.org; envelope-from=mptcp-bounces@lists.01.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Xc5DIGDX"; dkim-atps=neutral Received: from ml01.01.org (ml01.01.org [IPv6:2001:19d0:306:5::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47S1g03mP1z9sRG for ; Tue, 3 Dec 2019 23:35:56 +1100 (AEDT) Received: from ml01.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0BDBF101134ED; Tue, 3 Dec 2019 04:39:17 -0800 (PST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=207.211.31.120; helo=us-smtp-1.mimecast.com; envelope-from=pabeni@redhat.com; receiver= Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 12DD1101134EA for ; Tue, 3 Dec 2019 04:39:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1575376550; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2f/BeXLecOkw28PAshyX6ivVrNQNUFPC9cxYf+glL2c=; b=Xc5DIGDXdxyy0JS4mmHJ56ppQMK2ij+I+rrLydkRRf9VJ0apUY6iHV8OKEU6TPZW2C5gTD 6FjauCfZ3lj9A7dDlAU7foPNg7jUD9bDgJEDalraV7kfrg8qttfZzzEDhbycSLsLA4tGQU oD1qM3Tgj72VGu0uQJFV0r8kipYWmxA= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-343-VJ_cDHxMPl2mXnN1Z0Tt0w-1; Tue, 03 Dec 2019 07:35:43 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 811FE8017CC for ; Tue, 3 Dec 2019 12:35:42 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id DDABC60BFB for ; Tue, 3 Dec 2019 12:35:41 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.01.org Date: Tue, 3 Dec 2019 13:35:29 +0100 Message-Id: <86739a0eaa1063a30d25eb7744daeb86db4a78e1.1575376296.git.pabeni@redhat.com> In-Reply-To: <72975862a8d9c77313a512a29a91e62165e0c984.1575281341.git.pabeni@redhat.com> References: <72975862a8d9c77313a512a29a91e62165e0c984.1575281341.git.pabeni@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: VJ_cDHxMPl2mXnN1Z0Tt0w-1 X-Mimecast-Spam-Score: 0 Message-ID-Hash: BCTR3SKII35FZORDPAP6DFJ477RBFOTO X-Message-ID-Hash: BCTR3SKII35FZORDPAP6DFJ477RBFOTO X-MailFrom: pabeni@redhat.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] [PATCH v2 2/3] mptcp: avoid data stream corruption on allocation failure. List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Currently, when if mpext allocation fails, the data stream is corrupted, as we can add the required DSS nor roll-back the TCP status. Allocate a skb_ext before the actually skb_buff creation/TCP status update: in case of memory allocation failure we can bail early, avoiding the above condition. Additionally, if the ext is unused to to skb collapsing, cache the ext in the msk for the next send. Squash-to: "mptcp: Write MPTCP DSS headers to outgoing data packets" Signed-off-by: Paolo Abeni --- v1 -> v2: - properly convert to bool mptcp_ext_cache_refill() return value Note: a rebased tree including DATA_FIN, v1 and this patches is avaliable here: https://github.com/pabeni/mptcp/tree/mptcp_net-next_FIN_v1_recvmsg --- net/mptcp/protocol.c | 39 +++++++++++++++++++++++++-------------- net/mptcp/protocol.h | 1 + 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 3180202e56b4..baa5f84c7278 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -55,6 +55,14 @@ static struct sock *mptcp_subflow_get(const struct mptcp_sock *msk) return NULL; } +static bool mptcp_ext_cache_refill(struct mptcp_sock *msk) +{ + if (!msk->cached_ext) + msk->cached_ext = skb_ext_alloc(); + + return !!msk->cached_ext; +} + static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, struct msghdr *msg, long *timeo) { @@ -69,7 +77,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, * from one substream to another, but do per subflow memory accounting */ pfrag = sk_page_frag(sk); - while (!sk_page_frag_refill(ssk, pfrag)) { + while (!sk_page_frag_refill(ssk, pfrag) || + !mptcp_ext_cache_refill(msk)) { ret = sk_stream_wait_memory(ssk, timeo); if (ret) return ret; @@ -103,19 +112,19 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, iov_iter_revert(&msg->msg_iter, psize - ret); skb = tcp_write_queue_tail(ssk); - mpext = skb_ext_add(skb, SKB_EXT_MPTCP); - if (mpext) { - memset(mpext, 0, sizeof(*mpext)); - mpext->data_seq = msk->write_seq; - mpext->subflow_seq = mptcp_subflow_ctx(ssk)->rel_write_seq; - mpext->data_len = ret; - mpext->use_map = 1; - mpext->dsn64 = 1; - - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u dsn64=%d", - mpext->data_seq, mpext->subflow_seq, mpext->data_len, - mpext->dsn64); - } /* TODO: else fallback */ + mpext = __skb_ext_add(skb, SKB_EXT_MPTCP, msk->cached_ext); + msk->cached_ext = NULL; + + memset(mpext, 0, sizeof(*mpext)); + mpext->data_seq = msk->write_seq; + mpext->subflow_seq = mptcp_subflow_ctx(ssk)->rel_write_seq; + mpext->data_len = ret; + mpext->use_map = 1; + mpext->dsn64 = 1; + + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u dsn64=%d", + mpext->data_seq, mpext->subflow_seq, mpext->data_len, + mpext->dsn64); pfrag->offset += ret; msk->write_seq += ret; @@ -242,6 +251,8 @@ static void mptcp_close(struct sock *sk, long timeout) sock_release(mptcp_subflow_tcp_socket(subflow)); } + if (msk->cached_ext) + __skb_ext_put(msk->cached_ext); release_sock(sk); sk_common_release(sk); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 412718c1ae5c..3b8d1548dda1 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -58,6 +58,7 @@ struct mptcp_sock { u64 write_seq; u64 ack_seq; u32 token; + struct skb_ext *cached_ext; /* for the next sendmsg */ struct list_head conn_list; struct socket *subflow; /* outgoing connect/listener/!mp_capable */ };