[PATCH mptcp-next v14 06/25] mptcp: dump addrs in userspace pm list

Geliang Tang posted 25 patches 2 years, 2 months ago
[PATCH mptcp-next v14 06/25] mptcp: dump addrs in userspace pm list
Posted by Geliang Tang 2 years, 2 months ago
This patch adds a new function __userspace_pm_lookup_addr_by_id() to lookup
the address entry by the given id in the userspace local addresses list.
Invoke it when dumping addresses from netlink commands.

Signed-off-by: Geliang Tang <geliang.tang@linux.dev>
---
 net/mptcp/pm_netlink.c   |  9 +++++++--
 net/mptcp/pm_userspace.c | 25 +++++++++++++++++++++++++
 net/mptcp/protocol.h     |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 1c85d711a86e..489a7723efc4 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1676,8 +1676,13 @@ int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
 		if (test_bit(i, pernet->id_bitmap)) {
 			entry = __lookup_addr_by_id(pernet, i);
-			if (!entry)
-				break;
+			if (!entry) {
+				spin_unlock_bh(&pernet->lock);
+				entry = __userspace_pm_lookup_addr_by_id(net, i);
+				spin_lock_bh(&pernet->lock);
+				if (!entry)
+					break;
+			}
 
 			if (entry->addr.id <= id)
 				continue;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 6999296cd5db..5e45e36ce1d3 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -549,3 +549,28 @@ int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
 	sock_put(sk);
 	return ret;
 }
+
+struct mptcp_pm_addr_entry *
+__userspace_pm_lookup_addr_by_id(struct net *net, unsigned int id)
+{
+	struct mptcp_pm_addr_entry *entry = NULL;
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+
+		if (mptcp_pm_is_userspace(msk)) {
+			lock_sock(sk);
+			spin_lock_bh(&msk->pm.lock);
+			entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+			spin_unlock_bh(&msk->pm.lock);
+			release_sock(sk);
+		}
+
+		sock_put(sk);
+		cond_resched();
+	}
+
+	return entry;
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8296bdf58f90..3ab4a4f1bf81 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1025,6 +1025,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+struct mptcp_pm_addr_entry *
+__userspace_pm_lookup_addr_by_id(struct net *net, unsigned int id);
 
 void __init mptcp_pm_nl_init(void);
 void mptcp_pm_nl_work(struct mptcp_sock *msk);
-- 
2.35.3
Re: [PATCH mptcp-next v14 06/25] mptcp: dump addrs in userspace pm list
Posted by Mat Martineau 2 years, 2 months ago
On Fri, 8 Dec 2023, Geliang Tang wrote:

> This patch adds a new function __userspace_pm_lookup_addr_by_id() to lookup
> the address entry by the given id in the userspace local addresses list.
> Invoke it when dumping addresses from netlink commands.
>

Hi Geliang -

The existing per-net dump command won't work for the userspace PM, since 
each connection can have separate local address lists. So, the get-addr 
dump command needs an optional 'token' parameter that will dump the local 
addr list for one userspace PM connection.

- Mat

> Signed-off-by: Geliang Tang <geliang.tang@linux.dev>
> ---
> net/mptcp/pm_netlink.c   |  9 +++++++--
> net/mptcp/pm_userspace.c | 25 +++++++++++++++++++++++++
> net/mptcp/protocol.h     |  2 ++
> 3 files changed, 34 insertions(+), 2 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 1c85d711a86e..489a7723efc4 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1676,8 +1676,13 @@ int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
> 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
> 		if (test_bit(i, pernet->id_bitmap)) {
> 			entry = __lookup_addr_by_id(pernet, i);
> -			if (!entry)
> -				break;
> +			if (!entry) {
> +				spin_unlock_bh(&pernet->lock);
> +				entry = __userspace_pm_lookup_addr_by_id(net, i);
> +				spin_lock_bh(&pernet->lock);
> +				if (!entry)
> +					break;
> +			}
>
> 			if (entry->addr.id <= id)
> 				continue;
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 6999296cd5db..5e45e36ce1d3 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -549,3 +549,28 @@ int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
> 	sock_put(sk);
> 	return ret;
> }
> +
> +struct mptcp_pm_addr_entry *
> +__userspace_pm_lookup_addr_by_id(struct net *net, unsigned int id)
> +{
> +	struct mptcp_pm_addr_entry *entry = NULL;
> +	long s_slot = 0, s_num = 0;
> +	struct mptcp_sock *msk;
> +
> +	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
> +		struct sock *sk = (struct sock *)msk;
> +
> +		if (mptcp_pm_is_userspace(msk)) {
> +			lock_sock(sk);
> +			spin_lock_bh(&msk->pm.lock);
> +			entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
> +			spin_unlock_bh(&msk->pm.lock);
> +			release_sock(sk);
> +		}
> +
> +		sock_put(sk);
> +		cond_resched();
> +	}
> +
> +	return entry;
> +}
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 8296bdf58f90..3ab4a4f1bf81 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -1025,6 +1025,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
> int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
> +struct mptcp_pm_addr_entry *
> +__userspace_pm_lookup_addr_by_id(struct net *net, unsigned int id);
>
> void __init mptcp_pm_nl_init(void);
> void mptcp_pm_nl_work(struct mptcp_sock *msk);
> -- 
> 2.35.3
>
>
>