stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family
@ 2023-01-12 17:42 Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 1/3] mptcp: explicitly specify sock family at subflow creation time Matthieu Baerts
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Matthieu Baerts @ 2023-01-12 17:42 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Kishen Maloor,
	Florian Westphal, Shuah Khan
  Cc: netdev, mptcp, linux-kernel, linux-kselftest, Paolo Abeni,
	Mat Martineau, Matthieu Baerts, stable

Before these patches, the Userspace Path Manager would allow the
creation of subflows with wrong families: taking the one of the MPTCP
socket instead of the provided ones and resulting in the creation of
subflows with likely not the right source and/or destination IPs. It
would also allow the creation of subflows between different families or
not respecting v4/v6-only socket attributes.

Patch 1 lets the userspace PM select the proper family to avoid creating
subflows with the wrong source and/or destination addresses because the
family is not the expected one.

Patch 2 makes sure the userspace PM doesn't allow the userspace to
create subflows for a family that is not allowed.

Patch 3 validates scenarios with a mix of v4 and v6 subflows for the
same MPTCP connection.

These patches fix issues introduced in v5.19 when the userspace path
manager has been introduced.

To: "David S. Miller" <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Kishen Maloor <kishen.maloor@intel.com>
To: Florian Westphal <fw@strlen.de>
To: Shuah Khan <shuah@kernel.org>
Cc: netdev@vger.kernel.org
Cc: mptcp@lists.linux.dev
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>

---
Matthieu Baerts (2):
      mptcp: netlink: respect v4/v6-only sockets
      selftests: mptcp: userspace: validate v4-v6 subflows mix

Paolo Abeni (1):
      mptcp: explicitly specify sock family at subflow creation time

 net/mptcp/pm.c                                    | 25 ++++++++++++
 net/mptcp/pm_userspace.c                          |  7 ++++
 net/mptcp/protocol.c                              |  2 +-
 net/mptcp/protocol.h                              |  6 ++-
 net/mptcp/subflow.c                               |  9 +++--
 tools/testing/selftests/net/mptcp/userspace_pm.sh | 47 +++++++++++++++++++++++
 6 files changed, 90 insertions(+), 6 deletions(-)
---
base-commit: be53771c87f4e322a9835d3faa9cd73a4ecdec5b
change-id: 20230112-upstream-net-20230112-netlink-v4-v6-b6b958039ee0

