mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange
@ 2022-07-01 10:05 Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting Paolo Abeni
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

This series introduces the ability to control the MPC subflow for
the in kernel PM.

Patch 1 and 5 are actually a related bugfixes.

patch 2 && 3 refactor a bit the endpoint lookup and MP_PRIO generation
code, to simplify the next patch.

patch 4 introduces the new feature quering the backup status of the
endpoint used by the MPC subflow and eventually generating the needed
MP_PRIO option.

changes vs RFC:
 - rebased on top of Mats' patches
 - added patch 3/6 clarifying the endpoint id lookup semanthic
 - added self-tests (patch 6/6)

Paolo Abeni (6):
  mptcp: fix local endpoint acconting.
  mptcp: introduce and use mptcp_pm_send_ack()
  mptcp: address lookup improvements
  mptcp: allow the in kernel PM to set MPC subflow priority
  mptcp: more accurate MPC endpoint tracking
  selftests: mptcp: add MPC backup tests

 net/mptcp/pm_netlink.c                        | 129 ++++++++++--------
 net/mptcp/protocol.c                          |   2 +-
 net/mptcp/protocol.h                          |   2 +-
 .../testing/selftests/net/mptcp/mptcp_join.sh |  30 ++++
 4 files changed, 105 insertions(+), 58 deletions(-)

-- 
2.35.3


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

* [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting.
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  2022-07-02  0:04   ` Mat Martineau
  2022-07-01 10:05 ` [PATCH mptcp-next 2/6] mptcp: introduce and use mptcp_pm_send_ack() Paolo Abeni
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

In mptcp_pm_nl_rm_addr_or_subflow() we always mark as availble
the id corresponding to the just removed address.

The used bitmap actually tracks only the local IDs: we must
restrict the operation when a (local) subflow is removed.

Fixes: a88c9e496937 ("mptcp: do not block subflows creation on errors")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/mptcp/pm_netlink.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 0a295acf99b8..f1909006a859 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -800,7 +800,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 			removed = true;
 			__MPTCP_INC_STATS(sock_net(sk), rm_type);
 		}
-		__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
+		if (rm_type == MPTCP_MIB_RMSUBFLOW)
+			__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
 		if (!removed)
 			continue;
 
-- 
2.35.3


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

* [PATCH mptcp-next 2/6]  mptcp: introduce and use mptcp_pm_send_ack()
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  2022-07-02  0:13   ` Mat Martineau
  2022-07-01 10:05 ` [PATCH mptcp-next 3/6] mptcp: address lookup improvements Paolo Abeni
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

The in-kernel PM has a bit of duplicate code related to ack
generation. Create a new helper factoring out the PM-specific
needs and use it in a couple of places.

As a bonus, mptcp_subflow_send_ack() is not used anymore
outside its own compilation unit and can become static.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/mptcp/pm_netlink.c | 56 +++++++++++++++++++++++++-----------------
 net/mptcp/protocol.c   |  2 +-
 net/mptcp/protocol.h   |  1 -
 3 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index f1909006a859..8dc7ff9953b9 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -463,6 +463,37 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
 	return i;
 }
 
