All of lore.kernel.org
 help / color / mirror / Atom feed
* [MPTCP] [RFC 4/7] copy connection id from first subflow to mptcp socket
@ 2019-11-25  2:15 Florian Westphal
  0 siblings, 0 replies; only message in thread
From: Florian Westphal @ 2019-11-25  2:15 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 9462 bytes --]

This allows to call inet(6)_getname on the parent socket
and it will return the right result.

At this time it only works because the first incoming subflow has a
'struct socket' allocated.

This will change in followup patch, passive subflows will not have
a socket struct anymore.

Signed-off-by: Florian Westphal <fw(a)strlen.de>
---
 net/mptcp/pm.c       | 18 ++++----
 net/mptcp/protocol.c | 98 ++++++++++++++++++++++++--------------------
 net/mptcp/protocol.h |  1 -
 3 files changed, 63 insertions(+), 54 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 7e493d81afef..e474bd9dc05d 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -81,6 +81,7 @@ int mptcp_pm_create_subflow(u32 token, u8 remote_id, struct in_addr *addr)
 	struct mptcp_sock *msk = mptcp_token_get_sock(token);
 	struct sockaddr_in remote;
 	struct sockaddr_in local;
+	struct sock *sk;
 	int err;
 
 	if (!msk)
@@ -88,6 +89,7 @@ int mptcp_pm_create_subflow(u32 token, u8 remote_id, struct in_addr *addr)
 
 	pr_debug("msk=%p", msk);
 