Best regards,
-- 
Matthieu Baerts <matthieu.baerts@tessares.net>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net 1/3] mptcp: explicitly specify sock family at subflow creation time
  2023-01-12 17:42 [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family Matthieu Baerts
@ 2023-01-12 17:42 ` Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 2/3] mptcp: netlink: respect v4/v6-only sockets Matthieu Baerts
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Matthieu Baerts @ 2023-01-12 17:42 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Kishen Maloor,
	Florian Westphal, Shuah Khan
  Cc: netdev, mptcp, linux-kernel, linux-kselftest, Paolo Abeni,
	Mat Martineau, Matthieu Baerts, stable

From: Paolo Abeni <pabeni@redhat.com>

Let the caller specify the to-be-created subflow family.

For a given MPTCP socket created with the AF_INET6 family, the current
userspace PM can already ask the kernel to create subflows in v4 and v6.
If "plain" IPv4 addresses are passed to the kernel, they are
automatically mapped in v6 addresses "by accident". This can be
problematic because the userspace will need to pass different addresses,
now the v4-mapped-v6 addresses to destroy this new subflow.

On the other hand, if the MPTCP socket has been created with the AF_INET
family, the command to create a subflow in v6 will be accepted but the
result will not be the one as expected as new subflow will be created in
IPv4 using part of the v6 addresses passed to the kernel: not creating
the expected subflow then.

No functional change intended for the in-kernel PM where an explicit
enforcement is currently in place. This arbitrary enforcement will be
leveraged by other patches in a future version.

Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment")
Cc: stable@vger.kernel.org
Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
---
 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 b7ad030dfe89..8cd6cc67c2c5 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;
 
-	err = mptcp_subflow_create_socket(sk, &ssock);
+	err = mptcp_subflow_create_socket(sk, sk->sk_family, &ssock);
 	if (err)
 		return err;
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index a0d1658ce59e..a9e0355744b6 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -641,7 +641,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 struct mptcp_addr_info *loc,
 	if (!mptcp_is_fully_established(sk))
 		goto err_out;
 
-	err = mptcp_subflow_create_socket(sk, &sf);
+	err = mptcp_subflow_create_socket(sk, loc->family, &sf);
 	if (err)
 		goto err_out;
 
@@ -1660,7 +1660,9 @@ static void mptcp_subflow_ops_undo_override(struct sock *ssk)
 #endif
 		ssk->sk_prot = &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 = sock_net(sk);
@@ -1673,8 +1675,7 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
 	if (unlikely(!sk->sk_socket))
 		return -EINVAL;
 
-	err = sock_create_kern(net, sk->sk_family, SOCK_STREAM, IPPROTO_TCP,
-			       &sf);
+	err = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP, &sf);
 	if (err)
 		return err;
 

-- 
2.37.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 2/3] mptcp: netlink: respect v4/v6-only sockets
  2023-01-12 17:42 [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 1/3] mptcp: explicitly specify sock family at subflow creation time Matthieu Baerts
@ 2023-01-12 17:42 ` Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 3/3] selftests: mptcp: userspace: validate v4-v6 subflows mix Matthieu Baerts
  2023-01-14  6:00 ` [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Matthieu Baerts @ 2023-01-12 17:42 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Kishen Maloor,
	Florian Westphal, Shuah Khan
  Cc: netdev, mptcp, linux-kernel, linux-kselftest, Paolo Abeni,
	Mat Martineau, Matthieu Baerts, stable

If an MPTCP socket has been created with AF_INET6 and the IPV6_V6ONLY
option has been set, the userspace PM would allow creating subflows
using IPv4 addresses, e.g. mapped in v6.

The kernel side of userspace PM will also accept creating subflows with
local and remote addresses having different families. Depending on the
subflow socket's family, different behaviours are expected:
 - If AF_INET is forced with a v6 address, the kernel will take the last
   byte of the IP and try to connect to that: a new subflow is created
   but to a non expected address.
 - If AF_INET6 is forced with a v4 address, the kernel will try to
   connect to a v4 address (v4-mapped-v6). A -EBADF error from the
   connect() part is then expected.

It is then required to check the given families can be accepted. This is
done by using a new helper for addresses family matching, taking care of
IPv4 vs IPv4-mapped-IPv6 addresses. This helper will be re-used later by
the in-kernel path-manager to use mixed IPv4 and IPv6 addresses.

While at it, a clear error message is now reported if there are some
conflicts with the families that have been passed by the userspace.

Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment")
Cc: stable@vger.kernel.org
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
---
 net/mptcp/pm.c           | 25 +++++++++++++++++++++++++
 net/mptcp/pm_userspace.c |  7 +++++++
 net/mptcp/protocol.h     |  3 +++
 3 files changed, 35 insertions(+)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 45e2a48397b9..70f0ced3ca86 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -420,6 +420,31 @@ void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
 	}
 }
 
+/* if sk is ipv4 or ipv6_only allows only same-family local and remote addresses,
+ * otherwise allow any matching local/remote pair
+ */
+bool mptcp_pm_addr_families_match(const struct sock *sk,
+				  const struct mptcp_addr_info *loc,
+				  const struct mptcp_addr_info *rem)
+{
+	bool mptcp_is_v4 = sk->sk_family == AF_INET;
+
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	bool loc_is_v4 = loc->family == AF_INET || ipv6_addr_v4mapped(&loc->addr6);
+	bool rem_is_v4 = rem->family == AF_INET || ipv6_addr_v4mapped(&rem->addr6);
+
+	if (mptcp_is_v4)
+		return loc_is_v4 && rem_is_v4;
+
+	if (ipv6_only_sock(sk))
+		return !loc_is_v4 && !rem_is_v4;
+
+	return loc_is_v4 == rem_is_v4;
+#else
+	return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET;
+#endif
+}
+
 void mptcp_pm_data_reset(struct mptcp_sock *msk)
 {
 	u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk));
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 65dcc55a8ad8..ea6ad9da7493 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -294,6 +294,13 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	sk = (struct sock *)msk;
+
+	if (!mptcp_pm_addr_families_match(sk, &addr_l, &addr_r)) {
+		GENL_SET_ERR_MSG(info, "families mismatch");
+		err = -EINVAL;
+		goto create_err;
+	}
+
 	lock_sock(sk);
 
 	err = __mptcp_subflow_connect(sk, &addr_l, &addr_r);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index a9e0355744b6..601469249da8 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -777,6 +777,9 @@ int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
 int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
 			 bool require_family,
 			 struct mptcp_pm_addr_entry *entry);
+bool mptcp_pm_addr_families_match(const struct sock *sk,
+				  const struct mptcp_addr_info *loc,
+				  const struct mptcp_addr_info *rem);
 void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
 void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
 void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side);

-- 
2.37.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 3/3] selftests: mptcp: userspace: validate v4-v6 subflows mix
  2023-01-12 17:42 [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 1/3] mptcp: explicitly specify sock family at subflow creation time Matthieu Baerts
  2023-01-12 17:42 ` [PATCH net 2/3] mptcp: netlink: respect v4/v6-only sockets Matthieu Baerts