+static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+			        bool prio, bool backup)
+{
+	struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+	bool slow;
+
+	pr_debug("send ack for %s",
+		 prio ? "mp_prio" : (mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr"));
+
+	slow = lock_sock_fast(ssk);
+	if (prio) {
+		if (subflow->backup != backup)
+			msk->last_snd = NULL;
+
+		subflow->send_mp_prio = 1;
+		subflow->backup = backup;
+		subflow->request_bkup = backup;
+	}
+
+	__mptcp_subflow_send_ack(ssk);
+	unlock_sock_fast(ssk, slow);
+}
+
+static void mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+			      bool prio, bool backup)
+{
+	spin_unlock_bh(&msk->pm.lock);
+	__mptcp_pm_send_ack(msk, subflow, prio, backup);
+	spin_lock_bh(&msk->pm.lock);
+}
+
 static struct mptcp_pm_addr_entry *
 __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
 {
@@ -705,16 +736,8 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
 		return;
 
 	subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
-	if (subflow) {
-		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-
-		spin_unlock_bh(&msk->pm.lock);
-		pr_debug("send ack for %s",
-			 mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr");
-
-		mptcp_subflow_send_ack(ssk);
-		spin_lock_bh(&msk->pm.lock);
-	}
+	if (subflow)
+		mptcp_pm_send_ack(msk, subflow, false, false);
 }
 
 static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
@@ -728,23 +751,12 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
 	mptcp_for_each_subflow(msk, subflow) {
 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 		struct mptcp_addr_info local;
-		bool slow;
 
 		local_address((struct sock_common *)ssk, &local);
 		if (!mptcp_addresses_equal(&local, addr, addr->port))
 			continue;
 
-		slow = lock_sock_fast(ssk);
-		if (subflow->backup != bkup)
-			msk->last_snd = NULL;
-		subflow->backup = bkup;
-		subflow->send_mp_prio = 1;
-		subflow->request_bkup = bkup;
-
-		pr_debug("send ack for mp_prio");
-		__mptcp_subflow_send_ack(ssk);
-		unlock_sock_fast(ssk, slow);
-
+		__mptcp_pm_send_ack(msk, subflow, true, bkup);
 		return 0;
 	}
 
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 10bfa2b78206..874344f7e0fa 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -508,7 +508,7 @@ void __mptcp_subflow_send_ack(struct sock *ssk)
 		tcp_send_ack(ssk);
 }
 
-void mptcp_subflow_send_ack(struct sock *ssk)
+static void mptcp_subflow_send_ack(struct sock *ssk)
 {
 	bool slow;
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 9a7ec7773e8c..a92b6276a03c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -610,7 +610,6 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
 void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		     struct mptcp_subflow_context *subflow);
 void __mptcp_subflow_send_ack(struct sock *ssk);
-void mptcp_subflow_send_ack(struct sock *ssk);
 void mptcp_subflow_reset(struct sock *ssk);
 void mptcp_subflow_queue_clean(struct sock *ssk);
 void mptcp_sock_graft(struct sock *sk, struct socket *parent);
-- 
2.35.3


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

* [PATCH mptcp-next 3/6] mptcp: address lookup improvements
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 2/6] mptcp: introduce and use mptcp_pm_send_ack() Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 4/6] mptcp: allow the in kernel PM to set MPC subflow priority Paolo Abeni
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

When looking-up a socket address in the endpoint list, we
must prefer port-based matches over address only match.

Ensure that port-based endpoints are listed first, using
head insertion for them. Additionally be sure that only
port-based endpoints carry a non zero port number.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/mptcp/pm_netlink.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 8dc7ff9953b9..d6180b34a2c9 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -413,7 +413,7 @@ static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned
 	int i;
 
 	for (i = 0; i < nr; i++) {
-		if (mptcp_addresses_equal(&addrs[i], addr, addr->port))
+		if (addrs[i].id == addr->id)
 			return true;
 	}
 
