From nobody Fri May 3 02:16:21 2024 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:a02:9f92:0:0:0:0:0 with SMTP id a18csp2881430jam; Thu, 10 Feb 2022 02:07:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJz89XqrVrL9R+Ek0zLQYtA1n1k3ZDOBBGuuNlcJ75GOPAqZYhM9NIicuxGfJQlEDwgCSz+D X-Received: by 2002:ac8:59c6:: with SMTP id f6mr4181049qtf.343.1644487649806; Thu, 10 Feb 2022 02:07:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1644487649; cv=none; d=google.com; s=arc-20160816; b=XvBuvoOxb95e2K93XKUJ7InKY/4SbtcXsLkH44MP4Ad7GSo+SKItP/leBF0VHtWne+ NBwpNa0nS+GTzfxr8ROLhK8bipMgIFIa7EGJVYhoVrq/lxuE1amifhYvPb70UmFdU4hU bT6IEx7hMXjK/ibX0s8r0rC6DlLq1ZqOHWpICs1UxJFvG1o8lJWWBL8iQyggM8HScLZZ j89nTyLtW1uIiAp1l6aDg6hlt3WscKoZptN3X3v9SCOgtJ7Qkj8Joi5jjPXDOIvBUpAW VfTHKTdcaaQMdbdxS8YatTvWV0llhGB1N4x3jsAoIkxFtv+hn6Ip+uanfI56GNWvzvLJ sMeg== ARC-Message-Signature: i=1; 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:message-id:date:subject:to:from :dkim-signature; bh=19lzRj//pDv3I8Zo7XLJ//ZF0sCqPdpAneo7+BHFQdw=; b=ojOxK0EAstjK3ESTVTwNbGZQPs7PpZUOQHtFblH3zPA8cgwxW0cf22HX1O1rUs0DCE gSOa0NwuEnKXPdcotnMtS887kTm38eD0caufMUXbnFoe93NU+sZQYcJWOcdYIsOF7Xzq zQo7ZopD7HMaQCnxkbAl07kyALGBR7pOh7doVKLydgCJri3rvXtTGEuYcqgmexuDo2Do UkC/yBLjphvzq22+Q40Z41RGZYPymYdfZyhCEgx0bKEzdDkbf/2HIaJHXzpobzyt0GBN jcgVIP3p2cAjv/1FYAWUCssrQr6rExuEVXRNbF77KjmPJfEK+Ak9y0EqdOi3/bwoU9SY hs3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=YkmiE8Az; spf=pass (google.com: domain of mptcp+bounces-3625-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.197.195 as permitted sender) smtp.mailfrom="mptcp+bounces-3625-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from ewr.edge.kernel.org (ewr.edge.kernel.org. [147.75.197.195]) by mx.google.com with ESMTPS id 13si4980651qtp.445.2022.02.10.02.07.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 10 Feb 2022 02:07:29 -0800 (PST) Received-SPF: pass (google.com: domain of mptcp+bounces-3625-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.197.195 as permitted sender) client-ip=147.75.197.195; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=YkmiE8Az; spf=pass (google.com: domain of mptcp+bounces-3625-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.197.195 as permitted sender) smtp.mailfrom="mptcp+bounces-3625-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com 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 889091C0E5C for ; Thu, 10 Feb 2022 10:07:29 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3AE1829CA; Thu, 10 Feb 2022 10:07:28 +0000 (UTC) X-Original-To: mptcp@lists.linux.dev Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 9236E2F28 for ; Thu, 10 Feb 2022 10:07:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644487645; 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; bh=19lzRj//pDv3I8Zo7XLJ//ZF0sCqPdpAneo7+BHFQdw=; b=YkmiE8AzmiYZzB/y1VV9grL3jUosQwZc2H6/rg/SkWuxA/9BQMV+UY3gnIJA0Heqnm1eX/ pxtUjtcWodTksK7VuTy8rhqmuccooQY+jibeNK/Y3dhPl63LgV+GVjhYgjxyWVV+i645p/ Tkl029o7FFvZIE1Nekhg1MYdL3hBKWM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-528-UY58xcTPM_WQk2VHJrvelw-1; Thu, 10 Feb 2022 05:07:23 -0500 X-MC-Unique: UY58xcTPM_WQk2VHJrvelw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BD1D5193F561 for ; Thu, 10 Feb 2022 10:07:22 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.194.220]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D4D16F94E for ; Thu, 10 Feb 2022 10:07:21 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v2 mptcp-next] mptcp: strict local address ID selection. Date: Thu, 10 Feb 2022 11:07:17 +0100 Message-Id: <75e02d63aa8b03b873ad94f5b4d901776f9a81ea.1644487551.git.pabeni@redhat.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=pabeni@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The address ID selection for MPJ subflows created in response to incoming ADD_ADDR option is currently unreliable: it happens at MPJ socket creation time, when the local address could be unknown. Additionally, if the no local endpoint is available for the local address, a new dummy endpoint is created, confusing the user-land. This change refactor the code to move the address ID seleciton inside the rebuild_header() helper, when the local address eventually selected by the route lookup is finally known. If the address used is not mapped by any endpoint - and thus can't be advertised/removed pick the id 0 instead of allocate a new endpoint. Signed-off-by: Paolo Abeni --- Note: send v2 to address the build issue, to help the discussion v1 -> v2: - hopefully fix build issue with ipv6 disabled - avoid looking-up multiple times the local_id for req sockets - factor-out an helper for local_id initialization RFC -> v1: - don't bail if ID lookup fails, use 0 instead --- net/mptcp/pm_netlink.c | 39 +++++------------------- net/mptcp/protocol.c | 3 ++ net/mptcp/protocol.h | 3 +- net/mptcp/subflow.c | 69 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 72 insertions(+), 42 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 46346f009485..5f6395b10fdc 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -83,16 +83,6 @@ static bool addresses_equal(const struct mptcp_addr_info= *a, return a->port =3D=3D b->port; } =20 -static bool address_zero(const struct mptcp_addr_info *addr) -{ - struct mptcp_addr_info zero; - - memset(&zero, 0, sizeof(zero)); - zero.family =3D addr->family; - - return addresses_equal(addr, &zero, true); -} - static void local_address(const struct sock_common *skc, struct mptcp_addr_info *addr) { @@ -998,7 +988,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, st= ruct sock_common *skc) struct mptcp_addr_info skc_local; struct mptcp_addr_info msk_local; struct pm_nl_pernet *pernet; - int ret =3D -1; + int ret =3D 0; =20 if (WARN_ON_ONCE(!msk)) return -1; @@ -1011,9 +1001,6 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, = struct sock_common *skc) if (addresses_equal(&msk_local, &skc_local, false)) return 0; =20 - if (address_zero(&skc_local)) - return 0; - pernet =3D net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id); =20 rcu_read_lock(); @@ -1024,24 +1011,14 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk= , struct sock_common *skc) } } rcu_read_unlock(); - if (ret >=3D 0) - return ret; - - /* address not found, add to local list */ - entry =3D kmalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) - return -ENOMEM; - - entry->addr =3D skc_local; - entry->addr.id =3D 0; - entry->addr.port =3D 0; - entry->ifindex =3D 0; - entry->flags =3D 0; - entry->lsk =3D NULL; - ret =3D mptcp_pm_nl_append_new_local_addr(pernet, entry); - if (ret < 0) - kfree(entry); =20 + /* if src address is not mapped by any endpoint, we can't reliably pick an + * ID without creating "dummy" endpoint which would unexpectly pollute the + * netns. + * In such case arbitrary pick the 0 id. This is an RFC violation, as the + * mapping for ID 0 is not unique, but an unconsequential one: lacking the + * endpoint the peer can't generate RM_ADDR for this address + */ return ret; } =20 diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 3324e1c61576..57caf470e500 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -117,6 +117,9 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) list_add(&subflow->node, &msk->conn_list); sock_hold(ssock->sk); subflow->request_mptcp =3D 1; + + /* This is the first subflow, always with id 0 */ + subflow->local_id_valid =3D 1; mptcp_sock_graft(msk->first, sk->sk_socket); =20 return 0; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index a1ce1fd005ab..663b8d83154e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -453,7 +453,8 @@ struct mptcp_subflow_context { rx_eof : 1, can_ack : 1, /* only after processing the remote a key */ disposable : 1, /* ctx can be free at ulp release time */ - stale : 1; /* unable to snd/rcv data, do not use for xmit */ + stale : 1, /* unable to snd/rcv data, do not use for xmit */ + local_id_valid : 1; /* local_id is correctly initialized */ enum mptcp_data_avail data_avail; u32 remote_nonce; u64 thmac; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 485f00dcaf84..8e5e3c375ba1 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -481,7 +481,52 @@ static void subflow_finish_connect(struct sock *sk, co= nst struct sk_buff *skb) mptcp_subflow_reset(sk); } =20 -struct request_sock_ops mptcp_subflow_request_sock_ops; +static void subflow_set_local_id(struct mptcp_subflow_context *subflow, in= t local_id) +{ + subflow->local_id =3D local_id; + subflow->local_id_valid =3D 1; +} + +static int subflow_chk_local_id(struct sock *sk) +{ + struct mptcp_subflow_context *subflow =3D mptcp_subflow_ctx(sk); + struct mptcp_sock *msk =3D mptcp_sk(subflow->conn); + int err; + + if (likely(subflow->local_id_valid)) + return 0; + + err =3D mptcp_pm_get_local_id(msk, (struct sock_common *)sk); + if (err < 0) + return err; + + subflow_set_local_id(subflow, err); + return 0; +} + +static int subflow_rebuild_header(struct sock *sk) +{ + int err =3D subflow_chk_local_id(sk); + + if (unlikely(err < 0)) + return err; + + return inet_sk_rebuild_header(sk); +} + +#if IS_ENABLED(CONFIG_MPTCP_IPV6) +static int subflow_v6_rebuild_header(struct sock *sk) +{ + int err =3D subflow_chk_local_id(sk); + + if (unlikely(err < 0)) + return err; + + return inet6_sk_rebuild_header(sk); +} +#endif + + struct request_sock_ops mptcp_subflow_request_sock_ops; EXPORT_SYMBOL_GPL(mptcp_subflow_request_sock_ops); static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops; =20 @@ -1404,13 +1449,8 @@ int __mptcp_subflow_connect(struct sock *sk, const s= truct mptcp_addr_info *loc, get_random_bytes(&subflow->local_nonce, sizeof(u32)); } while (!subflow->local_nonce); =20 - if (!local_id) { - err =3D mptcp_pm_get_local_id(msk, (struct sock_common *)ssk); - if (err < 0) - goto failed; - - local_id =3D err; - } + if (local_id) + subflow_set_local_id(subflow, local_id); =20 mptcp_pm_get_flags_and_ifindex_by_id(sock_net(sk), local_id, &flags, &ifindex); @@ -1435,7 +1475,6 @@ int __mptcp_subflow_connect(struct sock *sk, const st= ruct mptcp_addr_info *loc, pr_debug("msk=3D%p remote_token=3D%u local_id=3D%d remote_id=3D%d", msk, remote_token, local_id, remote_id); subflow->remote_token =3D remote_token; - subflow->local_id =3D local_id; subflow->remote_id =3D remote_id; subflow->request_join =3D 1; subflow->request_bkup =3D !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP); @@ -1735,15 +1774,22 @@ static void subflow_ulp_clone(const struct request_= sock *req, new_ctx->token =3D subflow_req->token; new_ctx->ssn_offset =3D subflow_req->ssn_offset; new_ctx->idsn =3D subflow_req->idsn; + + /* this is the first subflow, id is always 0 */ + new_ctx->local_id_valid =3D 1; } else if (subflow_req->mp_join) { new_ctx->ssn_offset =3D subflow_req->ssn_offset; new_ctx->mp_join =3D 1; new_ctx->fully_established =3D 1; new_ctx->backup =3D subflow_req->backup; - new_ctx->local_id =3D subflow_req->local_id; new_ctx->remote_id =3D subflow_req->remote_id; new_ctx->token =3D subflow_req->token; new_ctx->thmac =3D subflow_req->thmac; + + /* the subflow req id is valid, fetched via subflow_check_req() + * and subflow_token_join_request() + */ + subflow_set_local_id(new_ctx, subflow_req->local_id); } } =20 @@ -1796,6 +1842,7 @@ void __init mptcp_subflow_init(void) subflow_specific.conn_request =3D subflow_v4_conn_request; subflow_specific.syn_recv_sock =3D subflow_syn_recv_sock; subflow_specific.sk_rx_dst_set =3D subflow_finish_connect; + subflow_specific.rebuild_header =3D subflow_rebuild_header; =20 tcp_prot_override =3D tcp_prot; tcp_prot_override.release_cb =3D tcp_release_cb_override; @@ -1808,6 +1855,7 @@ void __init mptcp_subflow_init(void) subflow_v6_specific.conn_request =3D subflow_v6_conn_request; subflow_v6_specific.syn_recv_sock =3D subflow_syn_recv_sock; subflow_v6_specific.sk_rx_dst_set =3D subflow_finish_connect; + subflow_v6_specific.rebuild_header =3D subflow_v6_rebuild_header; =20 subflow_v6m_specific =3D subflow_v6_specific; subflow_v6m_specific.queue_xmit =3D ipv4_specific.queue_xmit; @@ -1815,6 +1863,7 @@ void __init mptcp_subflow_init(void) subflow_v6m_specific.net_header_len =3D ipv4_specific.net_header_len; subflow_v6m_specific.mtu_reduced =3D ipv4_specific.mtu_reduced; subflow_v6m_specific.net_frag_header_len =3D 0; + subflow_v6m_specific.rebuild_header =3D subflow_rebuild_header; =20 tcpv6_prot_override =3D tcpv6_prot; tcpv6_prot_override.release_cb =3D tcp_release_cb_override; --=20 2.34.1