@ 2023-01-12 17:42 ` Matthieu Baerts
  2023-01-14  6:00 ` [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Matthieu Baerts @ 2023-01-12 17:42 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Kishen Maloor,
	Florian Westphal, Shuah Khan
  Cc: netdev, mptcp, linux-kernel, linux-kselftest, Paolo Abeni,
	Mat Martineau, Matthieu Baerts, stable

MPTCP protocol supports having subflows in both IPv4 and IPv6. In Linux,
it is possible to have that if the MPTCP socket has been created with
AF_INET6 family without the IPV6_V6ONLY option.

Here, a new IPv4 subflow is being added to the initial IPv6 connection,
then being removed using Netlink commands.

Cc: stable@vger.kernel.org # v5.19+
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
---
 tools/testing/selftests/net/mptcp/userspace_pm.sh | 47 +++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
index a29deb9fa024..ab2d581f28a1 100755
--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
+++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
@@ -752,6 +752,52 @@ test_subflows()
 	   "$server4_token" > /dev/null 2>&1
 }
 
+test_subflows_v4_v6_mix()
+{
+	# Attempt to add a listener at 10.0.2.1:<subflow-port>
+	ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\
+	   $app6_port > /dev/null 2>&1 &
+	local listener_pid=$!
+
+	# ADD_ADDR4 from server to client machine reusing the subflow port on
+	# the established v6 connection
+	:>"$client_evts"
+	ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\
+	   $server_addr_id dev ns1eth2 > /dev/null 2>&1
+	stdbuf -o0 -e0 printf "ADD_ADDR4 id:%d 10.0.2.1 (ns1) => ns2, reuse port\t\t" $server_addr_id
+	sleep 0.5
+	verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\
+			      "$server_addr_id" "$app6_port"
+
+	# CREATE_SUBFLOW from client to server machine
+	:>"$client_evts"
+	ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\
+	   $app6_port token "$client6_token" > /dev/null 2>&1
+	sleep 0.5
+	verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\
+			      "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\
+			      "$server_addr_id" "ns2" "ns1"
+
+	# Delete the listener from the server ns, if one was created
+	kill_wait $listener_pid
+
+	sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts")
+
+	# DESTROY_SUBFLOW from client to server machine
+	:>"$client_evts"
+	ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\
+	   $app6_port token "$client6_token" > /dev/null 2>&1
+	sleep 0.5
+	verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client6_token" \
+			      "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\
+			      "$server_addr_id" "ns2" "ns1"
+
+	# RM_ADDR from server to client machine
+	ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\
+	   "$server6_token" > /dev/null 2>&1
+	sleep 0.5
+}
+
 test_prio()
 {
 	local count
@@ -861,6 +907,7 @@ make_connection "v6"
 test_announce
 test_remove
 test_subflows
+test_subflows_v4_v6_mix
 test_prio
 test_listener
 

-- 
2.37.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family
  2023-01-12 17:42 [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family Matthieu Baerts
                   ` (2 preceding siblings ...)
  2023-01-12 17:42 ` [PATCH net 3/3] selftests: mptcp: userspace: validate v4-v6 subflows mix Matthieu Baerts
@ 2023-01-14  6:00 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-01-14  6:00 UTC (permalink / raw)
  To: Matthieu Baerts
  Cc: davem, edumazet, kuba, kishen.maloor, fw, shuah, netdev, mptcp,
	linux-kernel, linux-kselftest, pabeni, mathew.j.martineau, stable

Hello:

This series was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 12 Jan 2023 18:42:51 +0100 you wrote:
> Before these patches, the Userspace Path Manager would allow the
> creation of subflows with wrong families: taking the one of the MPTCP
> socket instead of the provided ones and resulting in the creation of
> subflows with likely not the right source and/or destination IPs. It
> would also allow the creation of subflows between different families or
> not respecting v4/v6-only socket attributes.
> 
> [...]

Here is the summary with links:
  - [net,1/3] mptcp: explicitly specify sock family at subflow creation time
    https://git.kernel.org/netdev/net/c/6bc1fe7dd748
  - [net,2/3] mptcp: netlink: respect v4/v6-only sockets
    https://git.kernel.org/netdev/net/c/fb00ee4f3343
  - [net,3/3] selftests: mptcp: userspace: validate v4-v6 subflows mix
    https://git.kernel.org/netdev/net/c/4656d72c1efa

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-01-14  6:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-12 17:42 [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family Matthieu Baerts
2023-01-12 17:42 ` [PATCH net 1/3] mptcp: explicitly specify sock family at subflow creation time Matthieu Baerts
2023-01-12 17:42 ` [PATCH net 2/3] mptcp: netlink: respect v4/v6-only sockets Matthieu Baerts
2023-01-12 17:42 ` [PATCH net 3/3] selftests: mptcp: userspace: validate v4-v6 subflows mix Matthieu Baerts
2023-01-14  6:00 ` [PATCH net 0/3] mptcp: userspace pm: create sockets for the right family patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).