@@ -449,7 +449,8 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
 		mptcp_for_each_subflow(msk, subflow) {
 			ssk = mptcp_subflow_tcp_sock(subflow);
 			remote_address((struct sock_common *)ssk, &addrs[i]);
-			if (deny_id0 && mptcp_addresses_equal(&addrs[i], &remote, false))
+			addrs[i].id = subflow->remote_id;
+			if (deny_id0 && !addrs[i].id)
 				continue;
 
 			if (!lookup_address_in_vec(addrs, i, &addrs[i]) &&
@@ -912,10 +913,11 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 	/* do not insert duplicate address, differentiate on port only
 	 * singled addresses
 	 */
+	if (!address_use_port(entry))
+		entry->addr.port = 0;
 	list_for_each_entry(cur, &pernet->local_addr_list, list) {
 		if (mptcp_addresses_equal(&cur->addr, &entry->addr,
-					  address_use_port(entry) &&
-					  address_use_port(cur))) {
+					  cur->addr.port || entry->addr.port)) {
 			/* allow replacing the exiting endpoint only if such
 			 * endpoint is an implicit one and the user-space
 			 * did not provide an endpoint id
@@ -961,7 +963,10 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 	}
 
 	pernet->addrs++;
-	list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
+	if (!entry->addr.port)
+		list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
+	else
+		list_add_rcu(&entry->list, &pernet->local_addr_list);
 	ret = entry->addr.id;
 
 out:
-- 
2.35.3


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

* [PATCH mptcp-next 4/6] mptcp: allow the in kernel PM to set MPC subflow priority
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
                   ` (2 preceding siblings ...)
  2022-07-01 10:05 ` [PATCH mptcp-next 3/6] mptcp: address lookup improvements Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 5/6] mptcp: more accurate MPC endpoint tracking Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 6/6] selftests: mptcp: add MPC backup tests Paolo Abeni
  5 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

Any local endpoints configured on the address matching the
MPC subflow are currently ignored.

Specifically, setting a backup flag on them has no effect
on the first subflow, as the MPC handshake can't carry such
info.

This change refactors the MPC endpoint id accounting to
additionally fetch the priority info from the relevant endpoint
and eventually trigger the MP_PRIO handshake as needed.

As a result, the MPC subflow now switches to backup priority
after that the MPTCP socket is fully established, according
to the local endpoint configuration.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/mptcp/pm_netlink.c | 37 +++++++++++++++----------------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index d6180b34a2c9..46950ccac07d 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -514,30 +514,14 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info,
 	struct mptcp_pm_addr_entry *entry;
 
 	list_for_each_entry(entry, &pernet->local_addr_list, list) {
-		if ((!lookup_by_id && mptcp_addresses_equal(&entry->addr, info, true)) ||
+		if ((!lookup_by_id &&
+		     mptcp_addresses_equal(&entry->addr, info, entry->addr.port)) ||
 		    (lookup_by_id && entry->addr.id == info->id))
 			return entry;
 	}
 	return NULL;
 }
 
-static int
-lookup_id_by_addr(const struct pm_nl_pernet *pernet, const struct mptcp_addr_info *addr)
-{
-	const struct mptcp_pm_addr_entry *entry;
-	int ret = -1;
-
-	rcu_read_lock();
-	list_for_each_entry(entry, &pernet->local_addr_list, list) {
-		if (mptcp_addresses_equal(&entry->addr, addr, entry->addr.port)) {
-			ret = entry->addr.id;
-			break;
-		}
-	}
-	rcu_read_unlock();
-	return ret;
-}
-
 static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 {
 	struct sock *sk = (struct sock *)msk;
@@ -555,13 +539,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 
 	/* do lazy endpoint usage accounting for the MPC subflows */
 	if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) {
+		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(msk->first);
+		struct mptcp_pm_addr_entry *entry;
 		struct mptcp_addr_info mpc_addr;
-		int mpc_id;
+		bool backup = false;
 
 		local_address((struct sock_common *)msk->first, &mpc_addr);
-		mpc_id = lookup_id_by_addr(pernet, &mpc_addr);
-		if (mpc_id >= 0)
-			__clear_bit(mpc_id, msk->pm.id_avail_bitmap);
+		rcu_read_lock();
+		entry = __lookup_addr(pernet, &mpc_addr, false);
+		if (entry) {
+			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
+			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+		}
+		rcu_read_unlock();
+
+		if (backup)
+			mptcp_pm_send_ack(msk, subflow, true, backup);
 
 		msk->pm.status |= BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED);
 	}
-- 
2.35.3


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

* [PATCH mptcp-next 5/6] mptcp: more accurate MPC endpoint tracking
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
                   ` (3 preceding siblings ...)
  2022-07-01 10:05 ` [PATCH mptcp-next 4/6] mptcp: allow the in kernel PM to set MPC subflow priority Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  2022-07-01 10:05 ` [PATCH mptcp-next 6/6] selftests: mptcp: add MPC backup tests Paolo Abeni
  5 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

Currently the id accounting for the ID 0 subflow is not correct:
at creation time we mark (correctly) as unavailable the endpoint
id corresponding the MPC subflow source address, while at subflow
removal time set as available the id 0.

With this change we track explicitly the endpoint id corresponding
to the MPC subflow so that we can mark it as available at removal time.
Additionally this allow deleting the initial subflow via the NL PM
specifying the corresponding endpoint id.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/mptcp/pm_netlink.c | 20 +++++++++++++-------
 net/mptcp/protocol.h   |  1 +
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 46950ccac07d..d3001484f0d6 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -549,6 +549,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 		entry = __lookup_addr(pernet, &mpc_addr, false);
 		if (entry) {
 			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
+			msk->mpc_endpoint_id = entry->addr.id;
 			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 		}
 		rcu_read_unlock();
@@ -757,6 +758,11 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
 	return -EINVAL;
 }
 
+static bool mptcp_local_id_match(const struct mptcp_sock *msk, u8 local_id, u8 id)
+{
+	return local_id == id || (!local_id && msk->mpc_endpoint_id == id);
+}
+
 static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 					   const struct mptcp_rm_list *rm_list,
 					   enum linux_mptcp_mib_field rm_type)
@@ -780,6 +786,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 		return;
 
 	for (i = 0; i < rm_list->nr; i++) {
+		u8 rm_id = rm_list->ids[i];
 		bool removed = false;
 
 		list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
@@ -787,15 +794,14 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 			int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
 			u8 id = subflow->local_id;
 
-			if (rm_type == MPTCP_MIB_RMADDR)
-				id = subflow->remote_id;
-
-			if (rm_list->ids[i] != id)
+			if (rm_type == MPTCP_MIB_RMADDR && subflow->remote_id != rm_id)
+				continue;
+			if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id))
 				continue;
 
-			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u",
+			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u",
 				 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
-				 i, rm_list->ids[i], subflow->local_id, subflow->remote_id);
+				 i, rm_id, subflow->local_id, subflow->remote_id, msk->mpc_endpoint_id);
 			spin_unlock_bh(&msk->pm.lock);
 			mptcp_subflow_shutdown(sk, ssk, how);
 
@@ -807,7 +813,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
 			__MPTCP_INC_STATS(sock_net(sk), rm_type);
 		}
 		if (rm_type == MPTCP_MIB_RMSUBFLOW)
-			__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
+			__set_bit(rm_id ? rm_id : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap);
 		if (!removed)
 			continue;
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index a92b6276a03c..ec91776f9b18 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -282,6 +282,7 @@ struct mptcp_sock {
 	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
 	bool		csum_enabled;
 	bool		allow_infinite_fallback;
+	u8		mpc_endpoint_id;
 	u8		recvmsg_inq:1,
 			cork:1,
 			nodelay:1;
-- 
2.35.3


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

* [PATCH mptcp-next 6/6] selftests: mptcp: add MPC backup tests
  2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
                   ` (4 preceding siblings ...)
  2022-07-01 10:05 ` [PATCH mptcp-next 5/6] mptcp: more accurate MPC endpoint tracking Paolo Abeni
@ 2022-07-01 10:05 ` Paolo Abeni
  5 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-01 10:05 UTC (permalink / raw)
  To: mptcp

Add a couple of test-cases covering the newly introduced
features - priority update for the MPC subflow.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 .../testing/selftests/net/mptcp/mptcp_join.sh | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 55efe2aafb84..ff83ef426df5 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -2428,6 +2428,36 @@ backup_tests()
 		chk_add_nr 1 1
 		chk_prio_nr 1 1
 	fi
+
+	if reset "mpc backup"; then
+		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
+		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+		chk_join_nr 0 0 0
+		chk_prio_nr 0 1
+	fi
+
+	if reset "mpc backup both sides"; then
+		pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow,backup
+		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
+		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+		chk_join_nr 0 0 0
+		chk_prio_nr 1 1
+	fi
+
+	if reset "mpc switch to backup"; then
+		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
+		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
+		chk_join_nr 0 0 0
+		chk_prio_nr 0 1
+	fi
+
+	if reset "mpc switch to backup both sides"; then
+		pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow
+		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
+		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
+		chk_join_nr 0 0 0
+		chk_prio_nr 1 1
+	fi
 }
 
 add_addr_ports_tests()