+	sk = (struct sock *)msk;
 	if (!msk->pm.remote_valid || remote_id != msk->pm.remote_id) {
 		err = -EBADR;
 		goto create_put;
@@ -101,15 +103,14 @@ int mptcp_pm_create_subflow(u32 token, u8 remote_id, struct in_addr *addr)
 		local.sin_addr.s_addr = htonl(INADDR_ANY);
 
 	remote.sin_family = msk->pm.remote_family;
-	remote.sin_port = htons(msk->dport);
+	remote.sin_port = inet_sk(sk)->inet_dport;
 	remote.sin_addr = msk->pm.remote_addr;
 
-	err = mptcp_subflow_connect((struct sock *)msk,
-				    (struct sockaddr *)&local,
+	err = mptcp_subflow_connect(sk, (struct sockaddr *)&local,
 				    (struct sockaddr *)&remote, remote_id);
 
 create_put:
-	sock_put((struct sock *)msk);
+	sock_put(sk);
 	return err;
 }
 
@@ -119,12 +120,14 @@ int mptcp_pm_create_subflow6(u32 token, u8 remote_id, struct in6_addr *addr)
 	struct mptcp_sock *msk = mptcp_token_get_sock(token);
 	struct sockaddr_in6 remote;
 	struct sockaddr_in6 local;
+	struct sock *sk;
 	int err;
 
 	if (!msk)
 		return -EINVAL;
 
 	pr_debug("msk=%p", msk);
+	sk = (struct sock *)msk;
 
 	if (!msk->pm.remote_valid || remote_id != msk->pm.remote_id) {
 		err = -EBADR;
@@ -139,15 +142,14 @@ int mptcp_pm_create_subflow6(u32 token, u8 remote_id, struct in6_addr *addr)
 		local.sin6_addr = in6addr_any;
 
 	remote.sin6_family = msk->pm.remote_family;
-	remote.sin6_port = htons(msk->dport);
+	remote.sin6_port = inet_sk(sk)->inet_dport;
 	remote.sin6_addr = msk->pm.remote_addr6;
 
-	err = mptcp_subflow_connect((struct sock *)msk,
-				    (struct sockaddr *)&local,
+	err = mptcp_subflow_connect(sk, (struct sockaddr *)&local,
 				    (struct sockaddr *)&remote, remote_id);
 
 create_put:
-	sock_put((struct sock *)msk);
+	sock_put(sk);
 	return err;
 }
 #endif
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 72e6950fbbc2..720c0ab46cfb 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -91,19 +91,6 @@ static struct socket *mptcp_fallback_get_ref(const struct mptcp_sock *msk)
 	return ssock;
 }
 
-static struct sock *mptcp_subflow_get(const struct mptcp_sock *msk)
-{
-	struct mptcp_subflow_context *subflow;
-
-	sock_owned_by_me((const struct sock *)msk);
-
-	mptcp_for_each_subflow(msk, subflow) {
-		return mptcp_subflow_tcp_socket(subflow)->sk;
-	}
-
-	return NULL;
-}
-
 static struct sock *mptcp_subflow_recv_lookup(const struct mptcp_sock *msk)
 {
 	struct sock *sk = (struct sock *)msk;
@@ -934,6 +921,29 @@ static int mptcp_disconnect(struct sock *sk, int flags)
 	return tcp_disconnect(sk, flags);
 }
 
+static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
+{
+	const struct ipv6_pinfo *ssk6 = inet6_sk(ssk);
+	struct ipv6_pinfo *msk6 = inet6_sk(msk);
+
+	inet_sk(msk)->inet_num = inet_sk(ssk)->inet_num;
+	inet_sk(msk)->inet_dport = inet_sk(ssk)->inet_dport;
+	inet_sk(msk)->inet_sport = inet_sk(ssk)->inet_sport;
+	inet_sk(msk)->inet_daddr = inet_sk(ssk)->inet_daddr;
+	inet_sk(msk)->inet_saddr = inet_sk(ssk)->inet_saddr;
+	inet_sk(msk)->inet_rcv_saddr = inet_sk(ssk)->inet_rcv_saddr;
+
+#if IS_ENABLED(CONFIG_IPV6)
+	msk->sk_v6_daddr = ssk->sk_v6_daddr;
+	msk->sk_v6_rcv_saddr = ssk->sk_v6_rcv_saddr;
+
+	if (msk6 && ssk6) {
+		msk6->saddr = ssk6->saddr;
+		msk6->flow_label = ssk6->flow_label;
+	}
+#endif
+}
+
 static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 				 bool kern)
 {
@@ -954,6 +964,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 	pr_debug("msk=%p, new subflow=%p, ", msk, subflow);
 
 	if (subflow->mp_capable) {
+		struct sock *ssk = new_sock->sk;
 		struct sock *new_mptcp_sock;
 		u64 ack_seq;
 
@@ -988,6 +999,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 		ack_seq++;
 		msk->ack_seq = ack_seq;
 		newsk = new_mptcp_sock;
+		mptcp_copy_inaddrs(newsk, ssk);
 		list_add(&subflow->node, &msk->conn_list);
 		bh_unlock_sock(new_mptcp_sock);
 
@@ -999,7 +1011,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 		/* the subflow can already receive packet, avoid racing with
 		 * the receive path and process the pending ones
 		 */
-		lock_sock(new_sock->sk);
+		lock_sock(ssk);
 		subflow->map_seq = ack_seq;
 		subflow->map_subflow_seq = 1;
 		subflow->rel_write_seq = 1;
@@ -1007,7 +1019,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
 		subflow->conn = new_mptcp_sock;
 		if (unlikely(!skb_queue_empty(&new_sock->sk->sk_receive_queue)))
 			mptcp_subflow_data_available(new_sock->sk);
-		release_sock(new_sock->sk);
+		release_sock(ssk);
 	} else {
 		newsk = new_sock->sk;
 		tcp_sk(newsk)->is_mptcp = 0;
@@ -1122,6 +1134,7 @@ void mptcp_finish_connect(struct sock *sk, int mp_capable)
 	subflow = mptcp_subflow_ctx(msk->subflow->sk);
 
 	if (mp_capable) {
+		struct sock *ssk = msk->subflow->sk;
 		u64 ack_seq;
 
 		/* sk (new subflow socket) is already locked, but we need
@@ -1151,7 +1164,7 @@ void mptcp_finish_connect(struct sock *sk, int mp_capable)
 		msk->local_key = subflow->local_key;
 		msk->token = subflow->token;
 		pr_debug("msk=%p, token=%u", msk, msk->token);
-		msk->dport = ntohs(inet_sk(msk->subflow->sk)->inet_dport);
+		mptcp_copy_inaddrs(sk, ssk);
 
 		mptcp_pm_new_connection(msk, 0);
 
@@ -1300,43 +1313,44 @@ static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 }
 
 static int mptcp_getname(struct socket *sock, struct sockaddr *uaddr,
-			 int peer)
+			 int peer, int af)
 {
 	struct mptcp_sock *msk = mptcp_sk(sock->sk);
 	struct socket *ssock;
-	struct sock *ssk;
 	int ret;
 
-	lock_sock(sock->sk);
-	ssock = __mptcp_fallback_get_ref(msk);
-	if (ssock) {
+	if (msk->subflow) {
+		lock_sock(sock->sk);
+		ssock = __mptcp_fallback_get_ref(msk);
 		release_sock(sock->sk);
-		pr_debug("subflow=%p", ssock->sk);
-		ret = ssock->ops->getname(ssock, uaddr, peer);
-		sock_put(ssock->sk);
-		return ret;
+		if (ssock) {
+			pr_debug("subflow=%p", ssock->sk);
+			ret = ssock->ops->getname(ssock, uaddr, peer);
+			sock_put(ssock->sk);
+			return ret;
+		}
 	}
 
-	/* @@ the meaning of getname() for the remote peer when the socket
-	 * is connected and there are multiple subflows is not defined.
-	 * For now just use the first subflow on the list.
-	 */
-	ssk = mptcp_subflow_get(msk);
-	if (!ssk) {
-		release_sock(sock->sk);
-		return -ENOTCONN;
+	switch (af) {
+	case AF_INET:
+		ret = inet_getname(sock, uaddr, peer);
+		break;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	case AF_INET6:
+		ret = inet6_getname(sock, uaddr, peer);
+		break;
+#endif
+	default:
+		ret = -ENOPROTOOPT;
+		WARN_ON_ONCE(1);
 	}
 
-	ret = ssk->sk_socket->ops->getname(ssk->sk_socket, uaddr, peer);
-	release_sock(sock->sk);
 	return ret;
 }
 
 static int mptcp_v4_getname(struct socket *sock, struct sockaddr *uaddr,
 			    int peer)
 {
-	int ret;
-
 	if (sock->sk->sk_prot == &tcp_prot) {
 		/* we are being invoked from __sys_accept4, after
 		 * mptcp_accept() has just accepted a non-mp-capable
@@ -1349,17 +1363,13 @@ static int mptcp_v4_getname(struct socket *sock, struct sockaddr *uaddr,
 		return sock->ops->getname(sock, uaddr, peer);
 	}
 
-	ret = mptcp_getname(sock, uaddr, peer);
-
-	return ret;
+	return mptcp_getname(sock, uaddr, peer, AF_INET);
 }
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
 static int mptcp_v6_getname(struct socket *sock, struct sockaddr *uaddr,
 			    int peer)
 {
-	int ret;
-
 	if (sock->sk->sk_prot == &tcpv6_prot) {
 		/* we are being invoked from __sys_accept4 after
 		 * mptcp_accept() has accepted a non-mp-capable
@@ -1372,9 +1382,7 @@ static int mptcp_v6_getname(struct socket *sock, struct sockaddr *uaddr,
 		return sock->ops->getname(sock, uaddr, peer);
 	}
 
-	ret = mptcp_getname(sock, uaddr, peer);
-
-	return ret;
+	return mptcp_getname(sock, uaddr, peer, AF_INET6);
 }
 #endif
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index acad61c70de9..237c5efd0ba7 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -134,7 +134,6 @@ struct mptcp_sock {
 	unsigned long	timer_ival;
 	u32		token;
 	unsigned long	flags;
-	u16		dport;
 	struct work_struct rtx_work;
 	struct list_head conn_list;
 	struct list_head rtx_queue;
-- 
2.23.0

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-11-25  2:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-25  2:15 [MPTCP] [RFC 4/7] copy connection id from first subflow to mptcp socket Florian Westphal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.