From patchwork Mon Feb 17 18:28:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Abeni X-Patchwork-Id: 1239500 X-Patchwork-Delegate: pabeni@redhat.com 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=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.a=rsa-sha256 header.s=mimecast20190719 header.b=hs5eCZfz; dkim-atps=neutral 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48LsvK1gxcz9sRY for ; Tue, 18 Feb 2020 05:29:01 +1100 (AEDT) Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 21CC910FC3599; Mon, 17 Feb 2020 10:32:16 -0800 (PST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=205.139.110.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 [205.139.110.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 D4DA610FC3584 for ; Mon, 17 Feb 2020 10:32:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581964130; 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=ZOTbJ/TkDvRD+E6f5SvhYRvLuugr8SyQKWeWz1sd3EE=; b=hs5eCZfz1Oy+lTnA4VLhv9mjp+4bvnuChV/NWrxywu7sER2O+Vm39z1X7U/A1rpEp/4S02 LeWV2vKtPHy+KRrCDh5uqiw0V0DSl6muZ2ctS40abNvQNnvdMBC02AZs7oITDgdZBg7yKU P7eeJFGKiUJJsZ14ShO9rAIeXqSXJdg= 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-134-Agd0Pj6gPpuNNHRJDwLK8Q-1; Mon, 17 Feb 2020 13:28:46 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 48475801E67 for ; Mon, 17 Feb 2020 18:28:45 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-153.ams2.redhat.com [10.36.116.153]) by smtp.corp.redhat.com (Postfix) with ESMTP id AA67A8B54B for ; Mon, 17 Feb 2020 18:28:44 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.01.org Date: Mon, 17 Feb 2020 19:28:30 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: Agd0Pj6gPpuNNHRJDwLK8Q-1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: EW3UUCC2N4247I3ZMBHMTGKUMAXNGVVQ X-Message-ID-Hash: EW3UUCC2N4247I3ZMBHMTGKUMAXNGVVQ 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 4/7] Squash-to: "mptcp: Add handling of outgoing MP_JOIN requests" List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: record local id for outgoing MP_JOIN connection. join_id is the local address id, set as such in mptcp_syn_options() Signed-off-by: Paolo Abeni --- net/mptcp/options.c | 2 +- net/mptcp/protocol.h | 6 +++-- net/mptcp/subflow.c | 58 ++++++++++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 29ccff13412e..2716cbc0953f 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -309,7 +309,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, pr_debug("remote_token=%u, nonce=%u", subflow->remote_token, subflow->local_nonce); opts->suboptions = OPTION_MPTCP_MPJ_SYN; - opts->join_id = subflow->remote_id; + opts->join_id = subflow->local_id; opts->token = subflow->remote_token; opts->nonce = subflow->local_nonce; opts->backup = subflow->request_bkup; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index a64a12a02d19..d16bc5a94f56 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -256,8 +256,10 @@ mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow) int mptcp_is_enabled(struct net *net); bool mptcp_subflow_data_available(struct sock *sk); void mptcp_subflow_init(void); -int mptcp_subflow_connect(struct sock *sk, struct sockaddr *local, - struct sockaddr *remote, u8 remote_id); + +/* called with sk socket lock held */ +int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, + const struct mptcp_addr_info *remote); int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock); static inline void mptcp_subflow_tcp_fallback(struct sock *sk, diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 14c168df264d..6d45659f0802 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -24,19 +24,31 @@ static int subflow_rebuild_header(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); - int err = 0; + int local_id, err = 0; if (subflow->request_mptcp && !subflow->token) { pr_debug("subflow=%p", sk); err = mptcp_token_new_connect(sk); } else if (subflow->request_join && !subflow->local_nonce) { + struct mptcp_sock *msk = (struct mptcp_sock *)subflow->conn; + pr_debug("subflow=%p", sk); do { get_random_bytes(&subflow->local_nonce, sizeof(u32)); } while (!subflow->local_nonce); + + if (subflow->local_id) + goto out; + + local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)sk); + if (local_id < 0) + return -EINVAL; + + subflow->local_id = local_id; } +out: if (err) return err; @@ -761,59 +773,73 @@ void mptcpv6_handle_mapped(struct sock *sk, bool mapped) } #endif -int mptcp_subflow_connect(struct sock *sk, struct sockaddr *local, - struct sockaddr *remote, u8 remote_id) +static void mptcp_info2sockaddr(const struct mptcp_addr_info *info, + struct sockaddr_storage *addr) +{ + memset(addr, 0, sizeof(*addr)); + addr->ss_family = info->family; + if (addr->ss_family == AF_INET) { + struct sockaddr_in *in_addr = (struct sockaddr_in *)addr; + + in_addr->sin_addr = info->addr; + in_addr->sin_port = info->port; + } else if (addr->ss_family == AF_INET6) { + struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)addr; + + in6_addr->sin6_addr = info->addr6; + in6_addr->sin6_port = info->port; + } +} + +int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, + const struct mptcp_addr_info *remote) { struct mptcp_sock *msk = mptcp_sk(sk); struct mptcp_subflow_context *subflow; + struct sockaddr_storage addr; struct socket *sf; u32 remote_token; int addrlen; int err; - lock_sock(sk); - if (sk->sk_state != TCP_ESTABLISHED) { - release_sock(sk); + if (sk->sk_state != TCP_ESTABLISHED) return -ENOTCONN; - } err = mptcp_subflow_create_socket(sk, &sf); - if (err) { - release_sock(sk); + if (err) return err; - } subflow = mptcp_subflow_ctx(sf->sk); subflow->remote_key = msk->remote_key; subflow->local_key = msk->local_key; subflow->token = msk->token; + mptcp_info2sockaddr(loc, &addr); addrlen = sizeof(struct sockaddr_in); #if IS_ENABLED(CONFIG_MPTCP_IPV6) - if (local->sa_family == AF_INET6) + if (loc->family == AF_INET6) addrlen = sizeof(struct sockaddr_in6); #endif - err = kernel_bind(sf, local, addrlen); + err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen); if (err) goto failed; mptcp_crypto_key_sha(subflow->remote_key, &remote_token, NULL); pr_debug("msk=%p remote_token=%u", msk, remote_token); subflow->remote_token = remote_token; - subflow->remote_id = remote_id; + subflow->local_id = loc->id; subflow->request_join = 1; subflow->request_bkup = 1; + mptcp_info2sockaddr(remote, &addr); - err = kernel_connect(sf, remote, addrlen, O_NONBLOCK); + err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK); if (err && err != -EINPROGRESS) goto failed; - release_sock(sk); return err; failed: list_del_init(&subflow->node); - release_sock(sk); sock_release(sf); return err; }