-- 
2.35.3


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

* Re: [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting.
  2022-07-01 10:05 ` [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting Paolo Abeni
@ 2022-07-02  0:04   ` Mat Martineau
  2022-07-04  8:02     ` Paolo Abeni
  0 siblings, 1 reply; 12+ messages in thread
From: Mat Martineau @ 2022-07-02  0:04 UTC (permalink / raw)
  To: Paolo Abeni; +Cc: mptcp

On Fri, 1 Jul 2022, Paolo Abeni wrote:

> In mptcp_pm_nl_rm_addr_or_subflow() we always mark as availble
> the id corresponding to the just removed address.
>
> The used bitmap actually tracks only the local IDs: we must
> restrict the operation when a (local) subflow is removed.
>
> Fixes: a88c9e496937 ("mptcp: do not block subflows creation on errors")
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>

Looks good to me. Ok to apply this one to the net branch, separate from 
the rest of the series?


For this single patch:
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>

> ---
> net/mptcp/pm_netlink.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 0a295acf99b8..f1909006a859 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -800,7 +800,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
> 			removed = true;
> 			__MPTCP_INC_STATS(sock_net(sk), rm_type);
> 		}
> -		__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
> +		if (rm_type == MPTCP_MIB_RMSUBFLOW)
> +			__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
> 		if (!removed)
> 			continue;
>
> -- 
> 2.35.3
>
>
>

--
Mat Martineau
Intel

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

* Re: [PATCH mptcp-next 2/6]  mptcp: introduce and use mptcp_pm_send_ack()
  2022-07-01 10:05 ` [PATCH mptcp-next 2/6] mptcp: introduce and use mptcp_pm_send_ack() Paolo Abeni
@ 2022-07-02  0:13   ` Mat Martineau
  2022-07-04  8:06     ` Paolo Abeni
  0 siblings, 1 reply; 12+ messages in thread
From: Mat Martineau @ 2022-07-02  0:13 UTC (permalink / raw)
  To: Paolo Abeni; +Cc: mptcp

On Fri, 1 Jul 2022, Paolo Abeni wrote:

> The in-kernel PM has a bit of duplicate code related to ack
> generation. Create a new helper factoring out the PM-specific
> needs and use it in a couple of places.
>
> As a bonus, mptcp_subflow_send_ack() is not used anymore
> outside its own compilation unit and can become static.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>

The rest of the series looks good, I ran the new tests and checked the 
pcaps too.

However, there's a conflict in this patch with the export branch. Can you 
rebase and repost?


Something else I noticed that is out of scope for this series, but 
something we should think about addressing:

The RFC says about MP_PRIO that "this signal applies to a single 
direction, and so the sender of this option could choose to continue using 
the subflow to send data even if it has signaled B=1 to the other host.".

However, we only have a single 'backup' value stored per subflow. If 
there's a netlink request to change the backup bit, it affects both 
outgoing scheduling and sends MP_PRIO to the peer to affect incoming 
traffic. A received MP_PRIO would affect outgoing packet scheduling on 
that subflow, but the peer may choose to schedule differently (and we do 
handle this ok). Would it be worth it to separate "incoming priority" and 
"outgoing priority"?

- Mat


> ---
> net/mptcp/pm_netlink.c | 56 +++++++++++++++++++++++++-----------------
> net/mptcp/protocol.c   |  2 +-
> net/mptcp/protocol.h   |  1 -
> 3 files changed, 35 insertions(+), 24 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index f1909006a859..8dc7ff9953b9 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -463,6 +463,37 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
> 	return i;
> }
>
> +static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
> +			        bool prio, bool backup)
> +{
> +	struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> +	bool slow;
> +
> +	pr_debug("send ack for %s",
> +		 prio ? "mp_prio" : (mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr"));
> +
> +	slow = lock_sock_fast(ssk);
> +	if (prio) {
> +		if (subflow->backup != backup)
> +			msk->last_snd = NULL;
> +
> +		subflow->send_mp_prio = 1;
> +		subflow->backup = backup;
> +		subflow->request_bkup = backup;
> +	}
> +
> +	__mptcp_subflow_send_ack(ssk);
> +	unlock_sock_fast(ssk, slow);
> +}
> +
> +static void mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
> +			      bool prio, bool backup)
> +{
> +	spin_unlock_bh(&msk->pm.lock);
> +	__mptcp_pm_send_ack(msk, subflow, prio, backup);
> +	spin_lock_bh(&msk->pm.lock);
> +}
> +
> static struct mptcp_pm_addr_entry *
> __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
> {
> @@ -705,16 +736,8 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
> 		return;
>
> 	subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
> -	if (subflow) {
> -		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> -
> -		spin_unlock_bh(&msk->pm.lock);
> -		pr_debug("send ack for %s",
> -			 mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr");
> -
> -		mptcp_subflow_send_ack(ssk);
> -		spin_lock_bh(&msk->pm.lock);
> -	}
> +	if (subflow)
> +		mptcp_pm_send_ack(msk, subflow, false, false);
> }
>
> static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> @@ -728,23 +751,12 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> 	mptcp_for_each_subflow(msk, subflow) {
> 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> 		struct mptcp_addr_info local;
> -		bool slow;
>
> 		local_address((struct sock_common *)ssk, &local);
> 		if (!mptcp_addresses_equal(&local, addr, addr->port))
> 			continue;
>
> -		slow = lock_sock_fast(ssk);
> -		if (subflow->backup != bkup)
> -			msk->last_snd = NULL;
> -		subflow->backup = bkup;
> -		subflow->send_mp_prio = 1;
> -		subflow->request_bkup = bkup;
> -
> -		pr_debug("send ack for mp_prio");
> -		__mptcp_subflow_send_ack(ssk);
> -		unlock_sock_fast(ssk, slow);
> -
> +		__mptcp_pm_send_ack(msk, subflow, true, bkup);
> 		return 0;
> 	}
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 10bfa2b78206..874344f7e0fa 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -508,7 +508,7 @@ void __mptcp_subflow_send_ack(struct sock *ssk)
> 		tcp_send_ack(ssk);
> }
>
> -void mptcp_subflow_send_ack(struct sock *ssk)
> +static void mptcp_subflow_send_ack(struct sock *ssk)
> {
> 	bool slow;
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 9a7ec7773e8c..a92b6276a03c 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -610,7 +610,6 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
> void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
> 		     struct mptcp_subflow_context *subflow);
> void __mptcp_subflow_send_ack(struct sock *ssk);
> -void mptcp_subflow_send_ack(struct sock *ssk);
> void mptcp_subflow_reset(struct sock *ssk);
> void mptcp_subflow_queue_clean(struct sock *ssk);
> void mptcp_sock_graft(struct sock *sk, struct socket *parent);
> -- 
> 2.35.3
>
>
>

--
Mat Martineau
Intel

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

* Re: [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting.
  2022-07-02  0:04   ` Mat Martineau
@ 2022-07-04  8:02     ` Paolo Abeni
  2022-07-04 16:09       ` Matthieu Baerts
  0 siblings, 1 reply; 12+ messages in thread
From: Paolo Abeni @ 2022-07-04  8:02 UTC (permalink / raw)
  To: Mat Martineau; +Cc: mptcp

On Fri, 2022-07-01 at 17:04 -0700, Mat Martineau wrote:
> On Fri, 1 Jul 2022, Paolo Abeni wrote:
> 
> > In mptcp_pm_nl_rm_addr_or_subflow() we always mark as availble
> > the id corresponding to the just removed address.
> > 
> > The used bitmap actually tracks only the local IDs: we must
> > restrict the operation when a (local) subflow is removed.
> > 
> > Fixes: a88c9e496937 ("mptcp: do not block subflows creation on errors")
> > Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> 
> Looks good to me. Ok to apply this one to the net branch, separate from 
> the rest of the series?

Works for me, thanks!

Paolo


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

* Re: [PATCH mptcp-next 2/6]  mptcp: introduce and use mptcp_pm_send_ack()
  2022-07-02  0:13   ` Mat Martineau
@ 2022-07-04  8:06     ` Paolo Abeni
  0 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2022-07-04  8:06 UTC (permalink / raw)
  To: Mat Martineau; +Cc: mptcp

On Fri, 2022-07-01 at 17:13 -0700, Mat Martineau wrote:
> On Fri, 1 Jul 2022, Paolo Abeni wrote:
> 
> > The in-kernel PM has a bit of duplicate code related to ack
> > generation. Create a new helper factoring out the PM-specific
> > needs and use it in a couple of places.
> > 
> > As a bonus, mptcp_subflow_send_ack() is not used anymore
> > outside its own compilation unit and can become static.
> > 
> > Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> 
> The rest of the series looks good, I ran the new tests and checked the 
> pcaps too.
> 
> However, there's a conflict in this patch with the export branch. Can you 
> rebase and repost?

I'm surprised by the conflict. I likely messed-up something in my tree.
I'll rebase.

> Something else I noticed that is out of scope for this series, but 
> something we should think about addressing:
> 
> The RFC says about MP_PRIO that "this signal applies to a single 
> direction, and so the sender of this option could choose to continue using 
> the subflow to send data even if it has signaled B=1 to the other host.".
> 
> However, we only have a single 'backup' value stored per subflow. If 
> there's a netlink request to change the backup bit, it affects both 
> outgoing scheduling and sends MP_PRIO to the peer to affect incoming 
> traffic. A received MP_PRIO would affect outgoing packet scheduling on 
> that subflow, but the peer may choose to schedule differently (and we do 
> handle this ok). Would it be worth it to separate "incoming priority" and 
> "outgoing priority"?

Indeed, that could be worthy. Note that we have a very similar issue
for fallback to TCP: according to the RFC is again an unidirectional
status, but we have a single bit info for both directions.

I guess the relevant changes (both for MP_PRIO and even more for
fallback could be a bit invasive, let's see...

Cheers,

Paolo


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

* Re: [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting.
  2022-07-04  8:02     ` Paolo Abeni
@ 2022-07-04 16:09       ` Matthieu Baerts
  0 siblings, 0 replies; 12+ messages in thread
From: Matthieu Baerts @ 2022-07-04 16:09 UTC (permalink / raw)
  To: Paolo Abeni, Mat Martineau; +Cc: mptcp

Hi Paolo, Mat,

On 04/07/2022 10:02, Paolo Abeni wrote:
> On Fri, 2022-07-01 at 17:04 -0700, Mat Martineau wrote:
>> On Fri, 1 Jul 2022, Paolo Abeni wrote:
>>
>>> In mptcp_pm_nl_rm_addr_or_subflow() we always mark as availble
>>> the id corresponding to the just removed address.
>>>
>>> The used bitmap actually tracks only the local IDs: we must
>>> restrict the operation when a (local) subflow is removed.
>>>
>>> Fixes: a88c9e496937 ("mptcp: do not block subflows creation on errors")
>>> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
>>
>> Looks good to me. Ok to apply this one to the net branch, separate from 
>> the rest of the series?
> 
> Works for me, thanks!

Thank you for the patch and the review!

This patch (and only this 1/6 patch) is now in our tree (fixes for -net)
with Mat's RvB tag and without some typos found by codespell
(./scripts/checkpatch.pl --codespell):

New patches for t/upstream-net:
- 700323697153: mptcp: fix local endpoint accounting
- Results: 8b0928bdfa52..9e57efad1e78 (export-net)

New patches for t/upstream:
- 700323697153: mptcp: fix local endpoint accounting
- Results: d9c4fd4f6874..d7694db70480 (export)


Builds and tests are now in progress:

https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export-net/20220704T160802
https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export-net
https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export/20220704T160802
https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

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

end of thread, other threads:[~2022-07-04 16:09 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-01 10:05 [PATCH mptcp-next 0/6] mptcp: support for MPC prio exchange Paolo Abeni
2022-07-01 10:05 ` [PATCH mptcp-next 1/6] mptcp: fix local endpoint acconting Paolo Abeni
2022-07-02  0:04   ` Mat Martineau
2022-07-04  8:02     ` Paolo Abeni
2022-07-04 16:09       ` Matthieu Baerts
2022-07-01 10:05 ` [PATCH mptcp-next 2/6] mptcp: introduce and use mptcp_pm_send_ack() Paolo Abeni
2022-07-02  0:13   ` Mat Martineau
2022-07-04  8:06     ` Paolo Abeni
2022-07-01 10:05 ` [PATCH mptcp-next 3/6] mptcp: address lookup improvements Paolo Abeni
2022-07-01 10:05 ` [PATCH mptcp-next 4/6] mptcp: allow the in kernel PM to set MPC subflow priority Paolo Abeni
2022-07-01 10:05 ` [PATCH mptcp-next 5/6] mptcp: more accurate MPC endpoint tracking Paolo Abeni
2022-07-01 10:05 ` [PATCH mptcp-next 6/6] selftests: mptcp: add MPC backup tests Paolo Abeni

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).