Commit 6bc1fe7d authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski

mptcp: explicitly specify sock family at subflow creation time

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: 702c2f64 ("mptcp: netlink: allow userspace-driven subflow establishment")
Cc: stable@vger.kernel.org
Co-developed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 925f3deb
...@@ -98,7 +98,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) ...@@ -98,7 +98,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
struct socket *ssock; struct socket *ssock;
int err; int err;
err = mptcp_subflow_create_socket(sk, &ssock); err = mptcp_subflow_create_socket(sk, sk->sk_family, &ssock);
if (err) if (err)
return err; return err;
......
...@@ -641,7 +641,8 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a, ...@@ -641,7 +641,8 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
/* called with sk socket lock held */ /* called with sk socket lock held */
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
const struct mptcp_addr_info *remote); 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, void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
struct sockaddr_storage *addr, struct sockaddr_storage *addr,
unsigned short family); unsigned short family);
......
...@@ -1547,7 +1547,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, ...@@ -1547,7 +1547,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
if (!mptcp_is_fully_established(sk)) if (!mptcp_is_fully_established(sk))
goto err_out; goto err_out;
err = mptcp_subflow_create_socket(sk, &sf); err = mptcp_subflow_create_socket(sk, loc->family, &sf);
if (err) if (err)
goto err_out; goto err_out;
...@@ -1660,7 +1660,9 @@ static void mptcp_subflow_ops_undo_override(struct sock *ssk) ...@@ -1660,7 +1660,9 @@ static void mptcp_subflow_ops_undo_override(struct sock *ssk)
#endif #endif
ssk->sk_prot = &tcp_prot; 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 mptcp_subflow_context *subflow;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
...@@ -1673,8 +1675,7 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) ...@@ -1673,8 +1675,7 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
if (unlikely(!sk->sk_socket)) if (unlikely(!sk->sk_socket))
return -EINVAL; return -EINVAL;
err = sock_create_kern(net, sk->sk_family, SOCK_STREAM, IPPROTO_TCP, err = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP, &sf);
&sf);
if (err) if (err)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment