From nobody Fri May 3 16:07:47 2024 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 D10768479 for ; Fri, 23 Dec 2022 12:52:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1671799934; 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=ULqKTqz06NnyraDBeKRoaACwrjiY+WsUXPOEZwey9Dk=; b=KJntsJGpEo6vzFDypAaRZf9BPOWm6O+oc/TBUVRV8F4FUKxDlLjg1PcJpZ0lh94Jzy2BaL POP34hu3+JdeAk7x1QycPHPJXsLxqMqJz8i2pqzfzOQ4ME2jv+CBUSyswEiNKrvg2jRgAe aMS0HfdNJgyK8QcMypRQkPNnj2FICSI= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-20-jyomk6dtMOaqEfp_zRwL4w-1; Fri, 23 Dec 2022 07:52:12 -0500 X-MC-Unique: jyomk6dtMOaqEfp_zRwL4w-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A27E585C06B for ; Fri, 23 Dec 2022 12:52:12 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.193.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3996B2026D2A for ; Fri, 23 Dec 2022 12:52:12 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-next 1/3] mptcp: explicitly specify sock family at subflow creation time Date: Fri, 23 Dec 2022 13:51:29 +0100 Message-Id: <7d3aae6493caa1563d1aaadc79d299c01077f28a.1671799401.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Let the caller specify the to-be-created subflow family. No functional change intended, will be leveraged by the next patch. Signed-off-by: Paolo Abeni --- net/mptcp/protocol.c | 2 +- net/mptcp/protocol.h | 3 ++- net/mptcp/subflow.c | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5e813580c394..f08ef9ca242a 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -98,7 +98,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) struct socket *ssock; int err; =20 - err =3D mptcp_subflow_create_socket(sk, &ssock); + err =3D mptcp_subflow_create_socket(sk, sk->sk_family, &ssock); if (err) return err; =20 diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 3cd3270407b0..fcce8f03c1b5 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -643,7 +643,8 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info= *a, /* 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); +int mptcp_subflow_create_socket(struct sock *sk, unsigned short family, + struct socket **new_sock); void mptcp_info2sockaddr(const struct mptcp_addr_info *info, struct sockaddr_storage *addr, unsigned short family); diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index bd387d4b5a38..ec54413fb31f 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1547,7 +1547,7 @@ int __mptcp_subflow_connect(struct sock *sk, const st= ruct mptcp_addr_info *loc, if (!mptcp_is_fully_established(sk)) goto err_out; =20 - err =3D mptcp_subflow_create_socket(sk, &sf); + err =3D mptcp_subflow_create_socket(sk, loc->family, &sf); if (err) goto err_out; =20 @@ -1660,7 +1660,9 @@ static void mptcp_subflow_ops_undo_override(struct so= ck *ssk) #endif ssk->sk_prot =3D &tcp_prot; } -int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) + +int mptcp_subflow_create_socket(struct sock *sk, unsigned short family, + struct socket **new_sock) { struct mptcp_subflow_context *subflow; struct net *net =3D sock_net(sk); @@ -1673,8 +1675,7 @@ int mptcp_subflow_create_socket(struct sock *sk, stru= ct socket **new_sock) if (unlikely(!sk->sk_socket)) return -EINVAL; =20 - err =3D sock_create_kern(net, sk->sk_family, SOCK_STREAM, IPPROTO_TCP, - &sf); + err =3D sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP, &sf); if (err) return err; =20 --=20 2.38.1 From nobody Fri May 3 16:07:47 2024 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 11ED8847A for ; Fri, 23 Dec 2022 12:52:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1671799934; 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=+EjIE2Zndjrl4eSls/PHkc1KG8mM0I545IM+ojDh0T4=; b=a/H9RkZmMAgBpBD2fuPuAsJT3e/YRv83rxat27Y7S/9uM5Wm8VVcPwklDYADGi1RY7YpwA PZ3a8tFAF05pgcJ8TmJoJYvR49wFaG5skq9M03CX89vSMDfi2Cbxb0Dg+iVnrjXQItuk5j ku01QneeHxfGnxEZpBPbbp3LtKpyDoE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-29-GeNijvXlOx6Ieheag3DlmQ-1; Fri, 23 Dec 2022 07:52:13 -0500 X-MC-Unique: GeNijvXlOx6Ieheag3DlmQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5E5B18F6E8E for ; Fri, 23 Dec 2022 12:52:13 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.193.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id E9A182026D2A for ; Fri, 23 Dec 2022 12:52:12 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-next 2/3] mptcp: let the in kernel PM use mixed ipv4 and ipv6 addresses Date: Fri, 23 Dec 2022 13:51:30 +0100 Message-Id: <2aabefc61c5e7212d57156971633660d50176a4b.1671799401.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Currently the in kernel PM arbitrary enforces that created subflow's family must match the main MPTCP socket. The RFC allow instead for mixing IPv4 and IPv6 subflows with no constraint. This patch changes the in kernel PM logic to create subflows matching the currently selected source (or destination) address, effectively allowing the creation of IPv4 and IPv6 subflows under the same msk. While at that, factor out a new helper for address family matching, taking care of ipv4 vs ipv4-mapped-ipv6. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/269 Signed-off-by: Paolo Abeni --- net/mptcp/pm_netlink.c | 57 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index f2a43e13bacd..1d4ba6716a98 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -152,7 +152,6 @@ static struct mptcp_pm_addr_entry * select_local_address(const struct pm_nl_pernet *pernet, const struct mptcp_sock *msk) { - const struct sock *sk =3D (const struct sock *)msk; struct mptcp_pm_addr_entry *entry, *ret =3D NULL; =20 msk_owned_by_me(msk); @@ -165,16 +164,6 @@ select_local_address(const struct pm_nl_pernet *pernet, if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap)) continue; =20 - if (entry->addr.family !=3D sk->sk_family) { -#if IS_ENABLED(CONFIG_MPTCP_IPV6) - if ((entry->addr.family =3D=3D AF_INET && - !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) || - (sk->sk_family =3D=3D AF_INET && - !ipv6_addr_v4mapped(&entry->addr.addr6))) -#endif - continue; - } - ret =3D entry; break; } @@ -420,10 +409,25 @@ static bool lookup_address_in_vec(const struct mptcp_= addr_info *addrs, unsigned return false; } =20 +static bool addr_families_match(const struct mptcp_addr_info *a, + const struct mptcp_addr_info *b) +{ + if (a->family =3D=3D b->family) + return true; +#if IS_ENABLED(CONFIG_MPTCP_IPV6) + if ((a->family =3D=3D AF_INET && ipv6_addr_v4mapped(&b->addr6)) || + (b->family =3D=3D AF_INET && ipv6_addr_v4mapped(&a->addr6))) + return true; +#endif + return false; +} + /* Fill all the remote addresses into the array addrs[], * and return the array size. */ -static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool= fullmesh, +static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, + struct mptcp_addr_info *local, + bool fullmesh, struct mptcp_addr_info *addrs) { bool deny_id0 =3D READ_ONCE(msk->pm.remote_deny_join_id0); @@ -443,6 +447,9 @@ static unsigned int fill_remote_addresses_vec(struct mp= tcp_sock *msk, bool fullm if (deny_id0) return 0; =20 + if (!addr_families_match(local, &remote)) + return 0; + msk->pm.subflows++; addrs[i++] =3D remote; } else { @@ -453,6 +460,9 @@ static unsigned int fill_remote_addresses_vec(struct mp= tcp_sock *msk, bool fullm if (deny_id0 && !addrs[i].id) continue; =20 + if (!addr_families_match(local, &addrs[i])) + continue; + if (!lookup_address_in_vec(addrs, i, &addrs[i]) && msk->pm.subflows < subflows_max) { msk->pm.subflows++; @@ -600,10 +610,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(st= ruct mptcp_sock *msk) fullmesh =3D !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); =20 msk->pm.local_addr_used++; - nr =3D fill_remote_addresses_vec(msk, fullmesh, addrs); - if (nr) - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + nr =3D fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs); + __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); spin_unlock_bh(&msk->pm.lock); + for (i =3D 0; i < nr; i++) __mptcp_subflow_connect(sk, &local->addr, &addrs[i]); spin_lock_bh(&msk->pm.lock); @@ -625,9 +635,9 @@ static void mptcp_pm_nl_subflow_established(struct mptc= p_sock *msk) * and return the array size. */ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk, + struct mptcp_addr_info *remote, struct mptcp_addr_info *addrs) { - struct sock *sk =3D (struct sock *)msk; struct mptcp_pm_addr_entry *entry; struct mptcp_addr_info local; struct pm_nl_pernet *pernet; @@ -642,15 +652,8 @@ static unsigned int fill_local_addresses_vec(struct mp= tcp_sock *msk, if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH)) continue; =20 - if (entry->addr.family !=3D sk->sk_family) { -#if IS_ENABLED(CONFIG_MPTCP_IPV6) - if ((entry->addr.family =3D=3D AF_INET && - !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) || - (sk->sk_family =3D=3D AF_INET && - !ipv6_addr_v4mapped(&entry->addr.addr6))) -#endif - continue; - } + if (!addr_families_match(&entry->addr, remote)) + continue; =20 if (msk->pm.subflows < subflows_max) { msk->pm.subflows++; @@ -664,7 +667,7 @@ static unsigned int fill_local_addresses_vec(struct mpt= cp_sock *msk, */ if (!i) { memset(&local, 0, sizeof(local)); - local.family =3D msk->pm.remote.family; + local.family =3D remote->family; =20 msk->pm.subflows++; addrs[i++] =3D local; @@ -703,7 +706,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_= sock *msk) /* connect to the specified remote address, using whatever * local address the routing configuration will pick. */ - nr =3D fill_local_addresses_vec(msk, addrs); + nr =3D fill_local_addresses_vec(msk, &remote, addrs); =20 msk->pm.add_addr_accepted++; if (msk->pm.add_addr_accepted >=3D add_addr_accept_max || --=20 2.38.1 From nobody Fri May 3 16:07:47 2024 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 E005D8476 for ; Fri, 23 Dec 2022 12:52:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1671799935; 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=hmTeTVSvc0OuOA+0/+7/RlDQ31R39bxHVXEn9q42CYU=; b=HEwa6nOX89QRR1xRKi29B3voTJGGSHOrPbjQTckGeyYm9cVR7pUYAMQRhtWlP2NFJ94WhM lOFCqiGVzgtdQY1qv8S9Qwu/wRgcuZ1iOHr3SInGAu1J4NcTIVLLGU7rXKd1JUuMnWJGsX jHOEzehFWKvL8joSr5jv3VHyGXC0IVU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-156-B59-gSMhO2S5GJjr5dFLDA-1; Fri, 23 Dec 2022 07:52:14 -0500 X-MC-Unique: B59-gSMhO2S5GJjr5dFLDA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 19D4E1875041 for ; Fri, 23 Dec 2022 12:52:14 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.193.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id A116C2026D2A for ; Fri, 23 Dec 2022 12:52:13 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-next 3/3] selftests: mptcp: add test-cases for mixed v4/v6 subflows Date: Fri, 23 Dec 2022 13:51:31 +0100 Message-Id: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Note that we can't guess anymore the listener family based on the client target address; use always IPv6. Signed-off-by: Paolo Abeni --- .../testing/selftests/net/mptcp/mptcp_join.sh | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testin= g/selftests/net/mptcp/mptcp_join.sh index d11d3d566608..6ef4787ad244 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -774,24 +774,17 @@ do_transfer() addr_nr_ns2=3D${addr_nr_ns2:9} fi =20 - local local_addr - if is_v6 "${connect_addr}"; then - local_addr=3D"::" - else - local_addr=3D"0.0.0.0" - fi - extra_srv_args=3D"$extra_args $extra_srv_args" if [ "$test_link_fail" -gt 1 ];then timeout ${timeout_test} \ ip netns exec ${listener_ns} \ ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \ - $extra_srv_args ${local_addr} < "$sinfail" > "$sout" & + $extra_srv_args "::" < "$sinfail" > "$sout" & else timeout ${timeout_test} \ ip netns exec ${listener_ns} \ ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \ - $extra_srv_args ${local_addr} < "$sin" > "$sout" & + $extra_srv_args "::" < "$sin" > "$sout" & fi local spid=3D$! =20 @@ -2448,6 +2441,45 @@ v4mapped_tests() fi } =20 +mixed_tests() +{ + # subflow IPv4-mapped to IPv4-mapped + if reset "simult IPv4 and IPv6 subflows, first is IPv4"; then + pm_nl_set_limits $ns1 0 1 + pm_nl_set_limits $ns2 1 1 + pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal + run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow + chk_join_nr 1 1 1 + fi + + # subflow IPv4-mapped to IPv4-mapped + if reset "simult IPv4 and IPv6 subflows, first is IPv6"; then + pm_nl_set_limits $ns1 0 1 + pm_nl_set_limits $ns2 1 1 + pm_nl_add_endpoint $ns1 10.0.1.1 flags signal + run_tests $ns1 $ns2 dead:beef:2::1 0 0 0 slow + chk_join_nr 1 1 1 + fi + + if reset "simult IPv4 and IPv6 subflows, fullmesh 1x1"; then + pm_nl_set_limits $ns1 0 4 + pm_nl_set_limits $ns2 1 4 + pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow,fullmesh + pm_nl_add_endpoint $ns1 10.0.1.1 flags signal + run_tests $ns1 $ns2 dead:beef:2::1 0 0 0 slow + chk_join_nr 1 1 1 + fi + + if reset "simult IPv4 and IPv6 subflows, fullmesh 2x2"; then + pm_nl_set_limits $ns1 0 4 + pm_nl_set_limits $ns2 2 4 + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal + run_tests $ns1 $ns2 dead:beef:1::1 0 0 fullmesh_1 slow + chk_join_nr 4 4 4 + fi +} + backup_tests() { # single subflow, backup @@ -3120,6 +3152,7 @@ all_tests_sorted=3D( a@add_tests 6@ipv6_tests 4@v4mapped_tests + M@mixed_tests b@backup_tests p@add_addr_ports_tests k@syncookies_tests --=20 2.38.1