From nobody Thu May 2 14:10:30 2024 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:a02:9f92:0:0:0:0:0 with SMTP id a18csp1996768jam; Wed, 9 Feb 2022 04:31:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJzYWdq2HOcBtTDG2Pp+pz9tJQOGGWq8aBwgie5LhjI/GXTyx2k2KVMpo40nD/6F6nndujth X-Received: by 2002:a05:6214:23c7:: with SMTP id hr7mr1313250qvb.4.1644409886605; Wed, 09 Feb 2022 04:31:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1644409886; cv=none; d=google.com; s=arc-20160816; b=fgVp0Io4837W+LLNhnWaCGDkNNBCiosaH8A0MSjS2q2/louvaPhVFGHYxf9nLiEkF4 ty80lhZBRQ4acdDA4/T5Oyp0NFXph+3jnO0gxsTVZk5U1nB6jqDLsvyBDW3aT5Sg3aJA JhVsnwbfPnqczJlhKsSgEW/28su5A7p8mzhMPrr9GPHnD1aYAFGg0/H+WTNjGrh2sIEz ENIX6YpebyTKsNlL8V+u+2j/LiFQiypdPxYpclBFA2dXC42eYY9Ey24o+K8Ar3UO9hXr OXUROsWzWkB7mzDwsj9ccvBLJF30dimuMBp58ochHiuEzlDHXvdxokC1IqtlE5m/rUN6 bV0g== 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=ENxyM9xqac9KDqr8QqifV0XIeP5iSoHbco3i1DceoNo=; b=HFmcoT5WVZuYwW8fH9AdkACC5oNt+Q4T7uyRKPxGrIP1r1q1HmpaTRt6c1k0Uy01H6 4yifvzN0OxCDJONsYv3jJJ22hDgq95qLvsqSbadwKf8yznclbB2hb6L8wuD7/pLYPBFf +j+QdBrmaGZQxhy5hTC6Fp7xJgjw6gC7UJztQz/jl+9Iu9/dKCrt/qPJs0pE3mUUHG3G +0eFS4e2Nd1zSc/TuIoU1qru8Ml3tAAwuKbtbc1yL3oJtUcFBwBqmxIT8hg5z046w8+D rlikUCbii292lHhXOq5/oBiZqoGx476mRx7f2pBz48jdMKW4MxSDnVbtkSY4kLiF4lPU nUpw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=LBUdl+tS; spf=pass (google.com: domain of mptcp+bounces-3580-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 2604:1380:1:3600::1 as permitted sender) smtp.mailfrom="mptcp+bounces-3580-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. [2604:1380:1:3600::1]) by mx.google.com with ESMTPS id 13si3044693qvt.543.2022.02.09.04.31.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Feb 2022 04:31:26 -0800 (PST) Received-SPF: pass (google.com: domain of mptcp+bounces-3580-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=@redhat.com header.s=mimecast20190719 header.b=LBUdl+tS; spf=pass (google.com: domain of mptcp+bounces-3580-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 2604:1380:1:3600::1 as permitted sender) smtp.mailfrom="mptcp+bounces-3580-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 43F031C0A44 for ; Wed, 9 Feb 2022 12:31:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D652729CA; Wed, 9 Feb 2022 12:31:24 +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.129.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 033942F28 for ; Wed, 9 Feb 2022 12:31:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644409882; 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=ENxyM9xqac9KDqr8QqifV0XIeP5iSoHbco3i1DceoNo=; b=LBUdl+tSJZFcqNOFyMhjY0aUxkFNYywLu8WpG1VuHgy8m/72a4uNSsNfB4sFLOXKFS1s1W dJtK8CO8bHhNXnntrYxOxXn07mx3T32d10/oo6oVXfXrRPSk58k26yPKv5dK3FC70m+5ss QuBoXS49nUIePwBGvWehwwfw2MSFWDk= 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-139-ZEx0P9AmOqOWss4Lj6FMoA-1; Wed, 09 Feb 2022 07:31:18 -0500 X-MC-Unique: ZEx0P9AmOqOWss4Lj6FMoA-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 8161F2F4C for ; Wed, 9 Feb 2022 12:31:17 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.193.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id CCBDA5F6DE for ; Wed, 9 Feb 2022 12:31:16 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-next] mptcp: strict local address ID selection. Date: Wed, 9 Feb 2022 13:31:01 +0100 Message-Id: <1d7dfcc6b0628ef009798298e0e5922513f30083.1644409809.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: this should address issues/225, the root cause is that dummy endpoint creation causes flush being unreliable when the tests flush the endpoints on both sides. This patch addressed that avoiding dummy endpoint creation. Beware! intentional RFC violation included ;) 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 | 59 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 64 insertions(+), 40 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 beb5ee38656a..f63b6f35d669 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..8d045c24da59 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -481,7 +481,45 @@ 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 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->local_id =3D err; + subflow->local_id_valid =3D 1; + 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); +} + +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); +} + + 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,12 +1442,9 @@ 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->local_id =3D local_id; + subflow->local_id_valid =3D 1; } =20 mptcp_pm_get_flags_and_ifindex_by_id(sock_net(sk), local_id, @@ -1435,7 +1470,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,6 +1769,9 @@ static void subflow_ulp_clone(const struct request_so= ck *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; @@ -1744,6 +1781,9 @@ static void subflow_ulp_clone(const struct request_so= ck *req, new_ctx->remote_id =3D subflow_req->remote_id; new_ctx->token =3D subflow_req->token; new_ctx->thmac =3D subflow_req->thmac; + + /* let rebuild header later get the correct ID */ + new_ctx->local_id_valid =3D 0; } } =20 @@ -1796,6 +1836,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 +1849,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 +1857,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