All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mptcp-next v2 00/36] BPF path manager
@ 2024-10-22  9:14 Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match Geliang Tang
                   ` (38 more replies)
  0 siblings, 39 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

v2:
 - add BPF-related code in this set (32-36).

In order to implement BPF userspace path manager, it is necessary to
unify the interfaces of the path manager. This set contains some
cleanups and refactoring to unify the interfaces in kernel space.
Finally, define a struct mptcp_pm_ops for a userspace path manager
like this:

struct mptcp_pm_ops {
        int (*address_announce)(struct mptcp_sock *msk,
                                struct mptcp_pm_addr_entry *local);
        int (*address_remove)(struct mptcp_sock *msk, u8 id);
        int (*subflow_create)(struct mptcp_sock *msk,
                              struct mptcp_pm_addr_entry *local,
                              struct mptcp_addr_info *remote);
        int (*subflow_destroy)(struct mptcp_sock *msk,
                               struct mptcp_pm_addr_entry *local,
                               struct mptcp_addr_info *remote);
        int (*get_local_id)(struct mptcp_sock *msk,
                            struct mptcp_pm_addr_entry *local);
        u8 (*get_flags)(struct mptcp_sock *msk,
                        struct mptcp_addr_info *skc);
        struct mptcp_pm_addr_entry *(*get_addr)(struct mptcp_sock *msk,
                                                u8 id);
        int (*dump_addr)(struct mptcp_sock *msk,
                         struct mptcp_id_bitmap *bitmap);
        int (*set_flags)(struct mptcp_sock *msk,
                         struct mptcp_pm_addr_entry *local,
                         struct mptcp_addr_info *remote);

        u8                      type;
        struct module           *owner;
        struct list_head        list;

        void (*init)(struct mptcp_sock *msk);
        void (*release)(struct mptcp_sock *msk);
} ____cacheline_aligned_in_smp;

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/74

Depends on:
 - "add mptcp_address bpf_iter" v2

Based-on: <cover.1729582332.git.tanggeliang@kylinos.cn>

Geliang Tang (36):
  mptcp: drop else in mptcp_pm_addr_families_match
  mptcp: use __lookup_addr in pm_netlink
  mptcp: add mptcp_for_each_address macros
  mptcp: use sock_kfree_s instead of kfree
  mptcp: add lookup_addr for userspace pm
  mptcp: add mptcp_userspace_pm_get_sock helper
  mptcp: make three pm wrappers static
  mptcp: drop skb parameter of get_addr
  mptcp: add id parameter for get_addr
  mptcp: add addr parameter for get_addr
  mptcp: reuse sending nlmsg code in get_addr
  mptcp: change info of get_addr as const
  mptcp: add struct mptcp_id_bitmap
  mptcp: refactor dump_addr with id bitmap
  mptcp: refactor dump_addr with get_addr
  mptcp: reuse sending nlmsg code in dump_addr
  mptcp: update local address flags when setting it
  mptcp: change rem type of set_flags
  mptcp: drop skb parameter of set_flags
  mptcp: add loc and rem for set_flags
  mptcp: update address type of get_local_id
  mptcp: change is_backup interfaces as get_flags
  mptcp: drop struct mptcp_pm_local
  mptcp: drop struct mptcp_pm_add_entry
  mptcp: change local type of subflow_destroy
  mptcp: hold pm lock when deleting entry
  mptcp: rename mptcp_pm_remove_addrs
  mptcp: drop free_list for deleting entries
  mptcp: define struct mptcp_pm_ops
  mptcp: implement userspace pm interfaces
  mptcp: register default userspace pm
  bpf: Add mptcp path manager struct_ops
  bpf: Register mptcp struct_ops kfunc set
  Squash to "bpf: Export mptcp packet scheduler helpers"
  selftests/bpf: Add mptcp userspace pm subtest
  selftests/bpf: Add mptcp bpf path manager subtest

 include/net/mptcp.h                           |  32 +
 net/mptcp/bpf.c                               | 377 ++++++++-
 net/mptcp/pm.c                                |  53 +-
 net/mptcp/pm_netlink.c                        | 313 +++----
 net/mptcp/pm_userspace.c                      | 777 ++++++++++--------
 net/mptcp/protocol.c                          |   1 +
 net/mptcp/protocol.h                          |  81 +-
 net/mptcp/subflow.c                           |   2 +-
 tools/testing/selftests/bpf/config            |   1 +
 .../testing/selftests/bpf/prog_tests/mptcp.c  | 305 +++++++
 tools/testing/selftests/bpf/progs/mptcp_bpf.h |  71 ++
 .../bpf/progs/mptcp_bpf_userspace_pm.c        | 409 +++++++++
 12 files changed, 1855 insertions(+), 567 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c

-- 
2.45.2


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

* [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22 17:01   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink Geliang Tang
                   ` (37 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The helper mptcp_pm_addr_families_match() uses "if-else" to handle IPv6
and IPv4 addresses separately. But the last line of "if" code block is
a "return" statement. In this case, no need to use an "else" statement.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 16c336c51940..f3d354a72c94 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -495,9 +495,8 @@ bool mptcp_pm_addr_families_match(const struct 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
+	return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET;
 }
 
 void mptcp_pm_data_reset(struct mptcp_sock *msk)
-- 
2.45.2


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

* [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22 17:09   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros Geliang Tang
                   ` (36 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The helper __lookup_addr() can be used in mptcp_pm_nl_get_local_id()
and mptcp_pm_nl_is_backup() to simplify the code if using
list_for_each_entry_rcu() instead of list_for_each_entry() in it.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 618289aac0ab..a60a6fc04bf4 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -524,7 +524,7 @@ __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) {
+	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
 		if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
 			return entry;
 	}
@@ -1146,12 +1146,9 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
 	pernet = pm_nl_get_pernet_from_msk(msk);
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
-			ret = entry->addr.id;
-			break;
-		}
-	}
+	entry = __lookup_addr(pernet, skc);
+	if (entry)
+		ret = entry->addr.id;
 	rcu_read_unlock();
 	if (ret >= 0)
 		return ret;
@@ -1181,12 +1178,9 @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
 	bool backup = false;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
-			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-			break;
-		}
-	}
+	entry = __lookup_addr(pernet, skc);
+	if (entry)
+		backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 	rcu_read_unlock();
 
 	return backup;
-- 
2.45.2


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

* [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-30 18:20   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree Geliang Tang
                   ` (35 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Similar to mptcp_for_each_subflow() and mptcp_for_each_subflow_safe()
macros, this patch adds two new macros mptcp_for_each_address() and
mptcp_for_each_address_safe() to iterate over the address entries on
userspace_pm_local_addr_list of the mptcp socket.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 12 ++++++------
 net/mptcp/protocol.h     |  5 +++++
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 2cceded3a83a..00a7f9dd90cf 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -41,7 +41,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 	bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
 
 	spin_lock_bh(&msk->pm.lock);
-	list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address(msk, e) {
 		addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true);
 		if (addr_match && entry->addr.id == 0 && needs_id)
 			entry->addr.id = e->addr.id;
@@ -92,7 +92,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
 {
 	struct mptcp_pm_addr_entry *entry, *tmp;
 
-	list_for_each_entry_safe(entry, tmp, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address_safe(msk, entry, tmp) {
 		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
 			/* TODO: a refcount is needed because the entry can
 			 * be used multiple times (e.g. fullmesh mode).
@@ -112,7 +112,7 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
 {
 	struct mptcp_pm_addr_entry *entry;
 
-	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address(msk, entry) {
 		if (entry->addr.id == id)
 			return entry;
 	}
@@ -127,7 +127,7 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
 			     inet_sk((struct sock *)msk))->inet_sport;
 
 	spin_lock_bh(&msk->pm.lock);
-	list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address(msk, e) {
 		if (mptcp_addresses_equal(&e->addr, skc, false)) {
 			entry = e;
 			break;
@@ -155,7 +155,7 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
 	bool backup = false;
 
 	spin_lock_bh(&msk->pm.lock);
-	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address(msk, entry) {
 		if (mptcp_addresses_equal(&entry->addr, skc, false)) {
 			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 			break;
@@ -642,7 +642,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+	mptcp_for_each_address(msk, entry) {
 		if (test_bit(entry->addr.id, bitmap->map))
 			continue;
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index b4c72a73594f..ce3b12778b3f 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -354,6 +354,11 @@ struct mptcp_sock {
 #define mptcp_for_each_subflow_safe(__msk, __subflow, __tmp)			\
 	list_for_each_entry_safe(__subflow, __tmp, &((__msk)->conn_list), node)
 
+#define mptcp_for_each_address(__msk, __entry)			\
+	list_for_each_entry(__entry, &((__msk)->pm.userspace_pm_local_addr_list), list)
+#define mptcp_for_each_address_safe(__msk, __entry, __tmp)			\
+	list_for_each_entry_safe(__entry, __tmp, &((__msk)->pm.userspace_pm_local_addr_list), list)
+
 extern struct genl_family mptcp_genl_family;
 
 static inline void msk_owned_by_me(const struct mptcp_sock *msk)
-- 
2.45.2


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

* [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (2 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-30 18:21   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm Geliang Tang
                   ` (34 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The local address entries on the userspace_pm_local_addr_list are allocated
by sock_kmalloc(). It's better to use sock_kfree_s() to free them, instead
of using kfree().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 00a7f9dd90cf..3fb5713cd988 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -91,6 +91,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
 						struct mptcp_pm_addr_entry *addr)
 {
 	struct mptcp_pm_addr_entry *entry, *tmp;
+	struct sock *sk = (struct sock *)msk;
 
 	mptcp_for_each_address_safe(msk, entry, tmp) {
 		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
@@ -98,7 +99,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
 			 * be used multiple times (e.g. fullmesh mode).
 			 */
 			list_del_rcu(&entry->list);
-			kfree(entry);
+			sock_kfree_s(sk, entry, sizeof(*entry));
 			msk->pm.local_addr_used--;
 			return 0;
 		}
-- 
2.45.2


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

* [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (3 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-30 18:21   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper Geliang Tang
                   ` (33 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Like __lookup_addr() helper in pm_netlink.c, a new helper
mptcp_userspace_pm_lookup_addr() is also defined in pm_userspace.c.
It looks up the corresponding mptcp_pm_addr_entry address in
userspace_pm_local_addr_list through the passed "addr" parameter
and returns it.

This helper can be used in mptcp_userspace_pm_delete_local_addr(),
mptcp_userspace_pm_get_local_id() and mptcp_userspace_pm_is_backup()
to simplify the code.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 56 +++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 27 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 3fb5713cd988..ce0f7131c701 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -26,6 +26,18 @@ void mptcp_free_local_addr_list(struct mptcp_sock *msk)
 	}
 }
 
+static struct mptcp_pm_addr_entry *
+mptcp_userspace_pm_lookup_addr(struct mptcp_sock *msk, const struct mptcp_addr_info *addr)
+{
+	struct mptcp_pm_addr_entry *entry, *tmp;
+
+	mptcp_for_each_address_safe(msk, entry, tmp) {
+		if (mptcp_addresses_equal(&entry->addr, addr, false))
+			return entry;
+	}
+	return NULL;
+}
+
 static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 						    struct mptcp_pm_addr_entry *entry,
 						    bool needs_id)
@@ -90,22 +102,20 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
 						struct mptcp_pm_addr_entry *addr)
 {
-	struct mptcp_pm_addr_entry *entry, *tmp;
 	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry *entry;
 
-	mptcp_for_each_address_safe(msk, entry, tmp) {
-		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
-			/* TODO: a refcount is needed because the entry can
-			 * be used multiple times (e.g. fullmesh mode).
-			 */
-			list_del_rcu(&entry->list);
-			sock_kfree_s(sk, entry, sizeof(*entry));
-			msk->pm.local_addr_used--;
-			return 0;
-		}
-	}
-
-	return -EINVAL;
+	entry = mptcp_userspace_pm_lookup_addr(msk, &addr->addr);
+	if (!entry)
+		return -EINVAL;
+
+	/* TODO: a refcount is needed because the entry can
+	 * be used multiple times (e.g. fullmesh mode).
+	 */
+	list_del_rcu(&entry->list);
+	sock_kfree_s(sk, entry, sizeof(*entry));
+	msk->pm.local_addr_used--;
+	return 0;
 }
 
 static struct mptcp_pm_addr_entry *
@@ -123,17 +133,12 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
 				    struct mptcp_addr_info *skc)
 {
-	struct mptcp_pm_addr_entry *entry = NULL, *e, new_entry;
+	struct mptcp_pm_addr_entry *entry = NULL, new_entry;
 	__be16 msk_sport =  ((struct inet_sock *)
 			     inet_sk((struct sock *)msk))->inet_sport;
 
 	spin_lock_bh(&msk->pm.lock);
-	mptcp_for_each_address(msk, e) {
-		if (mptcp_addresses_equal(&e->addr, skc, false)) {
-			entry = e;
-			break;
-		}
-	}
+	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
 	spin_unlock_bh(&msk->pm.lock);
 	if (entry)
 		return entry->addr.id;
@@ -156,12 +161,9 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
 	bool backup = false;
 
 	spin_lock_bh(&msk->pm.lock);
-	mptcp_for_each_address(msk, entry) {
-		if (mptcp_addresses_equal(&entry->addr, skc, false)) {
-			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-			break;
-		}
-	}
+	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
+	if (entry)
+		backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 	spin_unlock_bh(&msk->pm.lock);
 
 	return backup;
-- 
2.45.2


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

* [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (4 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-30 18:23   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static Geliang Tang
                   ` (32 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Each userspace pm netlink function uses nla_get_u32() to get the msk
token value, then pass it to mptcp_token_get_sock() to get the msk.
Finally check whether userspace PM is selected on this msk. It makes
sense to wrap them into a helper, named mptcp_userspace_pm_get_sock(),
to do this.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 137 +++++++++++++--------------------------
 1 file changed, 44 insertions(+), 93 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index ce0f7131c701..79ae32c921b7 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -169,36 +169,51 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
 	return backup;
 }
 
-int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
+static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
 {
 	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
+	struct mptcp_sock *msk = NULL;
+
+	if (!token) {
+		GENL_SET_ERR_MSG(info, "missing required inputs");
+		goto out;
+	}
+
+	msk = mptcp_token_get_sock(genl_info_net(info), nla_get_u32(token));
+	if (!msk) {
+		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+		goto out;
+	}
+
+	if (!mptcp_pm_is_userspace(msk)) {
+		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
+		sock_put((struct sock *)msk);
+		msk = NULL;
+	}
+
+out:
+	return msk;
+}
+
+int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
+{
 	struct nlattr *addr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	struct mptcp_pm_addr_entry addr_val;
 	struct mptcp_sock *msk;
 	int err = -EINVAL;
 	struct sock *sk;
-	u32 token_val;
 
-	if (!addr || !token) {
+	if (!addr) {
 		GENL_SET_ERR_MSG(info, "missing required inputs");
 		return err;
 	}
 
-	token_val = nla_get_u32(token);
-
-	msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return err;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto announce_err;
-	}
-
 	err = mptcp_pm_parse_entry(addr, info, true, &addr_val);
 	if (err < 0) {
 		GENL_SET_ERR_MSG(info, "error parsing local address");
@@ -271,7 +286,6 @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
 
 int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
 	struct mptcp_pm_addr_entry *match;
 	struct mptcp_pm_addr_entry *entry;
@@ -279,30 +293,21 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 	LIST_HEAD(free_list);
 	int err = -EINVAL;
 	struct sock *sk;
-	u32 token_val;
 	u8 id_val;
 
-	if (!id || !token) {
+	if (!id) {
 		GENL_SET_ERR_MSG(info, "missing required inputs");
 		return err;
 	}
 
 	id_val = nla_get_u8(id);
-	token_val = nla_get_u32(token);
 
-	msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return err;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto out;
-	}
-
 	if (id_val == 0) {
 		err = mptcp_userspace_pm_remove_id_zero_address(msk, info);
 		goto out;
@@ -336,7 +341,6 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
-	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	struct mptcp_pm_addr_entry entry = { 0 };
 	struct mptcp_addr_info addr_r;
@@ -344,28 +348,18 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 	struct mptcp_sock *msk;
 	int err = -EINVAL;
 	struct sock *sk;
-	u32 token_val;
 
-	if (!laddr || !raddr || !token) {
+	if (!laddr || !raddr) {
 		GENL_SET_ERR_MSG(info, "missing required inputs");
 		return err;
 	}
 
-	token_val = nla_get_u32(token);
-
-	msk = mptcp_token_get_sock(genl_info_net(info), token_val);
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return err;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto create_err;
-	}
-
 	err = mptcp_pm_parse_entry(laddr, info, true, &entry);
 	if (err < 0) {
 		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
@@ -468,35 +462,24 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
 int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
-	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	struct mptcp_addr_info addr_l;
 	struct mptcp_addr_info addr_r;
 	struct mptcp_sock *msk;
 	struct sock *sk, *ssk;
 	int err = -EINVAL;
-	u32 token_val;
 
-	if (!laddr || !raddr || !token) {
+	if (!laddr || !raddr) {
 		GENL_SET_ERR_MSG(info, "missing required inputs");
 		return err;
 	}
 
-	token_val = nla_get_u32(token);
-
-	msk = mptcp_token_get_sock(genl_info_net(info), token_val);
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return err;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto destroy_err;
-	}
-
 	err = mptcp_pm_parse_addr(laddr, info, &addr_l);
 	if (err < 0) {
 		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
@@ -559,30 +542,18 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
 	struct mptcp_pm_addr_entry rem = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
-	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
-	struct net *net = sock_net(skb->sk);
 	struct mptcp_sock *msk;
 	int ret = -EINVAL;
 	struct sock *sk;
-	u32 token_val;
 	u8 bkup = 0;
 
-	token_val = nla_get_u32(token);
-
-	msk = mptcp_token_get_sock(net, token_val);
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return ret;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "userspace PM not selected");
-		goto set_flags_err;
-	}
-
 	ret = mptcp_pm_parse_entry(attr, info, false, &loc);
 	if (ret < 0)
 		goto set_flags_err;
@@ -619,30 +590,20 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 		DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
 	} *bitmap;
 	const struct genl_info *info = genl_info_dump(cb);
-	struct net *net = sock_net(msg->sk);
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
-	struct nlattr *token;
 	int ret = -EINVAL;
 	struct sock *sk;
 	void *hdr;
 
 	bitmap = (struct id_bitmap *)cb->ctx;
-	token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 
-	msk = mptcp_token_get_sock(net, nla_get_u32(token));
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return ret;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto out;
-	}
-
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
 	mptcp_for_each_address(msk, entry) {
@@ -667,7 +628,6 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 	release_sock(sk);
 	ret = msg->len;
 
-out:
 	sock_put(sk);
 	return ret;
 }
@@ -676,28 +636,19 @@ int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
 				struct genl_info *info)
 {
 	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
-	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct mptcp_pm_addr_entry addr, *entry;
-	struct net *net = sock_net(skb->sk);
 	struct mptcp_sock *msk;
 	struct sk_buff *msg;
 	int ret = -EINVAL;
 	struct sock *sk;
 	void *reply;
 
-	msk = mptcp_token_get_sock(net, nla_get_u32(token));
-	if (!msk) {
-		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
 		return ret;
-	}
 
 	sk = (struct sock *)msk;
 
-	if (!mptcp_pm_is_userspace(msk)) {
-		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
-		goto out;
-	}
-
 	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
 	if (ret < 0)
 		goto out;
-- 
2.45.2


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

* [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (5 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-30 18:31   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 08/36] mptcp: drop skb parameter of get_addr Geliang Tang
                   ` (31 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Three path manager wrappers, mptcp_pm_get_addr(), mptcp_pm_dump_addr() and
mptcp_pm_set_flags() are used to switch the interfaces between in-kernel
PM and userspace PM. These wrappers are defined in pm.c but only used in
pm_netlink.c. It makes more sense to move them to pm_netlink.c and make
them all static.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c         | 23 -----------------------
 net/mptcp/pm_netlink.c | 31 +++++++++++++++++++++++++++----
 net/mptcp/protocol.h   |  7 -------
 3 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index f3d354a72c94..f5725c00eb70 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -433,29 +433,6 @@ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
 	return mptcp_pm_nl_is_backup(msk, &skc_local);
 }
 
-int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
-{
-	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_get_addr(skb, info);
-	return mptcp_pm_nl_get_addr(skb, info);
-}
-
-int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
-{
-	const struct genl_info *info = genl_info_dump(cb);
-
-	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_dump_addr(msg, cb);
-	return mptcp_pm_nl_dump_addr(msg, cb);
-}
-
-int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
-{
-	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_set_flags(skb, info);
-	return mptcp_pm_nl_set_flags(skb, info);
-}
-
 void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
 {
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index a60a6fc04bf4..8b4815d0df53 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1792,7 +1792,7 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
 	return -EMSGSIZE;
 }
 
-int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
@@ -1842,13 +1842,20 @@ int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
+static int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
+{
+	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
+		return mptcp_userspace_pm_get_addr(skb, info);
+	return mptcp_pm_nl_get_addr(skb, info);
+}
+
 int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	return mptcp_pm_get_addr(skb, info);
 }
 
-int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
-			  struct netlink_callback *cb)
+static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
+				 struct netlink_callback *cb)
 {
 	struct net *net = sock_net(msg->sk);
 	struct mptcp_pm_addr_entry *entry;
@@ -1890,6 +1897,15 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 	return msg->len;
 }
 
+static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
+{
+	const struct genl_info *info = genl_info_dump(cb);
+
+	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
+		return mptcp_userspace_pm_dump_addr(msg, cb);
+	return mptcp_pm_nl_dump_addr(msg, cb);
+}
+
 int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
 				struct netlink_callback *cb)
 {
@@ -2011,7 +2027,7 @@ static int mptcp_nl_set_flags(struct net *net,
 	return ret;
 }
 
-int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
@@ -2065,6 +2081,13 @@ int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
+static int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
+{
+	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
+		return mptcp_userspace_pm_set_flags(skb, info);
+	return mptcp_pm_nl_set_flags(skb, info);
+}
+
 int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	return mptcp_pm_set_flags(skb, info);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index ce3b12778b3f..b6e66bfca2e5 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1036,8 +1036,6 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 struct mptcp_pm_add_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr);
-int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
-int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info);
 int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 			   const struct mptcp_addr_info *addr,
@@ -1128,13 +1126,8 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_in
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
 bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb);
-int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
-			  struct netlink_callback *cb);
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb);
-int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info);
-int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info);
 int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
 				struct genl_info *info);
 
-- 
2.45.2


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

* [PATCH mptcp-next v2 08/36] mptcp: drop skb parameter of get_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (6 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 09/36] mptcp: add id parameter for get_addr Geliang Tang
                   ` (30 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The first parameters "skb" of all three get_addr() interfaces are now
useless since mptcp_userspace_pm_get_sock() helper is used. This patch
drops these useless parameters of them.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 10 +++++-----
 net/mptcp/pm_userspace.c |  3 +--
 net/mptcp/protocol.h     |  3 +--
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 8b4815d0df53..90279732d226 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1792,7 +1792,7 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
 	return -EMSGSIZE;
 }
 
-static int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_nl_get_addr(struct genl_info *info)
 {
 	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
@@ -1842,16 +1842,16 @@ static int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
-static int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_get_addr(struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_get_addr(skb, info);
-	return mptcp_pm_nl_get_addr(skb, info);
+		return mptcp_userspace_pm_get_addr(info);
+	return mptcp_pm_nl_get_addr(info);
 }
 
 int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	return mptcp_pm_get_addr(skb, info);
+	return mptcp_pm_get_addr(info);
 }
 
 static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 79ae32c921b7..e61cc1805cee 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -632,8 +632,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 	return ret;
 }
 
-int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
-				struct genl_info *info)
+int mptcp_userspace_pm_get_addr(struct genl_info *info)
 {
 	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
 	struct mptcp_pm_addr_entry addr, *entry;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index b6e66bfca2e5..b991c65b0a72 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1128,8 +1128,7 @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb);
-int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
-				struct genl_info *info);
+int mptcp_userspace_pm_get_addr(struct genl_info *info);
 
 static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
 {
-- 
2.45.2


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

* [PATCH mptcp-next v2 09/36] mptcp: add id parameter for get_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (7 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 08/36] mptcp: drop skb parameter of get_addr Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 10/36] mptcp: add addr " Geliang Tang
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The address id is parsed both in mptcp_pm_nl_get_addr() and
mptcp_userspace_pm_get_addr(), this makes the code somewhat repetitive.
So this patch adds a new parameter "id" for all get_addr() interfaces.
The address id is only parsed in mptcp_pm_nl_get_addr_doit(), then pass
it to both mptcp_pm_nl_get_addr() and mptcp_userspace_pm_get_addr().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 28 ++++++++++++++++------------
 net/mptcp/pm_userspace.c | 11 +++--------
 net/mptcp/protocol.h     |  2 +-
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 90279732d226..9a886caa336e 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1792,19 +1792,14 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
 	return -EMSGSIZE;
 }
 
-static int mptcp_pm_nl_get_addr(struct genl_info *info)
+static int mptcp_pm_nl_get_addr(u8 id, struct genl_info *info)
 {
-	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct mptcp_pm_addr_entry addr, *entry;
+	struct mptcp_pm_addr_entry *entry;
 	struct sk_buff *msg;
 	void *reply;
 	int ret;
 
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		return ret;
-
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
 		return -ENOMEM;
@@ -1818,7 +1813,7 @@ static int mptcp_pm_nl_get_addr(struct genl_info *info)
 	}
 
 	spin_lock_bh(&pernet->lock);
-	entry = __lookup_addr_by_id(pernet, addr.addr.id);
+	entry = __lookup_addr_by_id(pernet, id);
 	if (!entry) {
 		GENL_SET_ERR_MSG(info, "address not found");
 		ret = -EINVAL;
@@ -1842,16 +1837,25 @@ static int mptcp_pm_nl_get_addr(struct genl_info *info)
 	return ret;
 }
 
-static int mptcp_pm_get_addr(struct genl_info *info)
+static int mptcp_pm_get_addr(u8 id, struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_get_addr(info);
-	return mptcp_pm_nl_get_addr(info);
+		return mptcp_userspace_pm_get_addr(id, info);
+	return mptcp_pm_nl_get_addr(id, info);
 }
 
 int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	return mptcp_pm_get_addr(info);
+	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
+	struct mptcp_pm_addr_entry addr;
+	int ret;
+
+	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
+	if (ret < 0)
+		return ret;
+
+	ret = mptcp_pm_get_addr(addr.addr.id, info);
+	return ret;
 }
 
 static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index e61cc1805cee..079baceb9ca1 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -632,10 +632,9 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 	return ret;
 }
 
-int mptcp_userspace_pm_get_addr(struct genl_info *info)
+int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info)
 {
-	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
-	struct mptcp_pm_addr_entry addr, *entry;
+	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
 	struct sk_buff *msg;
 	int ret = -EINVAL;
@@ -648,10 +647,6 @@ int mptcp_userspace_pm_get_addr(struct genl_info *info)
 
 	sk = (struct sock *)msk;
 
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		goto out;
-
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg) {
 		ret = -ENOMEM;
@@ -668,7 +663,7 @@ int mptcp_userspace_pm_get_addr(struct genl_info *info)
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, addr.addr.id);
+	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
 	if (!entry) {
 		GENL_SET_ERR_MSG(info, "address not found");
 		ret = -EINVAL;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index b991c65b0a72..6326e8f4bf5c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1128,7 +1128,7 @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb);
-int mptcp_userspace_pm_get_addr(struct genl_info *info);
+int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info);
 
 static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
 {
-- 
2.45.2


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

* [PATCH mptcp-next v2 10/36] mptcp: add addr parameter for get_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (8 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 09/36] mptcp: add id parameter for get_addr Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 11/36] mptcp: reuse sending nlmsg code in get_addr Geliang Tang
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The netlink messages are sent both in mptcp_pm_nl_get_addr() and
mptcp_userspace_pm_get_addr(), this makes the code somewhat repetitive.
This is because the netlink PM and userspace PM use different locks to
protect the address entry that needs to be sent via the netlink message.
The former uses pernet->lock, and the latter uses msk->pm.lock.

The current get_addr() flow looks like this:

	lock();
	entry = get_entry();
	send_nlmsg(entry);
	unlock();

After holding the lock, get the entry from the list, send the entry, and
finally release the lock.

This patch changes the process by getting the entry while holding the lock,
then making a copy of the entry so that the lock can be released. Finally,
the copy of the entry is sent without locking:

	lock();
	entry = get_entry();
	*copy = *entry;
	unlock();

	send_nlmsg(copy);

This way we can reuse this send_nlmsg() code between the netlink PM and
userspace PM.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 33 ++++++++++++++++++---------------
 net/mptcp/pm_userspace.c | 24 +++++++++++++-----------
 net/mptcp/protocol.h     |  3 ++-
 3 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 9a886caa336e..bfd8bc3dfb86 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1792,13 +1792,14 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
 	return -EMSGSIZE;
 }
 
-static int mptcp_pm_nl_get_addr(u8 id, struct genl_info *info)
+static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+				struct genl_info *info)
 {
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
 	struct mptcp_pm_addr_entry *entry;
 	struct sk_buff *msg;
+	int ret = -EINVAL;
 	void *reply;
-	int ret;
 
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
@@ -1814,34 +1815,36 @@ static int mptcp_pm_nl_get_addr(u8 id, struct genl_info *info)
 
 	spin_lock_bh(&pernet->lock);
 	entry = __lookup_addr_by_id(pernet, id);
-	if (!entry) {
+	if (entry) {
+		*addr = *entry;
+		ret = 0;
+	}
+	spin_unlock_bh(&pernet->lock);
+
+	if (ret) {
 		GENL_SET_ERR_MSG(info, "address not found");
-		ret = -EINVAL;
-		goto unlock_fail;
+		goto fail;
 	}
 
-	ret = mptcp_nl_fill_addr(msg, entry);
+	ret = mptcp_nl_fill_addr(msg, addr);
 	if (ret)
-		goto unlock_fail;
+		goto fail;
 
 	genlmsg_end(msg, reply);
 	ret = genlmsg_reply(msg, info);
-	spin_unlock_bh(&pernet->lock);
 	return ret;
 
-unlock_fail:
-	spin_unlock_bh(&pernet->lock);
-
 fail:
 	nlmsg_free(msg);
 	return ret;
 }
 
-static int mptcp_pm_get_addr(u8 id, struct genl_info *info)
+static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+			     struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_get_addr(id, info);
-	return mptcp_pm_nl_get_addr(id, info);
+		return mptcp_userspace_pm_get_addr(id, addr, info);
+	return mptcp_pm_nl_get_addr(id, addr, info);
 }
 
 int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
@@ -1854,7 +1857,7 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		return ret;
 
-	ret = mptcp_pm_get_addr(addr.addr.id, info);
+	ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
 	return ret;
 }
 
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 079baceb9ca1..d1f2b592b47c 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -632,7 +632,8 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 	return ret;
 }
 
-int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info)
+int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+				struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
@@ -664,26 +665,27 @@ int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info)
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
 	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
-	if (!entry) {
+	if (entry) {
+		*addr = *entry;
+		ret = 0;
+	}
+	spin_unlock_bh(&msk->pm.lock);
+	release_sock(sk);
+
+	if (ret) {
 		GENL_SET_ERR_MSG(info, "address not found");
-		ret = -EINVAL;
-		goto unlock_fail;
+		goto fail;
 	}
 
-	ret = mptcp_nl_fill_addr(msg, entry);
+	ret = mptcp_nl_fill_addr(msg, addr);
 	if (ret)
-		goto unlock_fail;
+		goto fail;
 
 	genlmsg_end(msg, reply);
 	ret = genlmsg_reply(msg, info);
-	spin_unlock_bh(&msk->pm.lock);
-	release_sock(sk);
 	sock_put(sk);
 	return ret;
 
-unlock_fail:
-	spin_unlock_bh(&msk->pm.lock);
-	release_sock(sk);
 fail:
 	nlmsg_free(msg);
 out:
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 6326e8f4bf5c..ffc18646976b 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1128,7 +1128,8 @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb);
-int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info);
+int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+				struct genl_info *info);
 
 static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
 {
-- 
2.45.2


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

* [PATCH mptcp-next v2 11/36] mptcp: reuse sending nlmsg code in get_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (9 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 10/36] mptcp: add addr " Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const Geliang Tang
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

With the previous commit, we can reuse the send_nlmsg() code in
get_addr() interfaces between the netlink PM and userspace PM.
They only need to implement their own get_addr() interfaces to
hold the different locks, get the entry from the different lists,
then release the locks.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 58 ++++++++++++++++++++--------------------
 net/mptcp/pm_userspace.c | 33 -----------------------
 2 files changed, 29 insertions(+), 62 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index bfd8bc3dfb86..064fe4d494eb 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1797,21 +1797,7 @@ static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 {
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
 	struct mptcp_pm_addr_entry *entry;
-	struct sk_buff *msg;
 	int ret = -EINVAL;
-	void *reply;
-
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg)
-		return -ENOMEM;
-
-	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
-				  info->genlhdr->cmd);
-	if (!reply) {
-		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
-		ret = -EMSGSIZE;
-		goto fail;
-	}
 
 	spin_lock_bh(&pernet->lock);
 	entry = __lookup_addr_by_id(pernet, id);
@@ -1821,21 +1807,6 @@ static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 	}
 	spin_unlock_bh(&pernet->lock);
 
-	if (ret) {
-		GENL_SET_ERR_MSG(info, "address not found");
-		goto fail;
-	}
-
-	ret = mptcp_nl_fill_addr(msg, addr);
-	if (ret)
-		goto fail;
-
-	genlmsg_end(msg, reply);
-	ret = genlmsg_reply(msg, info);
-	return ret;
-
-fail:
-	nlmsg_free(msg);
 	return ret;
 }
 
@@ -1851,13 +1822,42 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
 	struct mptcp_pm_addr_entry addr;
+	struct sk_buff *msg;
+	void *reply;
 	int ret;
 
 	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
 	if (ret < 0)
 		return ret;
 
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
+				  info->genlhdr->cmd);
+	if (!reply) {
+		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
+		ret = -EMSGSIZE;
+		goto fail;
+	}
+
 	ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
+	if (ret) {
+		GENL_SET_ERR_MSG(info, "address not found");
+		goto fail;
+	}
+
+	ret = mptcp_nl_fill_addr(msg, &addr);
+	if (ret)
+		goto fail;
+
+	genlmsg_end(msg, reply);
+	ret = genlmsg_reply(msg, info);
+	return ret;
+
+fail:
+	nlmsg_free(msg);
 	return ret;
 }
 
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index d1f2b592b47c..dd2ecc9ee6d5 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -637,10 +637,8 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 {
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
-	struct sk_buff *msg;
 	int ret = -EINVAL;
 	struct sock *sk;
-	void *reply;
 
 	msk = mptcp_userspace_pm_get_sock(info);
 	if (!msk)
@@ -648,20 +646,6 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 
 	sk = (struct sock *)msk;
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
-				  info->genlhdr->cmd);
-	if (!reply) {
-		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
-		ret = -EMSGSIZE;
-		goto fail;
-	}
-
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
 	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
@@ -672,23 +656,6 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 	spin_unlock_bh(&msk->pm.lock);
 	release_sock(sk);
 
-	if (ret) {
-		GENL_SET_ERR_MSG(info, "address not found");
-		goto fail;
-	}
-
-	ret = mptcp_nl_fill_addr(msg, addr);
-	if (ret)
-		goto fail;
-
-	genlmsg_end(msg, reply);
-	ret = genlmsg_reply(msg, info);
-	sock_put(sk);
-	return ret;
-
-fail:
-	nlmsg_free(msg);
-out:
 	sock_put(sk);
 	return ret;
 }
-- 
2.45.2


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

* [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (10 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 11/36] mptcp: reuse sending nlmsg code in get_addr Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-31 18:41   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap Geliang Tang
                   ` (26 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

get_addr() interfeces will be invoked by dump_addr(), which using const
parameters "info", so this patch changes "info" parameters of get_addr()
as const too.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 9 ++++++---
 net/mptcp/pm_userspace.c | 2 +-
 net/mptcp/protocol.h     | 2 +-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 064fe4d494eb..02e4dda0dc13 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1793,12 +1793,15 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
 }
 
 static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
-				struct genl_info *info)
+				const struct genl_info *info)
 {
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct net *net = genl_info_net(info);
 	struct mptcp_pm_addr_entry *entry;
+	struct pm_nl_pernet *pernet;
 	int ret = -EINVAL;
 
+	pernet = pm_nl_get_pernet(net);
+
 	spin_lock_bh(&pernet->lock);
 	entry = __lookup_addr_by_id(pernet, id);
 	if (entry) {
@@ -1811,7 +1814,7 @@ static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 }
 
 static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
-			     struct genl_info *info)
+			     const struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
 		return mptcp_userspace_pm_get_addr(id, addr, info);
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index dd2ecc9ee6d5..c10794154187 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -633,7 +633,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 }
 
 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
-				struct genl_info *info)
+				const struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index ffc18646976b..8282a6355765 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1129,7 +1129,7 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb);
 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
-				struct genl_info *info);
+				const struct genl_info *info);
 
 static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
 {
-- 
2.45.2


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

* [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (11 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-31 18:45   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap Geliang Tang
                   ` (25 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

A new struct mptcp_id_bitmap is defined to unify all bitmap type of address
IDs for both in-kernel PM and userspace PM.

This type can be used to easily refactor dump_addr() interface of the path
managers to accept an mptcp_id_bitmap type parameter. It also allows this
parameter of dump_addr() can be modified by BPF program when implementing
this interface of a BFP path manager.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c           |  2 +-
 net/mptcp/pm_netlink.c   | 42 ++++++++++++++++++++--------------------
 net/mptcp/pm_userspace.c | 14 ++++++--------
 net/mptcp/protocol.h     |  6 +++++-
 4 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index f5725c00eb70..b6e6859903ef 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -512,7 +512,7 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
 	WRITE_ONCE(pm->addr_signal, 0);
 	WRITE_ONCE(pm->remote_deny_join_id0, false);
 	pm->status = 0;
-	bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	bitmap_fill(msk->pm.id_avail_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
 }
 
 void mptcp_pm_data_init(struct mptcp_sock *msk)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 02e4dda0dc13..c030a79cd1dd 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -37,7 +37,7 @@ struct pm_nl_pernet {
 	unsigned int		local_addr_max;
 	unsigned int		subflows_max;
 	unsigned int		next_id;
-	DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	struct mptcp_id_bitmap	id_bitmap;
 };
 
 #define MPTCP_PM_ADDR_MAX	8
@@ -161,7 +161,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
 		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
 			continue;
 
-		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap.map))
 			continue;
 
 		new_local->addr = entry->addr;
@@ -189,7 +189,7 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
 	 * can lead to additional addresses not being announced.
 	 */
 	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap.map))
 			continue;
 
 		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
@@ -243,7 +243,7 @@ bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk)
 	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
 
 	if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) ||
-	    (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap,
+	    (find_next_and_bit(pernet->id_bitmap.map, msk->pm.id_avail_bitmap.map,
 			       MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1)) {
 		WRITE_ONCE(msk->pm.work_pending, false);
 		return false;
@@ -443,15 +443,15 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
 		msk->pm.subflows++;
 		addrs[i++] = remote;
 	} else {
-		DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
+		struct mptcp_id_bitmap unavail_id;
 
 		/* Forbid creation of new subflows matching existing
 		 * ones, possibly already created by incoming ADD_ADDR
 		 */
-		bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
+		bitmap_zero(unavail_id.map, MPTCP_PM_MAX_ADDR_ID + 1);
 		mptcp_for_each_subflow(msk, subflow)
 			if (READ_ONCE(subflow->local_id) == local->id)
-				__set_bit(subflow->remote_id, unavail_id);
+				__set_bit(subflow->remote_id, unavail_id.map);
 
 		mptcp_for_each_subflow(msk, subflow) {
 			ssk = mptcp_subflow_tcp_sock(subflow);
@@ -460,7 +460,7 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
 			if (deny_id0 && !addrs[i].id)
 				continue;
 
-			if (test_bit(addrs[i].id, unavail_id))
+			if (test_bit(addrs[i].id, unavail_id.map))
 				continue;
 
 			if (!mptcp_pm_addr_families_match(sk, local, &addrs[i]))
@@ -470,7 +470,7 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
 				/* forbid creating multiple address towards
 				 * this id
 				 */
-				__set_bit(addrs[i].id, unavail_id);
+				__set_bit(addrs[i].id, unavail_id.map);
 				msk->pm.subflows++;
 				i++;
 			}
@@ -558,7 +558,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 		rcu_read_lock();
 		entry = __lookup_addr(pernet, &mpc_addr);
 		if (entry) {
-			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
+			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap.map);
 			msk->mpc_endpoint_id = entry->addr.id;
 			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 		}
@@ -596,7 +596,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 		if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
 			return;
 
-		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
+		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap.map);
 		msk->pm.add_addr_signaled++;
 
 		/* Special case for ID0: set the correct ID */
@@ -625,7 +625,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 
 		fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
 
-		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
+		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap.map);
 
 		/* Special case for ID0: set the correct ID */
 		if (local.addr.id == msk->mpc_endpoint_id)
@@ -991,7 +991,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 		ret = -ERANGE;
 		goto out;
 	}
-	if (test_bit(entry->addr.id, pernet->id_bitmap)) {
+	if (test_bit(entry->addr.id, pernet->id_bitmap.map)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -1025,7 +1025,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 
 	if (!entry->addr.id && needs_id) {
 find_next:
-		entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
+		entry->addr.id = find_next_zero_bit(pernet->id_bitmap.map,
 						    MPTCP_PM_MAX_ADDR_ID + 1,
 						    pernet->next_id);
 		if (!entry->addr.id && pernet->next_id != 1) {
@@ -1037,7 +1037,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 	if (!entry->addr.id && needs_id)
 		goto out;
 
-	__set_bit(entry->addr.id, pernet->id_bitmap);
+	__set_bit(entry->addr.id, pernet->id_bitmap.map);
 	if (entry->addr.id > pernet->next_id)
 		pernet->next_id = entry->addr.id;
 
@@ -1480,7 +1480,7 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
 	if (ret || force) {
 		spin_lock_bh(&msk->pm.lock);
 		if (ret) {
-			__set_bit(addr->id, msk->pm.id_avail_bitmap);
+			__set_bit(addr->id, msk->pm.id_avail_bitmap.map);
 			msk->pm.add_addr_signaled--;
 		}
 		mptcp_pm_remove_addr(msk, &list);
@@ -1492,7 +1492,7 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
 static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
 {
 	/* If it was marked as used, and not ID 0, decrement local_addr_used */
-	if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
+	if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap.map) &&
 	    id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
 		msk->pm.local_addr_used--;
 }
@@ -1623,7 +1623,7 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
 
 	pernet->addrs--;
 	list_del_rcu(&entry->list);
-	__clear_bit(entry->addr.id, pernet->id_bitmap);
+	__clear_bit(entry->addr.id, pernet->id_bitmap.map);
 	spin_unlock_bh(&pernet->lock);
 
 	mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), entry);
@@ -1687,7 +1687,7 @@ static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
 	if (slist.nr)
 		mptcp_pm_nl_rm_subflow_received(msk, &slist);
 	/* Reset counters: maybe some subflows have been removed before */
-	bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	bitmap_fill(msk->pm.id_avail_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
 	msk->pm.local_addr_used = 0;
 	spin_unlock_bh(&msk->pm.lock);
 }
@@ -1745,7 +1745,7 @@ int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
 	list_splice_init(&pernet->local_addr_list, &free_list);
 	__reset_counters(pernet);
 	pernet->next_id = 1;
-	bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	bitmap_zero(pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
 	spin_unlock_bh(&pernet->lock);
 	mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
 	synchronize_rcu();
@@ -1878,7 +1878,7 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 
 	spin_lock_bh(&pernet->lock);
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
-		if (test_bit(i, pernet->id_bitmap)) {
+		if (test_bit(i, pernet->id_bitmap.map)) {
 			entry = __lookup_addr_by_id(pernet, i);
 			if (!entry)
 				break;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index c10794154187..cb4f2a174d0d 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -42,15 +42,15 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 						    struct mptcp_pm_addr_entry *entry,
 						    bool needs_id)
 {
-	DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
 	struct mptcp_pm_addr_entry *match = NULL;
 	struct sock *sk = (struct sock *)msk;
+	struct mptcp_id_bitmap id_bitmap;
 	struct mptcp_pm_addr_entry *e;
 	bool addr_match = false;
 	bool id_match = false;
 	int ret = -EINVAL;
 
-	bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	bitmap_zero(id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
 
 	spin_lock_bh(&msk->pm.lock);
 	mptcp_for_each_address(msk, e) {
@@ -64,7 +64,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 		} else if (addr_match || id_match) {
 			break;
 		}
-		__set_bit(e->addr.id, id_bitmap);
+		__set_bit(e->addr.id, id_bitmap.map);
 	}
 
 	if (!match && !addr_match && !id_match) {
@@ -79,7 +79,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 
 		*e = *entry;
 		if (!e->addr.id && needs_id)
-			e->addr.id = find_next_zero_bit(id_bitmap,
+			e->addr.id = find_next_zero_bit(id_bitmap.map,
 							MPTCP_PM_MAX_ADDR_ID + 1,
 							1);
 		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
@@ -586,17 +586,15 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb)
 {
-	struct id_bitmap {
-		DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
-	} *bitmap;
 	const struct genl_info *info = genl_info_dump(cb);
 	struct mptcp_pm_addr_entry *entry;
+	struct mptcp_id_bitmap *bitmap;
 	struct mptcp_sock *msk;
 	int ret = -EINVAL;
 	struct sock *sk;
 	void *hdr;
 
-	bitmap = (struct id_bitmap *)cb->ctx;
+	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
 
 	msk = mptcp_userspace_pm_get_sock(info);
 	if (!msk)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8282a6355765..4358a9a21270 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -211,6 +211,10 @@ enum mptcp_addr_signal_status {
 /* max value of mptcp_addr_info.id */
 #define MPTCP_PM_MAX_ADDR_ID		U8_MAX
 
+struct mptcp_id_bitmap {
+	DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
+};
+
 struct mptcp_pm_data {
 	struct mptcp_addr_info local;
 	struct mptcp_addr_info remote;
@@ -231,7 +235,7 @@ struct mptcp_pm_data {
 	u8		pm_type;
 	u8		subflows;
 	u8		status;
-	DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	struct mptcp_id_bitmap id_avail_bitmap;
 	struct mptcp_rm_list rm_list_tx;
 	struct mptcp_rm_list rm_list_rx;
 };
-- 
2.45.2


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

* [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (12 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 17:18   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 15/36] mptcp: refactor dump_addr with get_addr Geliang Tang
                   ` (24 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

With the help of get_addr(), we can refactor dump_addr() interfaces to
reuse send_nlmsg code between the netlink PM and userspace PM.

The current dump_addr() flow looks like this:

	lock();
	for_each_entry(entry)
		send_nlmsg(entry);
	unlock();

After holding the lock, get every entry by walking the address list,
send each one looply, and finally release the lock.

This set changes the process by copying the address list to an id
bitmap while holding the lock, then release the lock immediately.
After that, without locking, walking the copied id bitmap to get
every copy of entry by using get_addr(), and send each one looply.

This patch is the first part of refactoring dump_addr().

Without changing the position of the locks, the dump process is split
into two parts: copying the ID bitmap first, and then traversing the
ID bitmap, use lookup_addr_by_id() to get the entry, then send each
one through nlmsg:

	lock();
	for_each_entry(entry)
		set_bit(bitmap);
	for_each_bit(bitmap) {
		entry = lookup_addr_by_id();
		send_nlmsg(entry);
	}
	unlock();

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   |  6 ++++-
 net/mptcp/pm_userspace.c | 54 +++++++++++++++++++++++++++++-----------
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index c030a79cd1dd..4cee5942200c 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1869,16 +1869,20 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 {
 	struct net *net = sock_net(msg->sk);
 	struct mptcp_pm_addr_entry *entry;
+	struct mptcp_id_bitmap *bitmap;
 	struct pm_nl_pernet *pernet;
 	int id = cb->args[0];
 	void *hdr;
 	int i;
 
+	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
 	pernet = pm_nl_get_pernet(net);
 
 	spin_lock_bh(&pernet->lock);
+	if (!id)
+		bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
-		if (test_bit(i, pernet->id_bitmap.map)) {
+		if (test_bit(i, bitmap->map)) {
 			entry = __lookup_addr_by_id(pernet, i);
 			if (!entry)
 				break;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index cb4f2a174d0d..237383cfd12e 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -583,6 +583,21 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
+static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
+					 struct mptcp_id_bitmap *bitmap)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	mptcp_for_each_address(msk, entry) {
+		if (test_bit(entry->addr.id, bitmap->map))
+			continue;
+
+		__set_bit(entry->addr.id, bitmap->map);
+	}
+
+	return 0;
+}
+
 int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb)
 {
@@ -590,9 +605,11 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_id_bitmap *bitmap;
 	struct mptcp_sock *msk;
+	int id = cb->args[0];
 	int ret = -EINVAL;
 	struct sock *sk;
 	void *hdr;
+	int i;
 
 	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
 
@@ -604,24 +621,33 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	mptcp_for_each_address(msk, entry) {
-		if (test_bit(entry->addr.id, bitmap->map))
-			continue;
+	if (!id)
+		ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
+		if (test_bit(i, bitmap->map)) {
+			entry = mptcp_userspace_pm_lookup_addr_by_id(msk, i);
+			if (!entry)
+				break;
+
+			if (id && entry->addr.id <= id)
+				continue;
 
-		hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
-				  cb->nlh->nlmsg_seq, &mptcp_genl_family,
-				  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
-		if (!hdr)
-			break;
+			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
+					  cb->nlh->nlmsg_seq, &mptcp_genl_family,
+					  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
+			if (!hdr)
+				break;
 
-		if (mptcp_nl_fill_addr(msg, entry) < 0) {
-			genlmsg_cancel(msg, hdr);
-			break;
-		}
+			if (mptcp_nl_fill_addr(msg, entry) < 0) {
+				genlmsg_cancel(msg, hdr);
+				break;
+			}
 
-		__set_bit(entry->addr.id, bitmap->map);
-		genlmsg_end(msg, hdr);
+			id = entry->addr.id;
+			genlmsg_end(msg, hdr);
+		}
 	}
+	cb->args[0] = id;
 	spin_unlock_bh(&msk->pm.lock);
 	release_sock(sk);
 	ret = msg->len;
-- 
2.45.2


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

* [PATCH mptcp-next v2 15/36] mptcp: refactor dump_addr with get_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (13 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 16/36] mptcp: reuse sending nlmsg code in dump_addr Geliang Tang
                   ` (23 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch is the second part of refactoring dump_addr().

With the help of get_addr(), only copy the address list to an id
bitmap while holding the lock, then release the lock immediately.

After that, without locking, walking the copied id bitmap to get
every copy of entry by using get_addr(), and send each one looply:

	lock();
	for_each_entry(entry)
		set_bit(bitmap);
	unlock();

	for_each_bit(bitmap) {
		copy = get_addr();
		send_nlmsg(copy);
	}

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 20 +++++++++++---------
 net/mptcp/pm_userspace.c | 23 ++++++++++++-----------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 4cee5942200c..1777421344e2 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1867,8 +1867,9 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb)
 {
+	const struct genl_info *info = genl_info_dump(cb);
 	struct net *net = sock_net(msg->sk);
-	struct mptcp_pm_addr_entry *entry;
+	struct mptcp_pm_addr_entry entry;
 	struct mptcp_id_bitmap *bitmap;
 	struct pm_nl_pernet *pernet;
 	int id = cb->args[0];
@@ -1878,16 +1879,18 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
 	pernet = pm_nl_get_pernet(net);
 
-	spin_lock_bh(&pernet->lock);
-	if (!id)
+	if (!id) {
+		spin_lock_bh(&pernet->lock);
 		bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
+		spin_unlock_bh(&pernet->lock);
+	}
+
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
 		if (test_bit(i, bitmap->map)) {
-			entry = __lookup_addr_by_id(pernet, i);
-			if (!entry)
+			if (mptcp_pm_nl_get_addr(i, &entry, info))
 				break;
 
-			if (entry->addr.id <= id)
+			if (entry.addr.id <= id)
 				continue;
 
 			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
@@ -1896,16 +1899,15 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 			if (!hdr)
 				break;
 
-			if (mptcp_nl_fill_addr(msg, entry) < 0) {
+			if (mptcp_nl_fill_addr(msg, &entry) < 0) {
 				genlmsg_cancel(msg, hdr);
 				break;
 			}
 
-			id = entry->addr.id;
+			id = entry.addr.id;
 			genlmsg_end(msg, hdr);
 		}
 	}
-	spin_unlock_bh(&pernet->lock);
 
 	cb->args[0] = id;
 	return msg->len;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 237383cfd12e..8c7fc1fd1e2b 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -602,7 +602,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 				 struct netlink_callback *cb)
 {
 	const struct genl_info *info = genl_info_dump(cb);
-	struct mptcp_pm_addr_entry *entry;
+	struct mptcp_pm_addr_entry entry;
 	struct mptcp_id_bitmap *bitmap;
 	struct mptcp_sock *msk;
 	int id = cb->args[0];
@@ -619,17 +619,20 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 
 	sk = (struct sock *)msk;
 
-	lock_sock(sk);
-	spin_lock_bh(&msk->pm.lock);
-	if (!id)
+	if (!id) {
+		lock_sock(sk);
+		spin_lock_bh(&msk->pm.lock);
 		ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+		spin_unlock_bh(&msk->pm.lock);
+		release_sock(sk);
+	}
+
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
 		if (test_bit(i, bitmap->map)) {
-			entry = mptcp_userspace_pm_lookup_addr_by_id(msk, i);
-			if (!entry)
+			if (mptcp_userspace_pm_get_addr(i, &entry, info))
 				break;
 
-			if (id && entry->addr.id <= id)
+			if (id && entry.addr.id <= id)
 				continue;
 
 			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
@@ -638,18 +641,16 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 			if (!hdr)
 				break;
 
-			if (mptcp_nl_fill_addr(msg, entry) < 0) {
+			if (mptcp_nl_fill_addr(msg, &entry) < 0) {
 				genlmsg_cancel(msg, hdr);
 				break;
 			}
 
-			id = entry->addr.id;
+			id = entry.addr.id;
 			genlmsg_end(msg, hdr);
 		}
 	}
 	cb->args[0] = id;
-	spin_unlock_bh(&msk->pm.lock);
-	release_sock(sk);
 	ret = msg->len;
 
 	sock_put(sk);
-- 
2.45.2


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

* [PATCH mptcp-next v2 16/36] mptcp: reuse sending nlmsg code in dump_addr
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (14 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 15/36] mptcp: refactor dump_addr with get_addr Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it Geliang Tang
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

With the previous commit, we can reuse the send_nlmsg() code in
dump_addr interfaces between the netlink PM and userspace PM.
They only need to implement their own dump_addr() interfaces to
hold the different locks, copy the different address lists to an
id bitmap, then release the locks.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 56 +++++++++++++++++++++-------------------
 net/mptcp/pm_userspace.c | 50 +++++------------------------------
 net/mptcp/protocol.h     |  4 +--
 3 files changed, 38 insertions(+), 72 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 1777421344e2..c6476cb464b0 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1864,33 +1864,50 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
-static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
-				 struct netlink_callback *cb)
+static int mptcp_pm_nl_dump_addr(struct mptcp_id_bitmap *bitmap,
+				 const struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct pm_nl_pernet *pernet;
+
+	pernet = pm_nl_get_pernet(net);
+
+	spin_lock_bh(&pernet->lock);
+	bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
+	spin_unlock_bh(&pernet->lock);
+
+	return 0;
+}
+
+static int mptcp_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+			      const struct genl_info *info)
+{
+	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
+		return mptcp_userspace_pm_dump_addr(bitmap, info);
+	return mptcp_pm_nl_dump_addr(bitmap, info);
+}
+
+int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
+				struct netlink_callback *cb)
 {
 	const struct genl_info *info = genl_info_dump(cb);
-	struct net *net = sock_net(msg->sk);
 	struct mptcp_pm_addr_entry entry;
 	struct mptcp_id_bitmap *bitmap;
-	struct pm_nl_pernet *pernet;
 	int id = cb->args[0];
 	void *hdr;
 	int i;
 
 	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
-	pernet = pm_nl_get_pernet(net);
 
-	if (!id) {
-		spin_lock_bh(&pernet->lock);
-		bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
-		spin_unlock_bh(&pernet->lock);
-	}
+	if (!id)
+		mptcp_pm_dump_addr(bitmap, info);
 
 	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
 		if (test_bit(i, bitmap->map)) {
-			if (mptcp_pm_nl_get_addr(i, &entry, info))
+			if (mptcp_pm_get_addr(i, &entry, info))
 				break;
 
-			if (entry.addr.id <= id)
+			if (id && entry.addr.id <= id)
 				continue;
 
 			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
@@ -1913,21 +1930,6 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
 	return msg->len;
 }
 
-static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
-{
-	const struct genl_info *info = genl_info_dump(cb);
-
-	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_dump_addr(msg, cb);
-	return mptcp_pm_nl_dump_addr(msg, cb);
-}
-
-int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
-				struct netlink_callback *cb)
-{
-	return mptcp_pm_dump_addr(msg, cb);
-}
-
 static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
 {
 	struct nlattr *attr = info->attrs[id];
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 8c7fc1fd1e2b..d815bfa57532 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -598,20 +598,12 @@ static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
 	return 0;
 }
 
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
-				 struct netlink_callback *cb)
+int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+				 const struct genl_info *info)
 {
-	const struct genl_info *info = genl_info_dump(cb);
-	struct mptcp_pm_addr_entry entry;
-	struct mptcp_id_bitmap *bitmap;
 	struct mptcp_sock *msk;
-	int id = cb->args[0];
 	int ret = -EINVAL;
 	struct sock *sk;
-	void *hdr;
-	int i;
-
-	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
 
 	msk = mptcp_userspace_pm_get_sock(info);
 	if (!msk)
@@ -619,39 +611,11 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
 
 	sk = (struct sock *)msk;
 
-	if (!id) {
-		lock_sock(sk);
-		spin_lock_bh(&msk->pm.lock);
-		ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
-		spin_unlock_bh(&msk->pm.lock);
-		release_sock(sk);
-	}
-
-	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
-		if (test_bit(i, bitmap->map)) {
-			if (mptcp_userspace_pm_get_addr(i, &entry, info))
-				break;
-
-			if (id && entry.addr.id <= id)
-				continue;
-
-			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
-					  cb->nlh->nlmsg_seq, &mptcp_genl_family,
-					  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
-			if (!hdr)
-				break;
-
-			if (mptcp_nl_fill_addr(msg, &entry) < 0) {
-				genlmsg_cancel(msg, hdr);
-				break;
-			}
-
-			id = entry.addr.id;
-			genlmsg_end(msg, hdr);
-		}
-	}
-	cb->args[0] = id;
-	ret = msg->len;
+	lock_sock(sk);
+	spin_lock_bh(&msk->pm.lock);
+	ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+	spin_unlock_bh(&msk->pm.lock);
+	release_sock(sk);
 
 	sock_put(sk);
 	return ret;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 4358a9a21270..833ad44c6e65 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1130,8 +1130,8 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_in
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
 bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
-				 struct netlink_callback *cb);
+int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+				 const struct genl_info *info);
 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 				const struct genl_info *info);
 
-- 
2.45.2


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

* [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (15 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 16/36] mptcp: reuse sending nlmsg code in dump_addr Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 18:20   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 18/36] mptcp: change rem type of set_flags Geliang Tang
                   ` (21 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Just like in-kernel pm, when userspace pm does set_flags, it needs to send
out MP_PRIO signal, and also modify the flags of the corresponding address
entry in the local address list. This patch implements the missing logic.

Fixes: 892f396c8e68 ("mptcp: netlink: issue MP_PRIO signals from userspace PMs")
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index d815bfa57532..ec2ac0f9c8f5 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -543,6 +543,7 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 	struct mptcp_pm_addr_entry rem = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
 	int ret = -EINVAL;
 	struct sock *sk;
@@ -574,6 +575,16 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 	if (loc.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
 		bkup = 1;
 
+	spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &loc.addr);
+	if (entry) {
+		if (bkup)
+			entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
+		else
+			entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
+	}
+	spin_unlock_bh(&msk->pm.lock);
+
 	lock_sock(sk);
 	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem.addr, bkup);
 	release_sock(sk);
-- 
2.45.2


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

* [PATCH mptcp-next v2 18/36] mptcp: change rem type of set_flags
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (16 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 19/36] mptcp: drop skb parameter " Geliang Tang
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Generally, in the path manager interfaces, the local address is defined as
an mptcp_pm_addr_entry type address, while the remote address is defined as
an mptcp_addr_info type one:

	(struct mptcp_pm_addr_entry *local, struct mptcp_addr_info *remote)

But the set_flags() interface uses two mptcp_pm_addr_entry type parameters.
This patch changes the second one to mptcp_addr_info type and use helper
mptcp_pm_parse_addr() to parse it instead of using mptcp_pm_parse_entry().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index ec2ac0f9c8f5..b83f4af632b5 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -540,9 +540,9 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
-	struct mptcp_pm_addr_entry rem = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+	struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
 	int ret = -EINVAL;
@@ -560,13 +560,13 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 		goto set_flags_err;
 
 	if (attr_rem) {
-		ret = mptcp_pm_parse_entry(attr_rem, info, false, &rem);
+		ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
 		if (ret < 0)
 			goto set_flags_err;
 	}
 
 	if (loc.addr.family == AF_UNSPEC ||
-	    rem.addr.family == AF_UNSPEC) {
+	    rem.family == AF_UNSPEC) {
 		GENL_SET_ERR_MSG(info, "invalid address families");
 		ret = -EINVAL;
 		goto set_flags_err;
@@ -586,7 +586,7 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
 	spin_unlock_bh(&msk->pm.lock);
 
 	lock_sock(sk);
-	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem.addr, bkup);
+	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem, bkup);
 	release_sock(sk);
 
 set_flags_err:
-- 
2.45.2


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

* [PATCH mptcp-next v2 19/36] mptcp: drop skb parameter of set_flags
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (17 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 18/36] mptcp: change rem type of set_flags Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags Geliang Tang
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The first parameter "skb" in mptcp_pm_nl_set_flags() is only used to
obtained the network namespace, which can also be obtained through the
second parameters "info" by using genl_info_net() helper. This patch
drops these useless parameters "skb" in all three set_flags() interfaces.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 12 ++++++------
 net/mptcp/pm_userspace.c |  2 +-
 net/mptcp/protocol.h     |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index c6476cb464b0..5fb1d5d8bf57 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -2045,13 +2045,13 @@ static int mptcp_nl_set_flags(struct net *net,
 	return ret;
 }
 
-static int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_nl_set_flags(struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
 			   MPTCP_PM_ADDR_FLAG_FULLMESH;
-	struct net *net = sock_net(skb->sk);
+	struct net *net = genl_info_net(info);
 	struct mptcp_pm_addr_entry *entry;
 	struct pm_nl_pernet *pernet;
 	u8 lookup_by_id = 0;
@@ -2099,16 +2099,16 @@ static int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
+static int mptcp_pm_set_flags(struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_set_flags(skb, info);
-	return mptcp_pm_nl_set_flags(skb, info);
+		return mptcp_userspace_pm_set_flags(info);
+	return mptcp_pm_nl_set_flags(info);
 }
 
 int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	return mptcp_pm_set_flags(skb, info);
+	return mptcp_pm_set_flags(info);
 }
 
 static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index b83f4af632b5..4db39bf26cf4 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -537,7 +537,7 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 	return err;
 }
 
-int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
+int mptcp_userspace_pm_set_flags(struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
 	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 833ad44c6e65..29e39a790409 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1040,7 +1040,7 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 struct mptcp_pm_add_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr);
-int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
+int mptcp_userspace_pm_set_flags(struct genl_info *info);
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 			   const struct mptcp_addr_info *addr,
 			   bool echo);
-- 
2.45.2


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

* [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (18 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 19/36] mptcp: drop skb parameter " Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 18:36   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id Geliang Tang
                   ` (18 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch updates the interfaces set_flags to reduce repetitive code,
adds two more parameters "loc" and "rem" for them. These addresses are
parsed in public helper mptcp_pm_nl_set_flags_doit(), then pass them
to mptcp_pm_nl_set_flags() and mptcp_userspace_pm_set_flags().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 57 ++++++++++++++++++++++++----------------
 net/mptcp/pm_userspace.c | 28 ++++++--------------
 net/mptcp/protocol.h     |  4 ++-
 3 files changed, 46 insertions(+), 43 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 5fb1d5d8bf57..5cd5241da3c6 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -2045,10 +2045,10 @@ static int mptcp_nl_set_flags(struct net *net,
 	return ret;
 }
 
-static int mptcp_pm_nl_set_flags(struct genl_info *info)
+static int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_addr_info *rem,
+				 struct genl_info *info)
 {
-	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
-	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
 			   MPTCP_PM_ADDR_FLAG_FULLMESH;
 	struct net *net = genl_info_net(info);
@@ -2056,59 +2056,72 @@ static int mptcp_pm_nl_set_flags(struct genl_info *info)
 	struct pm_nl_pernet *pernet;
 	u8 lookup_by_id = 0;
 	u8 bkup = 0;
-	int ret;
 
 	pernet = pm_nl_get_pernet(net);
 
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		return ret;
-
-	if (addr.addr.family == AF_UNSPEC) {
+	if (loc->addr.family == AF_UNSPEC) {
 		lookup_by_id = 1;
-		if (!addr.addr.id) {
+		if (!loc->addr.id) {
 			GENL_SET_ERR_MSG(info, "missing required inputs");
 			return -EOPNOTSUPP;
 		}
 	}
 
-	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+	if (loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
 		bkup = 1;
 
 	spin_lock_bh(&pernet->lock);
-	entry = lookup_by_id ? __lookup_addr_by_id(pernet, addr.addr.id) :
-			       __lookup_addr(pernet, &addr.addr);
+	entry = lookup_by_id ? __lookup_addr_by_id(pernet, loc->addr.id) :
+			       __lookup_addr(pernet, &loc->addr);
 	if (!entry) {
 		spin_unlock_bh(&pernet->lock);
 		GENL_SET_ERR_MSG(info, "address not found");
 		return -EINVAL;
 	}
-	if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
+	if ((loc->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
 	    (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
 		spin_unlock_bh(&pernet->lock);
 		GENL_SET_ERR_MSG(info, "invalid addr flags");
 		return -EINVAL;
 	}
 
-	changed = (addr.flags ^ entry->flags) & mask;
-	entry->flags = (entry->flags & ~mask) | (addr.flags & mask);
-	addr = *entry;
+	changed = (loc->flags ^ entry->flags) & mask;
+	entry->flags = (entry->flags & ~mask) | (loc->flags & mask);
+	*loc = *entry;
 	spin_unlock_bh(&pernet->lock);
 
-	mptcp_nl_set_flags(net, &addr.addr, bkup, changed);
+	mptcp_nl_set_flags(net, &loc->addr, bkup, changed);
 	return 0;
 }
 
-static int mptcp_pm_set_flags(struct genl_info *info)
+static int mptcp_pm_set_flags(struct mptcp_pm_addr_entry *loc,
+			      struct mptcp_addr_info *rem,
+			      struct genl_info *info)
 {
 	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
-		return mptcp_userspace_pm_set_flags(info);
-	return mptcp_pm_nl_set_flags(info);
+		return mptcp_userspace_pm_set_flags(loc, rem, info);
+	return mptcp_pm_nl_set_flags(loc, rem, info);
 }
 
 int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
 {
-	return mptcp_pm_set_flags(info);
+	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
+	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
+	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+	struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
+	int ret;
+
+	ret = mptcp_pm_parse_entry(attr, info, false, &loc);
+	if (ret < 0)
+		return ret;
+
+	if (attr_rem) {
+		ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
+		if (ret < 0)
+			return ret;
+	}
+
+	return mptcp_pm_set_flags(&loc, &rem, info);
 }
 
 static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 4db39bf26cf4..aa4a5d110376 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -537,12 +537,10 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 	return err;
 }
 
-int mptcp_userspace_pm_set_flags(struct genl_info *info)
+int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_addr_info *rem,
+				 struct genl_info *info)
 {
-	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
-	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
-	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
-	struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
 	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
 	int ret = -EINVAL;
@@ -555,28 +553,18 @@ int mptcp_userspace_pm_set_flags(struct genl_info *info)
 
 	sk = (struct sock *)msk;
 
-	ret = mptcp_pm_parse_entry(attr, info, false, &loc);
-	if (ret < 0)
-		goto set_flags_err;
-
-	if (attr_rem) {
-		ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
-		if (ret < 0)
-			goto set_flags_err;
-	}
-
-	if (loc.addr.family == AF_UNSPEC ||
-	    rem.family == AF_UNSPEC) {
+	if (loc->addr.family == AF_UNSPEC ||
+	    rem->family == AF_UNSPEC) {
 		GENL_SET_ERR_MSG(info, "invalid address families");
 		ret = -EINVAL;
 		goto set_flags_err;
 	}
 
-	if (loc.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+	if (loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
 		bkup = 1;
 
 	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_userspace_pm_lookup_addr(msk, &loc.addr);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &loc->addr);
 	if (entry) {
 		if (bkup)
 			entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
@@ -586,7 +574,7 @@ int mptcp_userspace_pm_set_flags(struct genl_info *info)
 	spin_unlock_bh(&msk->pm.lock);
 
 	lock_sock(sk);
-	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem, bkup);
+	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, rem, bkup);
 	release_sock(sk);
 
 set_flags_err:
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 29e39a790409..25d2d3def17a 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1040,7 +1040,9 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 struct mptcp_pm_add_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr);
-int mptcp_userspace_pm_set_flags(struct genl_info *info);
+int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_addr_info *rem,
+				 struct genl_info *info);
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 			   const struct mptcp_addr_info *addr,
 			   bool echo);
-- 
2.45.2


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

* [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (19 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 18:48   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags Geliang Tang
                   ` (17 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The following code in mptcp_userspace_pm_get_local_id() that assigns "skc"
to "new_entry" is not allowed in BPF if we use the same code to implement
the get_local_id() interface of a BFP path manager:

	memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
	new_entry.addr = *skc;
	new_entry.addr.id = 0;
	new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;

To solve the issue, this patch moves this assignment to "new_entry" forward
to mptcp_pm_get_local_id(), and then passing "new_entry" as a parameter to
both mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c           | 10 ++++++++--
 net/mptcp/pm_netlink.c   | 11 +++--------
 net/mptcp/pm_userspace.c | 17 ++++++-----------
 net/mptcp/protocol.h     |  4 ++--
 4 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index b6e6859903ef..d28e844eba2d 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -404,6 +404,7 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 {
 	struct mptcp_addr_info skc_local;
 	struct mptcp_addr_info msk_local;
+	struct mptcp_pm_addr_entry local;
 
 	if (WARN_ON_ONCE(!msk))
 		return -1;
@@ -416,9 +417,14 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 	if (mptcp_addresses_equal(&msk_local, &skc_local, false))
 		return 0;
 
+	memset(&local, 0, sizeof(struct mptcp_pm_addr_entry));
+	local.addr = skc_local;
+	local.addr.id = 0;
+	local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
+
 	if (mptcp_pm_is_userspace(msk))
-		return mptcp_userspace_pm_get_local_id(msk, &skc_local);
-	return mptcp_pm_nl_get_local_id(msk, &skc_local);
+		return mptcp_userspace_pm_get_local_id(msk, &local);
+	return mptcp_pm_nl_get_local_id(msk, &local);
 }
 
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 5cd5241da3c6..032c9eb2e48d 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1137,7 +1137,7 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
 	return err;
 }
 
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
+int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry *local)
 {
 	struct mptcp_pm_addr_entry *entry;
 	struct pm_nl_pernet *pernet;
@@ -1146,7 +1146,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
 	pernet = pm_nl_get_pernet_from_msk(msk);
 
 	rcu_read_lock();
-	entry = __lookup_addr(pernet, skc);
+	entry = __lookup_addr(pernet, &local->addr);
 	if (entry)
 		ret = entry->addr.id;
 	rcu_read_unlock();
@@ -1158,12 +1158,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
 	if (!entry)
 		return -ENOMEM;
 
-	entry->addr = *skc;
-	entry->addr.id = 0;
-	entry->addr.port = 0;
-	entry->ifindex = 0;
-	entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
-	entry->lsk = NULL;
+	*entry = *local;
 	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
 	if (ret < 0)
 		kfree(entry);
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index aa4a5d110376..c749f5dccdf9 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -131,27 +131,22 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
 }
 
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
-				    struct mptcp_addr_info *skc)
+				    struct mptcp_pm_addr_entry *local)
 {
-	struct mptcp_pm_addr_entry *entry = NULL, new_entry;
+	struct mptcp_pm_addr_entry *entry = NULL;
 	__be16 msk_sport =  ((struct inet_sock *)
 			     inet_sk((struct sock *)msk))->inet_sport;
 
 	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
 	spin_unlock_bh(&msk->pm.lock);
 	if (entry)
 		return entry->addr.id;
 
-	memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
-	new_entry.addr = *skc;
-	new_entry.addr.id = 0;
-	new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
-
-	if (new_entry.addr.port == msk_sport)
-		new_entry.addr.port = 0;
+	if (local->addr.port == msk_sport)
+		local->addr.port = 0;
 
-	return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
+	return mptcp_userspace_pm_append_new_local_addr(msk, local, true);
 }
 
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 25d2d3def17a..4ff6b7e37947 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1127,8 +1127,8 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
 bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 			     struct mptcp_rm_list *rm_list);
 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);
+int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry *local);
+int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry *local);
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
 bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-- 
2.45.2


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

* [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (20 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 18:55   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local Geliang Tang
                   ` (16 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The is_backup() interface of path manager is not very common. A more
common approach is to add a get_flags() interface to obtain the flags
value of a given address. Then is_backup() can be implemented through
get_flags() by test whether backup flag is set in the flags value.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c           |  7 +++++--
 net/mptcp/pm_netlink.c   |  8 ++++----
 net/mptcp/pm_userspace.c | 10 +++++-----
 net/mptcp/protocol.h     |  4 ++--
 4 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index d28e844eba2d..c2229e46de1a 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -430,13 +430,16 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
 {
 	struct mptcp_addr_info skc_local;
+	u8 flags;
 
 	mptcp_local_address((struct sock_common *)skc, &skc_local);
 
 	if (mptcp_pm_is_userspace(msk))
-		return mptcp_userspace_pm_is_backup(msk, &skc_local);
+		flags = mptcp_userspace_pm_get_flags(msk, &skc_local);
+	else
+		flags = mptcp_pm_nl_get_flags(msk, &skc_local);
 
-	return mptcp_pm_nl_is_backup(msk, &skc_local);
+	return !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
 }
 
 void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 032c9eb2e48d..287e715bcf68 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1166,19 +1166,19 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry
 	return ret;
 }
 
-bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
+u8 mptcp_pm_nl_get_flags(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
 {
 	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
 	struct mptcp_pm_addr_entry *entry;
-	bool backup = false;
+	u8 flags = 0;
 
 	rcu_read_lock();
 	entry = __lookup_addr(pernet, skc);
 	if (entry)
-		backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+		flags = entry->flags;
 	rcu_read_unlock();
 
-	return backup;
+	return flags;
 }
 
 #define MPTCP_PM_CMD_GRP_OFFSET       0
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index c749f5dccdf9..0012b1965421 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -149,19 +149,19 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
 	return mptcp_userspace_pm_append_new_local_addr(msk, local, true);
 }
 
-bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
-				  struct mptcp_addr_info *skc)
+u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
+				struct mptcp_addr_info *skc)
 {
 	struct mptcp_pm_addr_entry *entry;
-	bool backup = false;
+	u8 flags = 0;
 
 	spin_lock_bh(&msk->pm.lock);
 	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
 	if (entry)
-		backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+		flags = entry->flags;
 	spin_unlock_bh(&msk->pm.lock);
 
-	return backup;
+	return flags;
 }
 
 static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 4ff6b7e37947..8efd288bd247 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1130,8 +1130,8 @@ 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_pm_addr_entry *local);
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry *local);
 bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
-bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+u8 mptcp_pm_nl_get_flags(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
 int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
 				 const struct genl_info *info);
 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
-- 
2.45.2


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

* [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (21 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 19:08   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry Geliang Tang
                   ` (15 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The following code in mptcp_pm_nl_subflow_create_doit() that assigns struct
mptcp_pm_addr_entry "entry" to the local struct mptcp_pm_local variable
"local" is not allowed in BPF if we use the same code to implement the
subflow_create() interface of a BFP path manager:

	struct mptcp_pm_local local;

	local.addr = entry.addr;
	local.flags = entry.flags;
	local.ifindex = entry.ifindex;

We should avoid this type of assignment from struct mptcp_pm_addr_entry to
struct mptcp_pm_local.

In fact, there is no need to add a dedicated address entry type for local
address entry. All its fields are the same as struct mptcp_pm_addr_entry,
except that it lacks a "lsk" for the listening socket. So we can use struct
mptcp_pm_addr_entry directly. This makes the path manager code simpler.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 22 ++++++++--------------
 net/mptcp/pm_userspace.c |  7 +------
 net/mptcp/protocol.h     |  8 +-------
 net/mptcp/subflow.c      |  2 +-
 4 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 287e715bcf68..15f97e7af182 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -149,7 +149,7 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
 static bool
 select_local_address(const struct pm_nl_pernet *pernet,
 		     const struct mptcp_sock *msk,
-		     struct mptcp_pm_local *new_local)
+		     struct mptcp_pm_addr_entry *new_local)
 {
 	struct mptcp_pm_addr_entry *entry;
 	bool found = false;
@@ -164,9 +164,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
 		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap.map))
 			continue;
 
-		new_local->addr = entry->addr;
-		new_local->flags = entry->flags;
-		new_local->ifindex = entry->ifindex;
+		*new_local = *entry;
 		found = true;
 		break;
 	}
@@ -177,7 +175,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
 
 static bool
 select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
-		     struct mptcp_pm_local *new_local)
+		     struct mptcp_pm_addr_entry *new_local)
 {
 	struct mptcp_pm_addr_entry *entry;
 	bool found = false;
@@ -195,9 +193,7 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
 		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
 			continue;
 
-		new_local->addr = entry->addr;
-		new_local->flags = entry->flags;
-		new_local->ifindex = entry->ifindex;
+		*new_local = *entry;
 		found = true;
 		break;
 	}
@@ -534,11 +530,11 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
 static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 {
 	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry local;
 	unsigned int add_addr_signal_max;
 	bool signal_and_subflow = false;
 	unsigned int local_addr_max;
 	struct pm_nl_pernet *pernet;
-	struct mptcp_pm_local local;
 	unsigned int subflows_max;
 
 	pernet = pm_nl_get_pernet(sock_net(sk));
@@ -660,7 +656,7 @@ static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
  */
 static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
 					     struct mptcp_addr_info *remote,
-					     struct mptcp_pm_local *locals)
+					     struct mptcp_pm_addr_entry *locals)
 {
 	struct sock *sk = (struct sock *)msk;
 	struct mptcp_pm_addr_entry *entry;
@@ -683,9 +679,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
 			continue;
 
 		if (msk->pm.subflows < subflows_max) {
-			locals[i].addr = entry->addr;
-			locals[i].flags = entry->flags;
-			locals[i].ifindex = entry->ifindex;
+			locals[i] = *entry;
 
 			/* Special case for ID0: set the correct ID */
 			if (mptcp_addresses_equal(&locals[i].addr, &mpc_addr, locals[i].addr.port))
@@ -721,7 +715,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
 
 static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
 {
-	struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
+	struct mptcp_pm_addr_entry locals[MPTCP_PM_ADDR_MAX];
 	struct sock *sk = (struct sock *)msk;
 	unsigned int add_addr_accept_max;
 	struct mptcp_addr_info remote;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 0012b1965421..c1bc668cce1e 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -339,7 +339,6 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	struct mptcp_pm_addr_entry entry = { 0 };
 	struct mptcp_addr_info addr_r;
-	struct mptcp_pm_local local;
 	struct mptcp_sock *msk;
 	int err = -EINVAL;
 	struct sock *sk;
@@ -386,12 +385,8 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 		goto create_err;
 	}
 
-	local.addr = entry.addr;
-	local.flags = entry.flags;
-	local.ifindex = entry.ifindex;
-
 	lock_sock(sk);
-	err = __mptcp_subflow_connect(sk, &local, &addr_r);
+	err = __mptcp_subflow_connect(sk, &entry, &addr_r);
 	release_sock(sk);
 
 	spin_lock_bh(&msk->pm.lock);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8efd288bd247..d9badf270b15 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -240,12 +240,6 @@ struct mptcp_pm_data {
 	struct mptcp_rm_list rm_list_rx;
 };
 
-struct mptcp_pm_local {
-	struct mptcp_addr_info	addr;
-	u8			flags;
-	int			ifindex;
-};
-
 struct mptcp_pm_addr_entry {
 	struct list_head	list;
 	struct mptcp_addr_info	addr;
@@ -745,7 +739,7 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
 void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);
 
 /* called with sk socket lock held */
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
 			    const struct mptcp_addr_info *remote);
 int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
 				struct socket **new_sock);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 07352b15f145..2ae8f467abc1 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1586,7 +1586,7 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
 #endif
 }
 
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
 			    const struct mptcp_addr_info *remote)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
-- 
2.45.2


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

* [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (22 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 19:13   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 25/36] mptcp: change local type of subflow_destroy Geliang Tang
                   ` (14 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

There is no need to add a dedicated address entry type "mptcp_pm_add_entry"
to represent ADD_ADDR addresses. Additional fields for ADD_ADDR addresses
can be added into struct mptcp_pm_addr_entry directly. This makes the path
manager code simpler.

Here "union" can be used to merge struct mptcp_pm_addr_entry and struct
mptcp_pm_add_entry into one. Then all mptcp_pm_add_entry can be replaced by
mptcp_pm_addr_entry.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c | 26 +++++++++-----------------
 net/mptcp/protocol.h   | 20 +++++++++++++++-----
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 15f97e7af182..06f0c7df575e 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -18,14 +18,6 @@
 
 static int pm_nl_pernet_id;
 
-struct mptcp_pm_add_entry {
-	struct list_head	list;
-	struct mptcp_addr_info	addr;
-	u8			retrans_times;
-	struct timer_list	add_timer;
-	struct mptcp_sock	*sock;
-};
-
 struct pm_nl_pernet {
 	/* protects pernet updates */
 	spinlock_t		lock;
@@ -247,11 +239,11 @@ bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk)
 	return true;
 }
 
-struct mptcp_pm_add_entry *
+struct mptcp_pm_addr_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_addr_entry *entry;
 
 	lockdep_assert_held(&msk->pm.lock);
 
@@ -265,7 +257,7 @@ mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 
 bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_addr_info saddr;
 	bool ret = false;
 
@@ -286,7 +278,7 @@ bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
 
 static void mptcp_pm_add_timer(struct timer_list *timer)
 {
-	struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
+	struct mptcp_pm_addr_entry *entry = from_timer(entry, timer, add_timer);
 	struct mptcp_sock *msk = entry->sock;
 	struct sock *sk = (struct sock *)msk;
 
@@ -328,11 +320,11 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
 	__sock_put(sk);
 }
 
-struct mptcp_pm_add_entry *
+struct mptcp_pm_addr_entry *
 mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 		       const struct mptcp_addr_info *addr, bool check_id)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_addr_entry *entry;
 	struct sock *sk = (struct sock *)msk;
 	struct timer_list *add_timer = NULL;
 
@@ -356,7 +348,7 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
 			      const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *add_entry = NULL;
+	struct mptcp_pm_addr_entry *add_entry = NULL;
 	struct sock *sk = (struct sock *)msk;
 	struct net *net = sock_net(sk);
 
@@ -392,7 +384,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
 
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
 {
-	struct mptcp_pm_add_entry *entry, *tmp;
+	struct mptcp_pm_addr_entry *entry, *tmp;
 	struct sock *sk = (struct sock *)msk;
 	LIST_HEAD(free_list);
 
@@ -1439,7 +1431,7 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
 static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
 				      const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_addr_entry *entry;
 
 	entry = mptcp_pm_del_add_timer(msk, addr, false);
 	if (entry) {
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index d9badf270b15..9dc01140af23 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -243,9 +243,19 @@ struct mptcp_pm_data {
 struct mptcp_pm_addr_entry {
 	struct list_head	list;
 	struct mptcp_addr_info	addr;
-	u8			flags;
-	int			ifindex;
-	struct socket		*lsk;
+	union {
+		struct {
+			u8			flags;
+			int			ifindex;
+			struct socket		*lsk;
+		};
+		/* mptcp_pm_add_entry */
+		struct {
+			u8			retrans_times;
+			struct timer_list	add_timer;
+			struct mptcp_sock	*sock;
+		};
+	};
 };
 
 struct mptcp_data_frag {
@@ -1028,10 +1038,10 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
 			      const struct mptcp_addr_info *addr);
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
 bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
-struct mptcp_pm_add_entry *
+struct mptcp_pm_addr_entry *
 mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 		       const struct mptcp_addr_info *addr, bool check_id);
-struct mptcp_pm_add_entry *
+struct mptcp_pm_addr_entry *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr);
 int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
-- 
2.45.2


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

* [PATCH mptcp-next v2 25/36] mptcp: change local type of subflow_destroy
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (23 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry Geliang Tang
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Generally, in the path manager interfaces, the local address is defined as
an mptcp_pm_addr_entry type address, while the remote address is defined as
an mptcp_addr_info type one:

        (struct mptcp_pm_addr_entry *local, struct mptcp_addr_info *remote)

But subflow_destroy() interface uses two mptcp_addr_info type parameters.
This patch changes the first one to mptcp_pm_addr_entry type and use helper
mptcp_pm_parse_entry() to parse it instead of using mptcp_pm_parse_addr().

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index c1bc668cce1e..7c23f6f27626 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -453,7 +453,7 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 {
 	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
 	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
-	struct mptcp_addr_info addr_l;
+	struct mptcp_pm_addr_entry local;
 	struct mptcp_addr_info addr_r;
 	struct mptcp_sock *msk;
 	struct sock *sk, *ssk;
@@ -470,7 +470,7 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 
 	sk = (struct sock *)msk;
 
-	err = mptcp_pm_parse_addr(laddr, info, &addr_l);
+	err = mptcp_pm_parse_entry(laddr, info, true, &local);
 	if (err < 0) {
 		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
 		goto destroy_err;
@@ -483,35 +483,34 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 	}
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	if (addr_l.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) {
-		ipv6_addr_set_v4mapped(addr_l.addr.s_addr, &addr_l.addr6);
-		addr_l.family = AF_INET6;
+	if (local.addr.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) {
+		ipv6_addr_set_v4mapped(local.addr.addr.s_addr, &local.addr.addr6);
+		local.addr.family = AF_INET6;
 	}
-	if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&addr_l.addr6)) {
-		ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &addr_r.addr6);
+	if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&local.addr.addr6)) {
+		ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &local.addr.addr6);
 		addr_r.family = AF_INET6;
 	}
 #endif
-	if (addr_l.family != addr_r.family) {
+	if (local.addr.family != addr_r.family) {
 		GENL_SET_ERR_MSG(info, "address families do not match");
 		err = -EINVAL;
 		goto destroy_err;
 	}
 
-	if (!addr_l.port || !addr_r.port) {
+	if (!local.addr.port || !addr_r.port) {
 		GENL_SET_ERR_MSG(info, "missing local or remote port");
 		err = -EINVAL;
 		goto destroy_err;
 	}
 
 	lock_sock(sk);
-	ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);
+	ssk = mptcp_nl_find_ssk(msk, &local.addr, &addr_r);
 	if (ssk) {
 		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
-		struct mptcp_pm_addr_entry entry = { .addr = addr_l };
 
 		spin_lock_bh(&msk->pm.lock);
-		mptcp_userspace_pm_delete_local_addr(msk, &entry);
+		mptcp_userspace_pm_delete_local_addr(msk, &local);
 		spin_unlock_bh(&msk->pm.lock);
 		mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
 		mptcp_close_ssk(sk, ssk, subflow);
-- 
2.45.2


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

* [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (24 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 25/36] mptcp: change local type of subflow_destroy Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 19:17   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs Geliang Tang
                   ` (12 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

When traversing userspace_pm_local_addr_list and deleting an entry from
it in mptcp_pm_nl_remove_doit(), msk->pm.lock should be held.

Fixes: d9a4594edabf ("mptcp: netlink: Add MPTCP_PM_CMD_REMOVE")
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 7c23f6f27626..3ad10d8062d9 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -310,14 +310,17 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 
 	lock_sock(sk);
 
+	spin_lock_bh(&msk->pm.lock);
 	match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
 	if (!match) {
 		GENL_SET_ERR_MSG(info, "address with specified id not found");
+		spin_unlock_bh(&msk->pm.lock);
 		release_sock(sk);
 		goto out;
 	}
 
 	list_move(&match->list, &free_list);
+	spin_unlock_bh(&msk->pm.lock);
 
 	mptcp_pm_remove_addrs(msk, &free_list);
 
-- 
2.45.2


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

* [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (25 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 19:24   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries Geliang Tang
                   ` (11 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

mptcp_pm_remove_addrs() actually only deletes one address, which does
not match its name. This patch renames it to mptcp_pm_remove_addr_entry()
and changes the parameter "rm_list" to "entry".

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_netlink.c   | 24 ++++++++++--------------
 net/mptcp/pm_userspace.c |  2 +-
 net/mptcp/protocol.h     |  3 ++-
 3 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 06f0c7df575e..852706e43f13 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1615,26 +1615,22 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
 }
 
 /* Called from the userspace PM only */
-void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
+void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
+				struct mptcp_pm_addr_entry *entry)
 {
 	struct mptcp_rm_list alist = { .nr = 0 };
-	struct mptcp_pm_addr_entry *entry;
 	int anno_nr = 0;
 
-	list_for_each_entry(entry, rm_list, list) {
-		if (alist.nr >= MPTCP_RM_IDS_MAX)
-			break;
-
-		/* only delete if either announced or matching a subflow */
-		if (remove_anno_list_by_saddr(msk, &entry->addr))
-			anno_nr++;
-		else if (!lookup_subflow_by_saddr(&msk->conn_list,
-						  &entry->addr))
-			continue;
+	/* only delete if either announced or matching a subflow */
+	if (remove_anno_list_by_saddr(msk, &entry->addr))
+		anno_nr++;
+	else if (!lookup_subflow_by_saddr(&msk->conn_list,
+					  &entry->addr))
+		goto out;
 
-		alist.ids[alist.nr++] = entry->addr.id;
-	}
+	alist.ids[alist.nr++] = entry->addr.id;
 
+out:
 	if (alist.nr) {
 		spin_lock_bh(&msk->pm.lock);
 		msk->pm.add_addr_signaled -= anno_nr;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 3ad10d8062d9..21b2a3b02cfe 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -322,7 +322,7 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 	list_move(&match->list, &free_list);
 	spin_unlock_bh(&msk->pm.lock);
 
-	mptcp_pm_remove_addrs(msk, &free_list);
+	mptcp_pm_remove_addr_entry(msk, match);
 
 	release_sock(sk);
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 9dc01140af23..13cd97f9e0f7 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1051,7 +1051,8 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 			   const struct mptcp_addr_info *addr,
 			   bool echo);
 int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
-void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
+void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
+				struct mptcp_pm_addr_entry *entry);
 
 void mptcp_free_local_addr_list(struct mptcp_sock *msk);
 
-- 
2.45.2


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

* [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (26 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-11-04 19:27   ` Matthieu Baerts
  2024-10-22  9:14 ` [PATCH mptcp-next v2 29/36] mptcp: define struct mptcp_pm_ops Geliang Tang
                   ` (10 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

With the help of mptcp_pm_remove_addr_entry(), it's no longer necessary to
move the entry to be deleted to free_list and then traverse the list to
delete the entry, which is not allowed in BPF. The entry can be directly
deleted through list_del_rcu() and sock_kfree_s() now.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 21b2a3b02cfe..e5dfa1a6db31 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -283,9 +283,7 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
 	struct mptcp_pm_addr_entry *match;
-	struct mptcp_pm_addr_entry *entry;
 	struct mptcp_sock *msk;
-	LIST_HEAD(free_list);
 	int err = -EINVAL;
 	struct sock *sk;
 	u8 id_val;
@@ -312,23 +310,21 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 
 	spin_lock_bh(&msk->pm.lock);
 	match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
+	spin_unlock_bh(&msk->pm.lock);
 	if (!match) {
 		GENL_SET_ERR_MSG(info, "address with specified id not found");
-		spin_unlock_bh(&msk->pm.lock);
 		release_sock(sk);
 		goto out;
 	}
 
-	list_move(&match->list, &free_list);
-	spin_unlock_bh(&msk->pm.lock);
-
 	mptcp_pm_remove_addr_entry(msk, match);
 
 	release_sock(sk);
 
-	list_for_each_entry_safe(match, entry, &free_list, list) {
-		sock_kfree_s(sk, match, sizeof(*match));
-	}
+	spin_lock_bh(&msk->pm.lock);
+	list_del_rcu(&match->list);
+	sock_kfree_s(sk, match, sizeof(*match));
+	spin_unlock_bh(&msk->pm.lock);
 
 	err = 0;
 out:
-- 
2.45.2


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

* [PATCH mptcp-next v2 29/36] mptcp: define struct mptcp_pm_ops
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (27 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 30/36] mptcp: implement userspace pm interfaces Geliang Tang
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

In order to allow users to develop their own BPF-based path manager,
this patch defines a struct ops "mptcp_pm_ops" for a userspace path
manager, which contains a set of interfaces.

Add a set of functions to register, unregister, find and validate a
given struct ops.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 include/net/mptcp.h      | 32 ++++++++++++++++++++++
 net/mptcp/pm_userspace.c | 58 ++++++++++++++++++++++++++++++++++++++++
 net/mptcp/protocol.h     |  5 ++++
 3 files changed, 95 insertions(+)

diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 814b5f2e3ed5..38b5862f6d98 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -15,6 +15,8 @@
 struct mptcp_info;
 struct mptcp_sock;
 struct seq_file;
+struct mptcp_pm_addr_entry;
+struct mptcp_id_bitmap;
 
 /* MPTCP sk_buff extension data */
 struct mptcp_ext {
@@ -120,6 +122,36 @@ struct mptcp_sched_ops {
 	void (*release)(struct mptcp_sock *msk);
 } ____cacheline_aligned_in_smp;
 
+struct mptcp_pm_ops {
+	int (*address_announce)(struct mptcp_sock *msk,
+				struct mptcp_pm_addr_entry *local);
+	int (*address_remove)(struct mptcp_sock *msk, u8 id);
+	int (*subflow_create)(struct mptcp_sock *msk,
+			      struct mptcp_pm_addr_entry *local,
+			      struct mptcp_addr_info *remote);
+	int (*subflow_destroy)(struct mptcp_sock *msk,
+			       struct mptcp_pm_addr_entry *local,
+			       struct mptcp_addr_info *remote);
+	int (*get_local_id)(struct mptcp_sock *msk,
+			    struct mptcp_pm_addr_entry *local);
+	u8 (*get_flags)(struct mptcp_sock *msk,
+			struct mptcp_addr_info *skc);
+	struct mptcp_pm_addr_entry *(*get_addr)(struct mptcp_sock *msk,
+						u8 id);
+	int (*dump_addr)(struct mptcp_sock *msk,
+			 struct mptcp_id_bitmap *bitmap);
+	int (*set_flags)(struct mptcp_sock *msk,
+			 struct mptcp_pm_addr_entry *local,
+			 struct mptcp_addr_info *remote);
+
+	u8			type;
+	struct module		*owner;
+	struct list_head	list;
+
+	void (*init)(struct mptcp_sock *msk);
+	void (*release)(struct mptcp_sock *msk);
+} ____cacheline_aligned_in_smp;
+
 #ifdef CONFIG_MPTCP
 void mptcp_init(void);
 
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index e5dfa1a6db31..459532617663 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -4,10 +4,15 @@
  * Copyright (c) 2022, Intel Corporation.
  */
 
+#include <linux/rculist.h>
+#include <linux/spinlock.h>
 #include "protocol.h"
 #include "mib.h"
 #include "mptcp_pm_gen.h"
 
+static DEFINE_SPINLOCK(mptcp_pm_list_lock);
+static LIST_HEAD(mptcp_pm_list);
+
 void mptcp_free_local_addr_list(struct mptcp_sock *msk)
 {
 	struct mptcp_pm_addr_entry *entry, *tmp;
@@ -635,3 +640,56 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 	sock_put(sk);
 	return ret;
 }
+
+/* Must be called with rcu read lock held */
+struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type)
+{
+	struct mptcp_pm_ops *pm;
+
+	list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
+		if (pm->type == type)
+			return pm;
+	}
+
+	return NULL;
+}
+
+int mptcp_validate_path_manager(struct mptcp_pm_ops *pm)
+{
+	if (!pm->address_announce && !pm->address_remove &&
+	    !pm->subflow_create && !pm->subflow_destroy &&
+	    !pm->get_local_id && !pm->get_flags &&
+	    !pm->get_addr && !pm->dump_addr && !pm->set_flags) {
+		pr_err("%u does not implement required ops\n", pm->type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int mptcp_register_path_manager(struct mptcp_pm_ops *pm)
+{
+	int ret;
+
+	ret = mptcp_validate_path_manager(pm);
+	if (ret)
+		return ret;
+
+	spin_lock(&mptcp_pm_list_lock);
+	if (mptcp_pm_find(pm->type)) {
+		spin_unlock(&mptcp_pm_list_lock);
+		return -EEXIST;
+	}
+	list_add_tail_rcu(&pm->list, &mptcp_pm_list);
+	spin_unlock(&mptcp_pm_list_lock);
+
+	pr_debug("userspace_pm type %u registered\n", pm->type);
+	return 0;
+}
+
+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm)
+{
+	spin_lock(&mptcp_pm_list_lock);
+	list_del_rcu(&pm->list);
+	spin_unlock(&mptcp_pm_list_lock);
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 13cd97f9e0f7..d6c9ca292bff 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1054,6 +1054,11 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
 void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
 				struct mptcp_pm_addr_entry *entry);
 
+struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type);
+int mptcp_validate_path_manager(struct mptcp_pm_ops *pm);
+int mptcp_register_path_manager(struct mptcp_pm_ops *pm);
+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm);
+
 void mptcp_free_local_addr_list(struct mptcp_sock *msk);
 
 void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
-- 
2.45.2


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

* [PATCH mptcp-next v2 30/36] mptcp: implement userspace pm interfaces
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (28 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 29/36] mptcp: define struct mptcp_pm_ops Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 31/36] mptcp: register default userspace pm Geliang Tang
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

1. implements address_announce() and address_remove() interfaces of the
userspace PM.

Extract address_announce() interface from the handler of netlink commond
MPTCP_PM_CMD_ANNOUNCE mptcp_pm_nl_announce_doit(), only leave the code for
obtaining msk through "info" and parsing address entry in the handler.

Extract address_remove() interface from the handler of netlink commond
MPTCP_PM_CMD_REMOVE mptcp_pm_nl_remove_doit(), only leave the code for
parsing address id and obtaining msk through "info" in the handler.

Both interfaces are invoked under holding the msk socket lock.

2. implements subflow_create() and subflow_destroy() interfaces of the
userspace PM.

Extract subflow_create() interface from the handler of netlink commond
MPTCP_PM_CMD_SUBFLOW_CREATE mptcp_pm_nl_subflow_create_doit(), only leave
the code for obtaining msk through "info", parsing local address entry
and parsing remote address info in the handler.

Extract subflow_destroy() interface from the handler of netlink commond
MPTCP_PM_CMD_SUBFLOW_DESTROY mptcp_pm_nl_subflow_destroy_doit(), only leave
the code for obtaining msk through "info", parsing local address entry and
parsing remote address info in the handler.

Both interfaces are invoked under holding the msk socket lock.

3. implements get_local_id(), get_flags(), get_addr(), dump_addr() and
set_flags() interfaces of the userspace PM.

get_local_id() interface is the same as mptcp_userspace_pm_get_local_id(),
which now can be defined as a wrapper of the interface. While get_flags()
interface is the same as mptcp_userspace_pm_get_flags() too, which now can
be defined as a wrapper of get_flags() interface.

get_addr() interface is a wrapper of mptcp_userspace_pm_lookup_addr_by_id()
helper. While dump_addr() is a wrapper of mptcp_userspace_pm_set_bitmap()
helper. These two interfaces are invoked under holding both the msk socket
lock and the msk pm lock.

Extract set_flags() interface from function mptcp_userspace_pm_set_flags(),
only leave the code for obtaining msk through "info" in this function. This
interface is invoked under holding the msk socket lock.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 326 ++++++++++++++++++++++-----------------
 1 file changed, 187 insertions(+), 139 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 459532617663..54c97d3d05ef 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -135,8 +135,8 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
 	return NULL;
 }
 
-int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
-				    struct mptcp_pm_addr_entry *local)
+static int userspace_pm_get_local_id(struct mptcp_sock *msk,
+				     struct mptcp_pm_addr_entry *local)
 {
 	struct mptcp_pm_addr_entry *entry = NULL;
 	__be16 msk_sport =  ((struct inet_sock *)
@@ -154,8 +154,14 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
 	return mptcp_userspace_pm_append_new_local_addr(msk, local, true);
 }
 
-u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
-				struct mptcp_addr_info *skc)
+int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
+				    struct mptcp_pm_addr_entry *local)
+{
+	return userspace_pm_get_local_id(msk, local);
+}
+
+static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
+				 struct mptcp_addr_info *skc)
 {
 	struct mptcp_pm_addr_entry *entry;
 	u8 flags = 0;
@@ -169,6 +175,12 @@ u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
 	return flags;
 }
 
+u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
+				struct mptcp_addr_info *skc)
+{
+	return userspace_pm_get_flags(msk, skc);
+}
+
 static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
 {
 	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
@@ -195,6 +207,31 @@ static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *in
 	return msk;
 }
 
+static int userspace_pm_address_announce(struct mptcp_sock *msk,
+					 struct mptcp_pm_addr_entry *local)
+{
+	int err;
+
+	if (local->addr.id == 0 || !(local->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
+		return -EINVAL;
+
+	err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
+	if (err < 0)
+		return err;
+
+	spin_lock_bh(&msk->pm.lock);
+
+	if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
+		msk->pm.add_addr_signaled++;
+		mptcp_pm_announce_addr(msk, &local->addr, false);
+		mptcp_pm_nl_addr_send_ack(msk);
+	}
+
+	spin_unlock_bh(&msk->pm.lock);
+
+	return 0;
+}
+
 int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *addr = info->attrs[MPTCP_PM_ATTR_ADDR];
@@ -220,46 +257,24 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
 		goto announce_err;
 	}
 
-	if (addr_val.addr.id == 0 || !(addr_val.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
-		GENL_SET_ERR_MSG(info, "invalid addr id or flags");
-		err = -EINVAL;
-		goto announce_err;
-	}
-
-	err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
-	if (err < 0) {
-		GENL_SET_ERR_MSG(info, "did not match address and id");
-		goto announce_err;
-	}
-
 	lock_sock(sk);
-	spin_lock_bh(&msk->pm.lock);
-
-	if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) {
-		msk->pm.add_addr_signaled++;
-		mptcp_pm_announce_addr(msk, &addr_val.addr, false);
-		mptcp_pm_nl_addr_send_ack(msk);
-	}
-
-	spin_unlock_bh(&msk->pm.lock);
+	err = userspace_pm_address_announce(msk, &addr_val);
 	release_sock(sk);
+	if (err)
+		GENL_SET_ERR_MSG(info, "address_announce failed");
 
-	err = 0;
  announce_err:
 	sock_put(sk);
 	return err;
 }
 
-static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
-						     struct genl_info *info)
+static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
 {
 	struct mptcp_rm_list list = { .nr = 0 };
 	struct mptcp_subflow_context *subflow;
-	struct sock *sk = (struct sock *)msk;
 	bool has_id_0 = false;
 	int err = -EINVAL;
 
-	lock_sock(sk);
 	mptcp_for_each_subflow(msk, subflow) {
 		if (READ_ONCE(subflow->local_id) == 0) {
 			has_id_0 = true;
@@ -267,7 +282,7 @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
 		}
 	}
 	if (!has_id_0) {
-		GENL_SET_ERR_MSG(info, "address with id 0 not found");
+		pr_debug("address with id 0 not found\n");
 		goto remove_err;
 	}
 
@@ -280,14 +295,36 @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
 	err = 0;
 
 remove_err:
-	release_sock(sk);
 	return err;
 }
 
+static int userspace_pm_address_remove(struct mptcp_sock *msk, u8 id)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry *match;
+
+	if (id == 0)
+		return mptcp_userspace_pm_remove_id_zero_address(msk);
+
+	spin_lock_bh(&msk->pm.lock);
+	match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+	spin_unlock_bh(&msk->pm.lock);
+	if (!match)
+		return -EINVAL;
+
+	mptcp_pm_remove_addr_entry(msk, match);
+
+	spin_lock_bh(&msk->pm.lock);
+	list_del_rcu(&match->list);
+	sock_kfree_s(sk, match, sizeof(*match));
+	spin_unlock_bh(&msk->pm.lock);
+
+	return 0;
+}
+
 int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
-	struct mptcp_pm_addr_entry *match;
 	struct mptcp_sock *msk;
 	int err = -EINVAL;
 	struct sock *sk;
@@ -306,34 +343,42 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 
 	sk = (struct sock *)msk;
 
-	if (id_val == 0) {
-		err = mptcp_userspace_pm_remove_id_zero_address(msk, info);
-		goto out;
-	}
-
 	lock_sock(sk);
+	err = userspace_pm_address_remove(msk, id_val);
+	release_sock(sk);
+	if (err)
+		GENL_SET_ERR_MSG(info, "address_remove failed");
 
-	spin_lock_bh(&msk->pm.lock);
-	match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
-	spin_unlock_bh(&msk->pm.lock);
-	if (!match) {
-		GENL_SET_ERR_MSG(info, "address with specified id not found");
-		release_sock(sk);
-		goto out;
-	}
+	sock_put(sk);
+	return err;
+}
 
-	mptcp_pm_remove_addr_entry(msk, match);
+static int userspace_pm_subflow_create(struct mptcp_sock *msk,
+				       struct mptcp_pm_addr_entry *local,
+				       struct mptcp_addr_info *remote)
+{
+	struct sock *sk = (struct sock *)msk;
+	int err;
 
-	release_sock(sk);
+	if (local->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
+		return -EINVAL;
+	local->flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
 
+	if (!mptcp_pm_addr_families_match(sk, &local->addr, remote))
+		return -EINVAL;
+
+	err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
+	if (err < 0)
+		return err;
+
+	err = __mptcp_subflow_connect(sk, local, remote);
 	spin_lock_bh(&msk->pm.lock);
-	list_del_rcu(&match->list);
-	sock_kfree_s(sk, match, sizeof(*match));
+	if (err)
+		mptcp_userspace_pm_delete_local_addr(msk, local);
+	else
+		msk->pm.subflows++;
 	spin_unlock_bh(&msk->pm.lock);
 
-	err = 0;
-out:
-	sock_put(sk);
 	return err;
 }
 
@@ -364,41 +409,17 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 		goto create_err;
 	}
 
-	if (entry.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
-		GENL_SET_ERR_MSG(info, "invalid addr flags");
-		err = -EINVAL;
-		goto create_err;
-	}
-	entry.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
-
 	err = mptcp_pm_parse_addr(raddr, info, &addr_r);
 	if (err < 0) {
 		NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr");
 		goto create_err;
 	}
 
-	if (!mptcp_pm_addr_families_match(sk, &entry.addr, &addr_r)) {
-		GENL_SET_ERR_MSG(info, "families mismatch");
-		err = -EINVAL;
-		goto create_err;
-	}
-
-	err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
-	if (err < 0) {
-		GENL_SET_ERR_MSG(info, "did not match address and id");
-		goto create_err;
-	}
-
 	lock_sock(sk);
-	err = __mptcp_subflow_connect(sk, &entry, &addr_r);
+	err = userspace_pm_subflow_create(msk, &entry, &addr_r);
 	release_sock(sk);
-
-	spin_lock_bh(&msk->pm.lock);
 	if (err)
-		mptcp_userspace_pm_delete_local_addr(msk, &entry);
-	else
-		msk->pm.subflows++;
-	spin_unlock_bh(&msk->pm.lock);
+		GENL_SET_ERR_MSG(info, "subflow_create failed");
 
  create_err:
 	sock_put(sk);
@@ -453,6 +474,46 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
 	return NULL;
 }
 
+static int userspace_pm_subflow_destroy(struct mptcp_sock *msk,
+					struct mptcp_pm_addr_entry *local,
+					struct mptcp_addr_info *remote)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct sock *ssk;
+	int err = -ESRCH;
+
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	if (local->addr.family == AF_INET && ipv6_addr_v4mapped(&remote->addr6)) {
+		ipv6_addr_set_v4mapped(local->addr.addr.s_addr, &remote->addr6);
+		local->addr.family = AF_INET6;
+	}
+	if (remote->family == AF_INET && ipv6_addr_v4mapped(&local->addr.addr6)) {
+		ipv6_addr_set_v4mapped(remote->addr.s_addr, &local->addr.addr6);
+		remote->family = AF_INET6;
+	}
+#endif
+	if (local->addr.family != remote->family)
+		return -EINVAL;
+
+	if (!local->addr.port || !remote->port)
+		return -EINVAL;
+
+	ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
+	if (ssk) {
+		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+
+		spin_lock_bh(&msk->pm.lock);
+		mptcp_userspace_pm_delete_local_addr(msk, local);
+		spin_unlock_bh(&msk->pm.lock);
+		mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
+		mptcp_close_ssk(sk, ssk, subflow);
+		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
+		err = 0;
+	}
+
+	return err;
+}
+
 int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
@@ -460,8 +521,8 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 	struct mptcp_pm_addr_entry local;
 	struct mptcp_addr_info addr_r;
 	struct mptcp_sock *msk;
-	struct sock *sk, *ssk;
 	int err = -EINVAL;
+	struct sock *sk;
 
 	if (!laddr || !raddr) {
 		GENL_SET_ERR_MSG(info, "missing required inputs");
@@ -486,78 +547,35 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 		goto destroy_err;
 	}
 
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	if (local.addr.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) {
-		ipv6_addr_set_v4mapped(local.addr.addr.s_addr, &local.addr.addr6);
-		local.addr.family = AF_INET6;
-	}
-	if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&local.addr.addr6)) {
-		ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &local.addr.addr6);
-		addr_r.family = AF_INET6;
-	}
-#endif
-	if (local.addr.family != addr_r.family) {
-		GENL_SET_ERR_MSG(info, "address families do not match");
-		err = -EINVAL;
-		goto destroy_err;
-	}
-
-	if (!local.addr.port || !addr_r.port) {
-		GENL_SET_ERR_MSG(info, "missing local or remote port");
-		err = -EINVAL;
-		goto destroy_err;
-	}
-
 	lock_sock(sk);
-	ssk = mptcp_nl_find_ssk(msk, &local.addr, &addr_r);
-	if (ssk) {
-		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
-
-		spin_lock_bh(&msk->pm.lock);
-		mptcp_userspace_pm_delete_local_addr(msk, &local);
-		spin_unlock_bh(&msk->pm.lock);
-		mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
-		mptcp_close_ssk(sk, ssk, subflow);
-		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
-		err = 0;
-	} else {
-		err = -ESRCH;
-	}
+	err = userspace_pm_subflow_destroy(msk, &local, &addr_r);
 	release_sock(sk);
+	if (err)
+		GENL_SET_ERR_MSG(info, "subflow_destroy failed");
 
 destroy_err:
 	sock_put(sk);
 	return err;
 }
 
-int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
-				 struct mptcp_addr_info *rem,
-				 struct genl_info *info)
+static int userspace_pm_set_flags(struct mptcp_sock *msk,
+				  struct mptcp_pm_addr_entry *local,
+				  struct mptcp_addr_info *remote)
 {
 	struct mptcp_pm_addr_entry *entry;
-	struct mptcp_sock *msk;
-	int ret = -EINVAL;
-	struct sock *sk;
 	u8 bkup = 0;
 
-	msk = mptcp_userspace_pm_get_sock(info);
-	if (!msk)
-		return ret;
-
-	sk = (struct sock *)msk;
-
-	if (loc->addr.family == AF_UNSPEC ||
-	    rem->family == AF_UNSPEC) {
-		GENL_SET_ERR_MSG(info, "invalid address families");
-		ret = -EINVAL;
-		goto set_flags_err;
+	if (local->addr.family == AF_UNSPEC ||
+	    remote->family == AF_UNSPEC) {
+		pr_debug("invalid address families\n");
+		return -EINVAL;
 	}
 
-	if (loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+	if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
 		bkup = 1;
 
 	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_userspace_pm_lookup_addr(msk, &loc->addr);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
 	if (entry) {
 		if (bkup)
 			entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
@@ -566,11 +584,29 @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
 	}
 	spin_unlock_bh(&msk->pm.lock);
 
+	return mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, remote, bkup);
+}
+
+int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_addr_info *rem,
+				 struct genl_info *info)
+{
+	struct mptcp_sock *msk;
+	int ret = -EINVAL;
+	struct sock *sk;
+
+	msk = mptcp_userspace_pm_get_sock(info);
+	if (!msk)
+		return ret;
+
+	sk = (struct sock *)msk;
+
 	lock_sock(sk);
-	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, rem, bkup);
+	ret = userspace_pm_set_flags(msk, loc, rem);
 	release_sock(sk);
+	if (ret)
+		GENL_SET_ERR_MSG(info, "set_flags failed");
 
-set_flags_err:
 	sock_put(sk);
 	return ret;
 }
@@ -590,6 +626,12 @@ static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
 	return 0;
 }
 
+static int userspace_pm_dump_addr(struct mptcp_sock *msk,
+				  struct mptcp_id_bitmap *bitmap)
+{
+	return mptcp_userspace_pm_set_bitmap(msk, bitmap);
+}
+
 int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
 				 const struct genl_info *info)
 {
@@ -605,7 +647,7 @@ int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+	ret = userspace_pm_dump_addr(msk, bitmap);
 	spin_unlock_bh(&msk->pm.lock);
 	release_sock(sk);
 
@@ -613,6 +655,12 @@ int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
 	return ret;
 }
 
+static struct mptcp_pm_addr_entry *
+userspace_pm_get_addr(struct mptcp_sock *msk, u8 id)
+{
+	return mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+}
+
 int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 				const struct genl_info *info)
 {
@@ -629,7 +677,7 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+	entry = userspace_pm_get_addr(msk, id);
 	if (entry) {
 		*addr = *entry;
 		ret = 0;
-- 
2.45.2


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

* [PATCH mptcp-next v2 31/36] mptcp: register default userspace pm
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (29 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 30/36] mptcp: implement userspace pm interfaces Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 32/36] bpf: Add mptcp path manager struct_ops Geliang Tang
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch defines the original userspace pm as the default path manager,
named mptcp_userspace_pm, and register it in mptcp_pm_data_init().

Add a struct mptcp_pm_ops pointer "ops" in struct mptcp_pm_data, and two
functions mptcp_init_pm() and mptcp_release_pm(), to set and release this
pointer. mptcp_init_pm() is invoked in mptcp_pm_data_reset(), while
mptcp_release_pm() is invoked in __mptcp_destroy_sock().

In this way, different userspace path managers can be initialized through
the pm_type sysctl, and then called into their respective interfaces
through "ops" of "msk->pm".

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm.c           |  8 ++++
 net/mptcp/pm_userspace.c | 88 ++++++++++++++++++++++++++++++++++++----
 net/mptcp/protocol.c     |  1 +
 net/mptcp/protocol.h     |  4 ++
 4 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index c2229e46de1a..57ccb021091c 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -489,6 +489,7 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
 {
 	u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk));
 	struct mptcp_pm_data *pm = &msk->pm;
+	int ret;
 
 	pm->add_addr_signaled = 0;
 	pm->add_addr_accepted = 0;
@@ -516,6 +517,12 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
 		WRITE_ONCE(pm->work_pending, 0);
 		WRITE_ONCE(pm->accept_addr, 0);
 		WRITE_ONCE(pm->accept_subflow, 0);
+
+		rcu_read_lock();
+		ret = mptcp_init_pm(msk, mptcp_pm_find(pm_type));
+		rcu_read_unlock();
+		if (ret)
+			return;
 	}
 
 	WRITE_ONCE(pm->addr_signal, 0);
@@ -535,4 +542,5 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
 void __init mptcp_pm_init(void)
 {
 	mptcp_pm_nl_init();
+	mptcp_userspace_pm_init();
 }
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 54c97d3d05ef..b22077fa1fa6 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -157,7 +157,9 @@ static int userspace_pm_get_local_id(struct mptcp_sock *msk,
 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
 				    struct mptcp_pm_addr_entry *local)
 {
-	return userspace_pm_get_local_id(msk, local);
+	return INDIRECT_CALL_1(msk->pm.ops->get_local_id,
+			       userspace_pm_get_local_id,
+			       msk, local);
 }
 
 static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
@@ -178,7 +180,9 @@ static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
 u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
 				struct mptcp_addr_info *skc)
 {
-	return userspace_pm_get_flags(msk, skc);
+	return INDIRECT_CALL_1(msk->pm.ops->get_flags,
+			       userspace_pm_get_flags,
+			       msk, skc);
 }
 
 static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
@@ -258,7 +262,9 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	lock_sock(sk);
-	err = userspace_pm_address_announce(msk, &addr_val);
+	err = INDIRECT_CALL_1(msk->pm.ops->address_announce,
+			      userspace_pm_address_announce,
+			      msk, &addr_val);
 	release_sock(sk);
 	if (err)
 		GENL_SET_ERR_MSG(info, "address_announce failed");
@@ -344,7 +350,9 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
 	sk = (struct sock *)msk;
 
 	lock_sock(sk);
-	err = userspace_pm_address_remove(msk, id_val);
+	err = INDIRECT_CALL_1(msk->pm.ops->address_remove,
+			      userspace_pm_address_remove,
+			      msk, id_val);
 	release_sock(sk);
 	if (err)
 		GENL_SET_ERR_MSG(info, "address_remove failed");
@@ -416,7 +424,9 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	lock_sock(sk);
-	err = userspace_pm_subflow_create(msk, &entry, &addr_r);
+	err = INDIRECT_CALL_1(msk->pm.ops->subflow_create,
+			      userspace_pm_subflow_create,
+			      msk, &entry, &addr_r);
 	release_sock(sk);
 	if (err)
 		GENL_SET_ERR_MSG(info, "subflow_create failed");
@@ -548,7 +558,9 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
 	}
 
 	lock_sock(sk);
-	err = userspace_pm_subflow_destroy(msk, &local, &addr_r);
+	err = INDIRECT_CALL_1(msk->pm.ops->subflow_destroy,
+			      userspace_pm_subflow_destroy,
+			      msk, &local, &addr_r);
 	release_sock(sk);
 	if (err)
 		GENL_SET_ERR_MSG(info, "subflow_destroy failed");
@@ -602,7 +614,9 @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,
 	sk = (struct sock *)msk;
 
 	lock_sock(sk);
-	ret = userspace_pm_set_flags(msk, loc, rem);
+	ret = INDIRECT_CALL_1(msk->pm.ops->set_flags,
+			      userspace_pm_set_flags,
+			      msk, loc, rem);
 	release_sock(sk);
 	if (ret)
 		GENL_SET_ERR_MSG(info, "set_flags failed");
@@ -647,7 +661,9 @@ int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	ret = userspace_pm_dump_addr(msk, bitmap);
+	ret = INDIRECT_CALL_1(msk->pm.ops->dump_addr,
+			      userspace_pm_dump_addr,
+			      msk, bitmap);
 	spin_unlock_bh(&msk->pm.lock);
 	release_sock(sk);
 
@@ -677,7 +693,9 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 
 	lock_sock(sk);
 	spin_lock_bh(&msk->pm.lock);
-	entry = userspace_pm_get_addr(msk, id);
+	entry = INDIRECT_CALL_1(msk->pm.ops->get_addr,
+				userspace_pm_get_addr,
+				msk, id);
 	if (entry) {
 		*addr = *entry;
 		ret = 0;
@@ -689,6 +707,20 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
 	return ret;
 }
 
+static struct mptcp_pm_ops mptcp_userspace_pm = {
+	.address_announce	= userspace_pm_address_announce,
+	.address_remove		= userspace_pm_address_remove,
+	.subflow_create		= userspace_pm_subflow_create,
+	.subflow_destroy	= userspace_pm_subflow_destroy,
+	.get_local_id		= userspace_pm_get_local_id,
+	.get_flags		= userspace_pm_get_flags,
+	.get_addr		= userspace_pm_get_addr,
+	.dump_addr		= userspace_pm_dump_addr,
+	.set_flags		= userspace_pm_set_flags,
+	.type			= MPTCP_PM_TYPE_USERSPACE,
+	.owner			= THIS_MODULE,
+};
+
 /* Must be called with rcu read lock held */
 struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type)
 {
@@ -737,7 +769,45 @@ int mptcp_register_path_manager(struct mptcp_pm_ops *pm)
 
 void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm)
 {
+	if (pm == &mptcp_userspace_pm)
+		return;
+
 	spin_lock(&mptcp_pm_list_lock);
 	list_del_rcu(&pm->list);
 	spin_unlock(&mptcp_pm_list_lock);
 }
+
+int mptcp_init_pm(struct mptcp_sock *msk, struct mptcp_pm_ops *pm)
+{
+	if (!pm)
+		pm = &mptcp_userspace_pm;
+
+	if (!bpf_try_module_get(pm, pm->owner))
+		return -EBUSY;
+
+	msk->pm.ops = pm;
+	if (msk->pm.ops->init)
+		msk->pm.ops->init(msk);
+
+	pr_debug("userspace_pm type %u initialized\n", msk->pm.ops->type);
+	return 0;
+}
+
+void mptcp_release_pm(struct mptcp_sock *msk)
+{
+	struct mptcp_pm_ops *pm = msk->pm.ops;
+
+	if (!pm)
+		return;
+
+	msk->pm.ops = NULL;
+	if (pm->release)
+		pm->release(msk);
+
+	bpf_module_put(pm, pm->owner);
+}
+
+void __init mptcp_userspace_pm_init(void)
+{
+	mptcp_register_path_manager(&mptcp_userspace_pm);
+}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 21bc3586c33e..de6f93cffaaa 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3040,6 +3040,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
 	sk_stop_timer(sk, &sk->sk_timer);
 	msk->pm.status = 0;
 	mptcp_release_sched(msk);
+	mptcp_release_pm(msk);
 
 	sk->sk_prot->destroy(sk);
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index d6c9ca292bff..26950be3b37c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -220,6 +220,7 @@ struct mptcp_pm_data {
 	struct mptcp_addr_info remote;
 	struct list_head anno_list;
 	struct list_head userspace_pm_local_addr_list;
+	struct mptcp_pm_ops *ops;
 
 	spinlock_t	lock;		/*protects the whole PM data */
 
@@ -1058,6 +1059,8 @@ struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type);
 int mptcp_validate_path_manager(struct mptcp_pm_ops *pm);
 int mptcp_register_path_manager(struct mptcp_pm_ops *pm);
 void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm);
+int mptcp_init_pm(struct mptcp_sock *msk, struct mptcp_pm_ops *pm);
+void mptcp_release_pm(struct mptcp_sock *msk);
 
 void mptcp_free_local_addr_list(struct mptcp_sock *msk);
 
@@ -1157,6 +1160,7 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
 }
 
 void __init mptcp_pm_nl_init(void);
+void __init mptcp_userspace_pm_init(void);
 void mptcp_pm_nl_work(struct mptcp_sock *msk);
 unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
 unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
-- 
2.45.2


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

* [PATCH mptcp-next v2 32/36] bpf: Add mptcp path manager struct_ops
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (30 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 31/36] mptcp: register default userspace pm Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 33/36] bpf: Register mptcp struct_ops kfunc set Geliang Tang
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch implements a new struct bpf_struct_ops for MPTCP BPF path
manager: bpf_mptcp_pm_ops. Register and unregister the bpf path manager
in .reg and .unreg.

Add write access for some fields of struct mptcp_addr_info, struct
mptcp_pm_addr_entry and struct mptcp_sock in .btf_struct_access.

This MPTCP BPF path manager implementation is similar to BPF TCP CC. And
net/ipv4/bpf_tcp_ca.c is a frame of reference for this patch.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/bpf.c      | 260 ++++++++++++++++++++++++++++++++++++++++++-
 net/mptcp/protocol.h |   3 +-
 2 files changed, 260 insertions(+), 3 deletions(-)

diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
index 057017d3f5c0..89ff8d5b55bb 100644
--- a/net/mptcp/bpf.c
+++ b/net/mptcp/bpf.c
@@ -17,9 +17,264 @@
 #include "protocol.h"
 
 #ifdef CONFIG_BPF_JIT
-static struct bpf_struct_ops bpf_mptcp_sched_ops;
+static struct bpf_struct_ops bpf_mptcp_pm_ops,
+			     bpf_mptcp_sched_ops;
 static const struct btf_type *mptcp_sock_type, *mptcp_subflow_type __read_mostly;
-static u32 mptcp_sock_id, mptcp_subflow_id;
+static u32 mptcp_sock_id, mptcp_entry_id, mptcp_addr_id, mptcp_subflow_id;
+
+/* MPTCP BPF path manager */
+
+static const struct bpf_func_proto *
+bpf_mptcp_pm_get_func_proto(enum bpf_func_id func_id,
+			    const struct bpf_prog *prog)
+{
+	switch (func_id) {
+	case BPF_FUNC_sk_storage_get:
+		return &bpf_sk_storage_get_proto;
+	case BPF_FUNC_sk_storage_delete:
+		return &bpf_sk_storage_delete_proto;
+	default:
+		return bpf_base_func_proto(func_id, prog);
+	}
+}
+
+static int bpf_mptcp_pm_btf_struct_access(struct bpf_verifier_log *log,
+					  const struct bpf_reg_state *reg,
+					  int off, int size)
+{
+	u32 id = reg->btf_id;
+	size_t end;
+
+	if (id == mptcp_sock_id) {
+		switch (off) {
+		case offsetof(struct mptcp_sock, pm.add_addr_signaled):
+			end = offsetofend(struct mptcp_sock, pm.add_addr_signaled);
+			break;
+		case offsetof(struct mptcp_sock, pm.local_addr_used):
+			end = offsetofend(struct mptcp_sock, pm.local_addr_used);
+			break;
+		case offsetof(struct mptcp_sock, pm.subflows):
+			end = offsetofend(struct mptcp_sock, pm.subflows);
+			break;
+		default:
+			bpf_log(log, "no write support to mptcp_sock at off %d\n",
+				off);
+			return -EACCES;
+		}
+	} else if (id == mptcp_entry_id) {
+		switch (off) {
+		case offsetof(struct mptcp_pm_addr_entry, addr.id):
+			end = offsetofend(struct mptcp_pm_addr_entry, addr.id);
+			break;
+		case offsetof(struct mptcp_pm_addr_entry, addr.family):
+			end = offsetofend(struct mptcp_pm_addr_entry, addr.family);
+			break;
+		case offsetof(struct mptcp_pm_addr_entry, addr.port):
+			end = offsetofend(struct mptcp_pm_addr_entry, addr.port);
+			break;
+		case offsetof(struct mptcp_pm_addr_entry, flags):
+			end = offsetofend(struct mptcp_pm_addr_entry, flags);
+			break;
+		default:
+			bpf_log(log, "no write support to mptcp_pm_addr_entry at off %d\n",
+				off);
+			return -EACCES;
+		}
+	} else if (id == mptcp_addr_id) {
+		switch (off) {
+		case offsetof(struct mptcp_addr_info, id):
+			end = offsetofend(struct mptcp_addr_info, id);
+			break;
+		case offsetof(struct mptcp_addr_info, family):
+			end = offsetofend(struct mptcp_addr_info, family);
+			break;
+		case offsetof(struct mptcp_addr_info, port):
+			end = offsetofend(struct mptcp_addr_info, port);
+			break;
+		default:
+			bpf_log(log, "no write support to mptcp_addr_info at off %d\n",
+				off);
+			return -EACCES;
+		}
+	} else {
+		bpf_log(log, "only access to mptcp sock or addr or entry is supported\n");
+		return -EACCES;
+	}
+
+	if (off + size > end) {
+		bpf_log(log, "access beyond %s at off %u size %u ended at %zu",
+			id == mptcp_sock_id ? "mptcp_sock" :
+			(id == mptcp_entry_id ? "mptcp_pm_addr_entry" : "mptcp_addr_info"),
+			off, size, end);
+		return -EACCES;
+	}
+
+	return NOT_INIT;
+}
+
+static const struct bpf_verifier_ops bpf_mptcp_pm_verifier_ops = {
+	.get_func_proto		= bpf_mptcp_pm_get_func_proto,
+	.is_valid_access	= bpf_tracing_btf_ctx_access,
+	.btf_struct_access	= bpf_mptcp_pm_btf_struct_access,
+};
+
+static int bpf_mptcp_pm_reg(void *kdata, struct bpf_link *link)
+{
+	return mptcp_register_path_manager(kdata);
+}
+
+static void bpf_mptcp_pm_unreg(void *kdata, struct bpf_link *link)
+{
+	mptcp_unregister_path_manager(kdata);
+}
+
+static int bpf_mptcp_pm_check_member(const struct btf_type *t,
+				     const struct btf_member *member,
+				     const struct bpf_prog *prog)
+{
+	return 0;
+}
+
+static int bpf_mptcp_pm_init_member(const struct btf_type *t,
+				    const struct btf_member *member,
+				    void *kdata, const void *udata)
+{
+	const struct mptcp_pm_ops *upm;
+	struct mptcp_pm_ops *pm;
+	u32 moff;
+
+	upm = (const struct mptcp_pm_ops *)udata;
+	pm = (struct mptcp_pm_ops *)kdata;
+
+	moff = __btf_member_bit_offset(t, member) / 8;
+	switch (moff) {
+	case offsetof(struct mptcp_pm_ops, type):
+		pm->type = upm->type;
+		return 1;
+	}
+
+	return 0;
+}
+
+static int bpf_mptcp_pm_init(struct btf *btf)
+{
+	s32 type_id;
+
+	type_id = btf_find_by_name_kind(btf, "mptcp_sock",
+					BTF_KIND_STRUCT);
+	if (type_id < 0)
+		return -EINVAL;
+	mptcp_sock_id = type_id;
+
+	type_id = btf_find_by_name_kind(btf, "mptcp_pm_addr_entry",
+					BTF_KIND_STRUCT);
+	if (type_id < 0)
+		return -EINVAL;
+	mptcp_entry_id = type_id;
+
+	type_id = btf_find_by_name_kind(btf, "mptcp_addr_info",
+					BTF_KIND_STRUCT);
+	if (type_id < 0)
+		return -EINVAL;
+	mptcp_addr_id = type_id;
+
+	return 0;
+}
+
+static int bpf_mptcp_pm_validate(void *kdata)
+{
+	return mptcp_validate_path_manager(kdata);
+}
+
+static int __bpf_mptcp_pm_address_announce(struct mptcp_sock *msk,
+					   struct mptcp_pm_addr_entry *addr)
+{
+	return 0;
+}
+
+static int __bpf_mptcp_pm_address_remove(struct mptcp_sock *msk, u8 id)
+{
+	return 0;
+}
+
+static int __bpf_mptcp_pm_subflow_create(struct mptcp_sock *msk,
+					 struct mptcp_pm_addr_entry *entry,
+					 struct mptcp_addr_info *addr)
+{
+	return 0;
+}
+
+static int __bpf_mptcp_pm_subflow_destroy(struct mptcp_sock *msk,
+					  struct mptcp_pm_addr_entry *local,
+					  struct mptcp_addr_info *remote)
+{
+	return 0;
+}
+
+static int __bpf_mptcp_pm_get_local_id(struct mptcp_sock *msk,
+				       struct mptcp_pm_addr_entry *local)
+{
+	return 0;
+}
+
+static u8 __bpf_mptcp_pm_get_flags(struct mptcp_sock *msk,
+				   struct mptcp_addr_info *skc)
+{
+	return 0;
+}
+
+static struct mptcp_pm_addr_entry *
+__bpf_mptcp_pm_get_addr(struct mptcp_sock *msk, u8 id)
+{
+	return NULL;
+}
+
+static int __bpf_mptcp_pm_dump_addr(struct mptcp_sock *msk,
+				    struct mptcp_id_bitmap *bitmap)
+{
+	return 0;
+}
+
+static int __bpf_mptcp_pm_set_flags(struct mptcp_sock *msk,
+				    struct mptcp_pm_addr_entry *local,
+				    struct mptcp_addr_info *remote)
+{
+	return 0;
+}
+
+static void __bpf_mptcp_pm_init(struct mptcp_sock *msk)
+{
+}
+
+static void __bpf_mptcp_pm_release(struct mptcp_sock *msk)
+{
+}
+
+static struct mptcp_pm_ops __bpf_mptcp_pm_ops = {
+	.address_announce	= __bpf_mptcp_pm_address_announce,
+	.address_remove		= __bpf_mptcp_pm_address_remove,
+	.subflow_create		= __bpf_mptcp_pm_subflow_create,
+	.subflow_destroy	= __bpf_mptcp_pm_subflow_destroy,
+	.get_local_id		= __bpf_mptcp_pm_get_local_id,
+	.get_flags		= __bpf_mptcp_pm_get_flags,
+	.get_addr		= __bpf_mptcp_pm_get_addr,
+	.dump_addr		= __bpf_mptcp_pm_dump_addr,
+	.set_flags		= __bpf_mptcp_pm_set_flags,
+	.init			= __bpf_mptcp_pm_init,
+	.release		= __bpf_mptcp_pm_release,
+};
+
+static struct bpf_struct_ops bpf_mptcp_pm_ops = {
+	.verifier_ops	= &bpf_mptcp_pm_verifier_ops,
+	.reg		= bpf_mptcp_pm_reg,
+	.unreg		= bpf_mptcp_pm_unreg,
+	.check_member	= bpf_mptcp_pm_check_member,
+	.init_member	= bpf_mptcp_pm_init_member,
+	.init		= bpf_mptcp_pm_init,
+	.validate	= bpf_mptcp_pm_validate,
+	.name		= "mptcp_pm_ops",
+	.cfi_stubs	= &__bpf_mptcp_pm_ops,
+};
 
 static const struct bpf_func_proto *
 bpf_mptcp_sched_get_func_proto(enum bpf_func_id func_id,
@@ -406,6 +661,7 @@ static int __init bpf_mptcp_kfunc_init(void)
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
 					       &bpf_mptcp_sched_kfunc_set);
 #ifdef CONFIG_BPF_JIT
+	ret = ret ?: register_bpf_struct_ops(&bpf_mptcp_pm_ops, mptcp_pm_ops);
 	ret = ret ?: register_bpf_struct_ops(&bpf_mptcp_sched_ops, mptcp_sched_ops);
 #endif
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 26950be3b37c..b8ce6507be49 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -194,6 +194,7 @@ enum mptcp_pm_status {
 enum mptcp_pm_type {
 	MPTCP_PM_TYPE_KERNEL = 0,
 	MPTCP_PM_TYPE_USERSPACE,
+	MPTCP_PM_TYPE_BPF,
 
 	__MPTCP_PM_TYPE_NR,
 	__MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1,
@@ -1102,7 +1103,7 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
 
 static inline bool mptcp_pm_is_userspace(const struct mptcp_sock *msk)
 {
-	return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_USERSPACE;
+	return READ_ONCE(msk->pm.pm_type);
 }
 
 static inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk)
-- 
2.45.2


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

* [PATCH mptcp-next v2 33/36] bpf: Register mptcp struct_ops kfunc set
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (31 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 32/36] bpf: Add mptcp path manager struct_ops Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 34/36] Squash to "bpf: Export mptcp packet scheduler helpers" Geliang Tang
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch exports mptcp path manager helpers into BPF, adds these
kfunc names into struct_ops kfunc_set and register this set with
BPF_PROG_TYPE_STRUCT_OPS type.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/bpf.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
index 89ff8d5b55bb..8ce3a48c27e5 100644
--- a/net/mptcp/bpf.c
+++ b/net/mptcp/bpf.c
@@ -598,6 +598,91 @@ __bpf_kfunc static bool bpf_ipv6_addr_v4mapped(const struct mptcp_addr_info *a)
 	return false;
 }
 
+__bpf_kfunc static void bpf_list_add_tail_rcu(struct list_head *new,
+					      struct list_head *head)
+{
+	list_add_tail_rcu(new, head);
+}
+
+__bpf_kfunc static void bpf_list_del_rcu(struct list_head *entry)
+{
+	list_del_rcu(entry);
+}
+
+__bpf_kfunc static struct mptcp_pm_addr_entry *
+bpf_pm_alloc_entry(struct sock *sk, struct mptcp_pm_addr_entry *entry)
+{
+	struct mptcp_pm_addr_entry *e;
+
+	e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
+	if (!e)
+		return NULL;
+	*e = *entry;
+
+	return e;
+}
+
+__bpf_kfunc static void bpf_pm_free_entry(struct sock *sk,
+					  struct mptcp_pm_addr_entry *entry)
+{
+	sock_kfree_s(sk, entry, sizeof(*entry));
+}
+
+__bpf_kfunc static bool bpf_mptcp_addresses_equal(const struct mptcp_addr_info *a,
+						  const struct mptcp_addr_info *b, bool use_port)
+{
+	return mptcp_addresses_equal(a, b, use_port);
+}
+
+__bpf_kfunc static void bpf_bitmap_zero(struct mptcp_id_bitmap *bitmap)
+{
+	bitmap_zero(bitmap->map, MPTCP_PM_MAX_ADDR_ID + 1);
+}
+
+__bpf_kfunc static bool bpf_test_bit(__u8 id, struct mptcp_id_bitmap *bitmap)
+{
+	return test_bit(id, bitmap->map);
+}
+
+__bpf_kfunc static void bpf_set_bit(__u8 id, struct mptcp_id_bitmap *bitmap)
+{
+	__set_bit(id, bitmap->map);
+}
+
+__bpf_kfunc static __u8 bpf_next_bit(struct mptcp_id_bitmap *bitmap)
+{
+	return find_next_zero_bit(bitmap->map, MPTCP_PM_MAX_ADDR_ID + 1, 1);
+}
+
+__bpf_kfunc static bool bpf_mptcp_pm_addr_families_match(const struct sock *sk,
+							 const struct mptcp_addr_info *loc,
+							 const struct mptcp_addr_info *rem)
+{
+	return mptcp_pm_addr_families_match(sk, loc, rem);
+}
+
+__bpf_kfunc static struct ipv6_pinfo *bpf_inet6_sk(const struct sock *sk)
+{
+	return inet6_sk(sk);
+}
+
+__bpf_kfunc static bool bpf_ipv6_addr_equal(const struct mptcp_addr_info *a1,
+					    const struct in6_addr *a2)
+{
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	return ipv6_addr_equal(&a1->addr6, a2);
+#endif
+	return false;
+}
+
+__bpf_kfunc static void bpf_ipv6_addr_set_v4mapped(const __be32 addr,
+						   struct mptcp_addr_info *v4mapped)
+{
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	ipv6_addr_set_v4mapped(addr, &v4mapped->addr6);
+#endif
+}
+
 __bpf_kfunc struct mptcp_subflow_context *
 bpf_mptcp_subflow_ctx_by_pos(const struct mptcp_sched_data *data, unsigned int pos)
 {
@@ -635,6 +720,36 @@ static const struct btf_kfunc_id_set bpf_mptcp_common_kfunc_set = {
 	.set	= &bpf_mptcp_common_kfunc_ids,
 };
 
+BTF_KFUNCS_START(bpf_mptcp_struct_ops_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_list_add_tail_rcu)
+BTF_ID_FLAGS(func, bpf_list_del_rcu)
+BTF_ID_FLAGS(func, bpf_pm_alloc_entry)
+BTF_ID_FLAGS(func, bpf_pm_free_entry)
+BTF_ID_FLAGS(func, mptcp_pm_alloc_anno_list)
+BTF_ID_FLAGS(func, mptcp_pm_announce_addr)
+BTF_ID_FLAGS(func, mptcp_pm_nl_addr_send_ack, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_mptcp_addresses_equal)
+BTF_ID_FLAGS(func, bpf_bitmap_zero)
+BTF_ID_FLAGS(func, bpf_test_bit)
+BTF_ID_FLAGS(func, bpf_set_bit)
+BTF_ID_FLAGS(func, bpf_next_bit)
+BTF_ID_FLAGS(func, bpf_mptcp_pm_addr_families_match)
+BTF_ID_FLAGS(func, bpf_inet6_sk)
+BTF_ID_FLAGS(func, bpf_ipv6_addr_equal)
+BTF_ID_FLAGS(func, bpf_ipv6_addr_set_v4mapped)
+BTF_ID_FLAGS(func, mptcp_pm_remove_addr)
+BTF_ID_FLAGS(func, mptcp_pm_remove_addr_entry, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, __mptcp_subflow_connect, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, mptcp_subflow_shutdown, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, mptcp_close_ssk, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, mptcp_pm_nl_mp_prio_send_ack, KF_SLEEPABLE)
+BTF_KFUNCS_END(bpf_mptcp_struct_ops_kfunc_ids)
+
+static const struct btf_kfunc_id_set bpf_mptcp_struct_ops_kfunc_set = {
+	.owner	= THIS_MODULE,
+	.set	= &bpf_mptcp_struct_ops_kfunc_ids,
+};
+
 BTF_KFUNCS_START(bpf_mptcp_sched_kfunc_ids)
 BTF_ID_FLAGS(func, mptcp_subflow_set_scheduled)
 BTF_ID_FLAGS(func, bpf_mptcp_subflow_ctx_by_pos)
@@ -658,6 +773,8 @@ static int __init bpf_mptcp_kfunc_init(void)
 	ret = register_btf_fmodret_id_set(&bpf_mptcp_fmodret_set);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_UNSPEC,
 					       &bpf_mptcp_common_kfunc_set);
+	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
+					       &bpf_mptcp_struct_ops_kfunc_set);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
 					       &bpf_mptcp_sched_kfunc_set);
 #ifdef CONFIG_BPF_JIT
-- 
2.45.2


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

* [PATCH mptcp-next v2 34/36] Squash to "bpf: Export mptcp packet scheduler helpers"
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (32 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 33/36] bpf: Register mptcp struct_ops kfunc set Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 35/36] selftests/bpf: Add mptcp userspace pm subtest Geliang Tang
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

bpf_mptcp_struct_ops_kfunc_set has been added, no need to add a new one.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/bpf.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
index 8ce3a48c27e5..2583a6af6628 100644
--- a/net/mptcp/bpf.c
+++ b/net/mptcp/bpf.c
@@ -743,14 +743,6 @@ BTF_ID_FLAGS(func, __mptcp_subflow_connect, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, mptcp_subflow_shutdown, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, mptcp_close_ssk, KF_SLEEPABLE)
 BTF_ID_FLAGS(func, mptcp_pm_nl_mp_prio_send_ack, KF_SLEEPABLE)
-BTF_KFUNCS_END(bpf_mptcp_struct_ops_kfunc_ids)
-
-static const struct btf_kfunc_id_set bpf_mptcp_struct_ops_kfunc_set = {
-	.owner	= THIS_MODULE,
-	.set	= &bpf_mptcp_struct_ops_kfunc_ids,
-};
-
-BTF_KFUNCS_START(bpf_mptcp_sched_kfunc_ids)
 BTF_ID_FLAGS(func, mptcp_subflow_set_scheduled)
 BTF_ID_FLAGS(func, bpf_mptcp_subflow_ctx_by_pos)
 BTF_ID_FLAGS(func, mptcp_subflow_active)
@@ -759,11 +751,11 @@ BTF_ID_FLAGS(func, mptcp_wnd_end)
 BTF_ID_FLAGS(func, tcp_stream_memory_free)
 BTF_ID_FLAGS(func, bpf_mptcp_subflow_queues_empty)
 BTF_ID_FLAGS(func, mptcp_pm_subflow_chk_stale)
-BTF_KFUNCS_END(bpf_mptcp_sched_kfunc_ids)
+BTF_KFUNCS_END(bpf_mptcp_struct_ops_kfunc_ids)
 
-static const struct btf_kfunc_id_set bpf_mptcp_sched_kfunc_set = {
+static const struct btf_kfunc_id_set bpf_mptcp_struct_ops_kfunc_set = {
 	.owner	= THIS_MODULE,
-	.set	= &bpf_mptcp_sched_kfunc_ids,
+	.set	= &bpf_mptcp_struct_ops_kfunc_ids,
 };
 
 static int __init bpf_mptcp_kfunc_init(void)
@@ -775,8 +767,6 @@ static int __init bpf_mptcp_kfunc_init(void)
 					       &bpf_mptcp_common_kfunc_set);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
 					       &bpf_mptcp_struct_ops_kfunc_set);
-	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
-					       &bpf_mptcp_sched_kfunc_set);
 #ifdef CONFIG_BPF_JIT
 	ret = ret ?: register_bpf_struct_ops(&bpf_mptcp_pm_ops, mptcp_pm_ops);
 	ret = ret ?: register_bpf_struct_ops(&bpf_mptcp_sched_ops, mptcp_sched_ops);
-- 
2.45.2


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

* [PATCH mptcp-next v2 35/36] selftests/bpf: Add mptcp userspace pm subtest
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (33 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 34/36] Squash to "bpf: Export mptcp packet scheduler helpers" Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22  9:14 ` [PATCH mptcp-next v2 36/36] selftests/bpf: Add mptcp bpf path manager subtest Geliang Tang
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

To verify that the behavior of BPF path manager is the same as that of
userspace pm in the kernel, a userspace pm self-test has been added.
BPF path manager in the next commit will also use this test.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../testing/selftests/bpf/prog_tests/mptcp.c  | 244 ++++++++++++++++++
 1 file changed, 244 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 73bfd177dc04..2e8f4e458430 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -66,6 +66,12 @@ enum mptcp_pm_type {
 	__MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1,
 };
 
+enum mptcp_pm_family {
+	IPV4 = 0,
+	IPV6,
+	IPV4MAPPED,
+};
+
 static const unsigned int total_bytes = 10 * 1024 * 1024;
 static int duration;
 
@@ -797,6 +803,242 @@ static void test_iters_address(void)
 	close(cgroup_fd);
 }
 
+static int userspace_pm_add_addr(__u32 token, char *addr, __u8 id)
+{
+	return SYS_NOFAIL("ip netns exec %s %s ann %s id %u token %u",
+			  NS_TEST, PM_CTL, addr, id, token);
+}
+
+static int userspace_pm_get_addr(__u32 token, __u8 id, char *output)
+{
+	char cmd[1024];
+	FILE *fp;
+
+	sprintf(cmd, "ip netns exec %s %s get %u token %u",
+		NS_TEST, PM_CTL, id, token);
+	fp = popen(cmd, "r");
+	if (!fp)
+		return -1;
+
+	bzero(output, BUFSIZ);
+	fread(output, 1, BUFSIZ, fp);
+	pclose(fp);
+
+	return 0;
+}
+
+static int userspace_pm_dump_addr(__u32 token, char *output)
+{
+	char cmd[1024];
+	FILE *fp;
+
+	sprintf(cmd, "ip netns exec %s %s dump token %u",
+		NS_TEST, PM_CTL, token);
+	fp = popen(cmd, "r");
+	if (!fp)
+		return -1;
+
+	bzero(output, BUFSIZ);
+	fread(output, 1, BUFSIZ, fp);
+	pclose(fp);
+
+	return 0;
+}
+
+static int userspace_pm_set_flags(__u32 token, char *addr, char *flags)
+{
+	bool ipv6 = strstr(addr, ":");
+	char line[1024], *str;
+	__u32 sport, dport;
+
+	if (userspace_pm_get_events_line("type:10", line))
+		return -1;
+
+	str = strstr(line, "sport");
+	if (!str || sscanf(str, "sport:%u,dport:%u,", &sport, &dport) != 2) {
+		log_err("set_flags error, str=%s\n", str);
+		return -1;
+	}
+
+	str = ipv6 ? (strstr(addr, ".") ? "::ffff:"ADDR_1 : ADDR6_1) : ADDR_1;
+	return SYS_NOFAIL("ip netns exec %s %s set %s port %u rip %s rport %u flags %s token %u",
+			  NS_TEST, PM_CTL, addr, sport, str, dport, flags, token);
+}
+
+static int userspace_pm_rm_subflow(__u32 token, char *addr, __u8 id)
+{
+	bool ipv6 = strstr(addr, ":");
+	char line[1024], *str;
+	__u32 sport, dport;
+
+	if (userspace_pm_get_events_line("type:10", line))
+		return -1;
+
+	str = strstr(line, "sport");
+	if (!str || sscanf(str, "sport:%u,dport:%u,", &sport, &dport) != 2) {
+		log_err("rm_subflow error, str=%s\n", str);
+		return -1;
+	}
+
+	str = ipv6 ? (strstr(addr, ".") ? "::ffff:"ADDR_1 : ADDR6_1) : ADDR_1;
+	return SYS_NOFAIL("ip netns exec %s %s dsf lip %s lport %u rip %s rport %u token %u",
+			  NS_TEST, PM_CTL, addr, sport, str, dport, token);
+}
+
+static int userspace_pm_rm_addr(__u32 token, __u8 id)
+{
+	return SYS_NOFAIL("ip netns exec %s %s rem id %u token %u",
+			  NS_TEST, PM_CTL, id, token);
+}
+
+static void run_userspace_pm(enum mptcp_pm_family family)
+{
+	bool ipv6 = (family == IPV6 || family == IPV4MAPPED);
+	bool ipv4mapped = (family == IPV4MAPPED);
+	int server_fd, client_fd, accept_fd;
+	char output[BUFSIZ], expect[1024];
+	__u32 token;
+	char *addr;
+	int err;
+
+	addr = ipv6 ? (ipv4mapped ? "::ffff:"ADDR_1 : ADDR6_1) : ADDR_1;
+	server_fd = start_mptcp_server(ipv6 ? AF_INET6 : AF_INET, addr, PORT_1, 0);
+	if (!ASSERT_OK_FD(server_fd, "start_mptcp_server"))
+		return;
+
+	client_fd = connect_to_fd(server_fd, 0);
+	if (!ASSERT_OK_FD(client_fd, "connect_to_fd"))
+		goto close_server;
+
+	accept_fd = accept(server_fd, NULL, NULL);
+	if (!ASSERT_OK_FD(accept_fd, "accept"))
+		goto close_client;
+
+	token = userspace_pm_get_token(client_fd);
+	if (!token)
+		goto close_client;
+	recv_byte(accept_fd);
+	usleep(200000); /* 0.2s */
+
+	addr = ipv6 ? (ipv4mapped ? "::ffff:"ADDR_2 : ADDR6_2) : ADDR_2;
+	err = userspace_pm_add_subflow(token, addr, 100);
+	if (!ASSERT_OK(err, "userspace_pm_add_subflow 100"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	sprintf(expect, "id 100 flags subflow %s\n", addr);
+	err = userspace_pm_get_addr(token, 100, output);
+	if (!ASSERT_OK(err, "userspace_pm_get_addr 100") ||
+	    !ASSERT_STRNEQ(output, expect, sizeof(expect), "get_addr"))
+		goto close_accept;
+
+	send_byte(client_fd);
+	recv_byte(accept_fd);
+
+	err = userspace_pm_set_flags(token, addr, "backup");
+	if (!ASSERT_OK(err, "userspace_pm_set_flags backup"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	sprintf(expect, "id 100 flags subflow,backup %s\n", addr);
+	err = userspace_pm_get_addr(token, 100, output);
+	if (!ASSERT_OK(err, "userspace_pm_get_addr 100") ||
+	    !ASSERT_STRNEQ(output, expect, sizeof(expect), "get_addr"))
+		goto close_accept;
+
+	send_byte(client_fd);
+	recv_byte(accept_fd);
+
+	err = userspace_pm_set_flags(token, addr, "nobackup");
+	if (!ASSERT_OK(err, "userspace_pm_set_flags nobackup"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	sprintf(expect, "id 100 flags subflow %s\n", addr);
+	err = userspace_pm_get_addr(token, 100, output);
+	if (!ASSERT_OK(err, "userspace_pm_get_addr 100") ||
+	    !ASSERT_STRNEQ(output, expect, sizeof(expect), "get_addr"))
+		goto close_accept;
+
+	send_byte(client_fd);
+	recv_byte(accept_fd);
+
+	err = userspace_pm_rm_subflow(token, addr, 100);
+	if (!ASSERT_OK(err, "userspace_pm_rm_subflow 100"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	err = userspace_pm_dump_addr(token, output);
+	if (!ASSERT_OK(err, "userspace_pm_dump_addr") ||
+	    !ASSERT_STRNEQ(output, "", sizeof(output), "dump_addr"))
+		goto close_accept;
+
+	send_byte(client_fd);
+	recv_byte(accept_fd);
+
+	addr = ipv6 ? (ipv4mapped ? "::ffff:"ADDR_3 : ADDR6_3) : ADDR_3;
+	err = userspace_pm_add_addr(token, addr, 200);
+	if (!ASSERT_OK(err, "userspace_pm_add_addr 200"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	sprintf(expect, "id 200 flags signal %s\n", addr);
+	err = userspace_pm_dump_addr(token, output);
+	if (!ASSERT_OK(err, "userspace_pm_dump_addr") ||
+	    !ASSERT_STRNEQ(output, expect, sizeof(expect), "dump_addr"))
+		goto close_accept;
+
+	send_byte(client_fd);
+	recv_byte(accept_fd);
+
+	err = userspace_pm_rm_addr(token, 200);
+	if (!ASSERT_OK(err, "userspace_pm_rm_addr 200"))
+		goto close_accept;
+
+	send_byte(accept_fd);
+	recv_byte(client_fd);
+
+	err = userspace_pm_rm_addr(token, 0);
+	ASSERT_OK(err, "userspace_pm_rm_addr 0");
+
+close_accept:
+	close(accept_fd);
+close_client:
+	close(client_fd);
+close_server:
+	close(server_fd);
+}
+
+static void test_userspace_pm(void)
+{
+	struct nstoken *nstoken;
+	int err;
+
+	nstoken = create_netns();
+	if (!ASSERT_OK_PTR(nstoken, "create_netns"))
+		return;
+
+	err = userspace_pm_init(MPTCP_PM_TYPE_USERSPACE);
+	if (!ASSERT_OK(err, "userspace_pm_init: userspace pm"))
+		goto fail;
+
+	run_userspace_pm(IPV4);
+
+	userspace_pm_cleanup();
+fail:
+	cleanup_netns(nstoken);
+}
+
 static struct nstoken *sched_init(char *flags, char *sched)
 {
 	struct nstoken *nstoken;
@@ -982,6 +1224,8 @@ void test_mptcp(void)
 		test_iters_subflow();
 	if (test__start_subtest("iters_address"))
 		test_iters_address();
+	if (test__start_subtest("userspace_pm"))
+		test_userspace_pm();
 	if (test__start_subtest("default"))
 		test_default();
 	if (test__start_subtest("first"))
-- 
2.45.2


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

* [PATCH mptcp-next v2 36/36] selftests/bpf: Add mptcp bpf path manager subtest
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (34 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 35/36] selftests/bpf: Add mptcp userspace pm subtest Geliang Tang
@ 2024-10-22  9:14 ` Geliang Tang
  2024-10-22 10:12 ` [PATCH mptcp-next v2 00/36] BPF path manager MPTCP CI
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-22  9:14 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch adds an mptcp bpf userspace pm example program, implements
address_announce, address_remove, subflow_create, subflow_destroy,
get_local_id, get_flags, get_addr, dump_addr and set_flags interfaces
using almost the same logic as the userspace pm in kernel.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 tools/testing/selftests/bpf/config            |   1 +
 .../testing/selftests/bpf/prog_tests/mptcp.c  |  61 +++
 tools/testing/selftests/bpf/progs/mptcp_bpf.h |  71 +++
 .../bpf/progs/mptcp_bpf_userspace_pm.c        | 409 ++++++++++++++++++
 4 files changed, 542 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c

diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
index 4ca84c8d9116..278d62c4a16b 100644
--- a/tools/testing/selftests/bpf/config
+++ b/tools/testing/selftests/bpf/config
@@ -58,6 +58,7 @@ CONFIG_MPLS=y
 CONFIG_MPLS_IPTUNNEL=y
 CONFIG_MPLS_ROUTING=y
 CONFIG_MPTCP=y
+CONFIG_MPTCP_IPV6=y
 CONFIG_NET_ACT_SKBMOD=y
 CONFIG_NET_CLS=y
 CONFIG_NET_CLS_ACT=y
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 2e8f4e458430..45d6448c2235 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -12,6 +12,7 @@
 #include "mptcpify.skel.h"
 #include "mptcp_subflow.skel.h"
 #include "mptcp_bpf_iters.skel.h"
+#include "mptcp_bpf_userspace_pm.skel.h"
 #include "mptcp_bpf_first.skel.h"
 #include "mptcp_bpf_bkup.skel.h"
 #include "mptcp_bpf_rr.skel.h"
@@ -61,6 +62,7 @@
 enum mptcp_pm_type {
 	MPTCP_PM_TYPE_KERNEL = 0,
 	MPTCP_PM_TYPE_USERSPACE,
+	MPTCP_PM_TYPE_BPF,
 
 	__MPTCP_PM_TYPE_NR,
 	__MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1,
@@ -1039,6 +1041,63 @@ static void test_userspace_pm(void)
 	cleanup_netns(nstoken);
 }
 
+static void test_bpf_pm(void)
+{
+	struct mptcp_bpf_userspace_pm *skel;
+	struct nstoken *nstoken;
+	struct bpf_link *link;
+	int err;
+
+	skel = mptcp_bpf_userspace_pm__open();
+	if (!ASSERT_OK_PTR(skel, "open: userspace_pm"))
+		return;
+
+	if (!ASSERT_OK(bpf_program__set_flags(skel->progs.mptcp_pm_address_announce,
+		BPF_F_SLEEPABLE), "set pm_address_announce sleepable"))
+		goto skel_destroy;
+
+	if (!ASSERT_OK(bpf_program__set_flags(skel->progs.mptcp_pm_address_remove,
+		BPF_F_SLEEPABLE), "set pm_address_remove sleepable"))
+		goto skel_destroy;
+
+	if (!ASSERT_OK(bpf_program__set_flags(skel->progs.mptcp_pm_subflow_create,
+		BPF_F_SLEEPABLE), "set pm_subflow_create sleepable"))
+		goto skel_destroy;
+
+	if (!ASSERT_OK(bpf_program__set_flags(skel->progs.mptcp_pm_subflow_destroy,
+		BPF_F_SLEEPABLE), "set pm_subflow_destroy sleepable"))
+		goto skel_destroy;
+
+	if (!ASSERT_OK(bpf_program__set_flags(skel->progs.mptcp_pm_set_flags,
+		BPF_F_SLEEPABLE), "set pm_set_flags sleepable"))
+		goto skel_destroy;
+
+	if (!ASSERT_OK(mptcp_bpf_userspace_pm__load(skel), "load: userspace_pm"))
+		goto skel_destroy;
+
+	link = bpf_map__attach_struct_ops(skel->maps.userspace_pm);
+	if (!ASSERT_OK_PTR(link, "attach_struct_ops"))
+		goto skel_destroy;
+
+	nstoken = create_netns();
+	if (!ASSERT_OK_PTR(nstoken, "create_netns"))
+		goto link_destroy;
+
+	err = userspace_pm_init(MPTCP_PM_TYPE_BPF);
+	if (!ASSERT_OK(err, "userspace_pm_init: bpf pm"))
+		goto close_netns;
+
+	run_userspace_pm(skel->kconfig->CONFIG_MPTCP_IPV6 ? IPV6 : IPV4);
+
+	userspace_pm_cleanup();
+close_netns:
+	cleanup_netns(nstoken);
+link_destroy:
+	bpf_link__destroy(link);
+skel_destroy:
+	mptcp_bpf_userspace_pm__destroy(skel);
+}
+
 static struct nstoken *sched_init(char *flags, char *sched)
 {
 	struct nstoken *nstoken;
@@ -1226,6 +1285,8 @@ void test_mptcp(void)
 		test_iters_address();
 	if (test__start_subtest("userspace_pm"))
 		test_userspace_pm();
+	if (test__start_subtest("bpf_pm"))
+		test_bpf_pm();
 	if (test__start_subtest("default"))
 		test_default();
 	if (test__start_subtest("first"))
diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf.h b/tools/testing/selftests/bpf/progs/mptcp_bpf.h
index 52bc8ac03508..a8c1d679942a 100644
--- a/tools/testing/selftests/bpf/progs/mptcp_bpf.h
+++ b/tools/testing/selftests/bpf/progs/mptcp_bpf.h
@@ -2,11 +2,30 @@
 #ifndef __MPTCP_BPF_H__
 #define __MPTCP_BPF_H__
 
+#include <string.h>
 #include "bpf_experimental.h"
 
 /* mptcp helpers from include/net/mptcp.h */
 #define MPTCP_SUBFLOWS_MAX 8
 
+extern bool CONFIG_MPTCP_IPV6 __kconfig __weak;
+
+#define MPTCP_PM_ADDR_FLAG_SIGNAL			(1 << 0)
+#define MPTCP_PM_ADDR_FLAG_SUBFLOW			(1 << 1)
+#define MPTCP_PM_ADDR_FLAG_BACKUP			(1 << 2)
+#define MPTCP_PM_ADDR_FLAG_FULLMESH			(1 << 3)
+#define MPTCP_PM_ADDR_FLAG_IMPLICIT			(1 << 4)
+
+#define AF_UNSPEC	0
+#define AF_INET		2
+#define AF_INET6	10
+
+#define RCV_SHUTDOWN	1
+#define SEND_SHUTDOWN	2
+
+#define	ENOMEM		12	/* Out of Memory */
+#define	EINVAL		22	/* Invalid argument */
+
 /* list helpers from include/linux/list.h */
 static inline int list_is_head(const struct list_head *list,
 			       const struct list_head *head)
@@ -36,6 +55,9 @@ static inline int list_is_head(const struct list_head *list,
 #define mptcp_for_each_subflow(__msk, __subflow)			\
 	list_for_each_entry(__subflow, &((__msk)->conn_list), node)
 
+#define mptcp_for_each_address(__msk, __entry)			\
+	list_for_each_entry(__entry, &((__msk)->pm.userspace_pm_local_addr_list), list)
+
 static __always_inline struct sock *
 mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
 {
@@ -57,6 +79,55 @@ extern void bpf_spin_unlock_bh(spinlock_t *lock) __ksym;
 
 extern bool bpf_ipv6_addr_v4mapped(const struct mptcp_addr_info *a) __ksym;
 
+extern void bpf_list_add_tail_rcu(struct list_head *new,
+				  struct list_head *head) __ksym;
+extern void bpf_list_del_rcu(struct list_head *entry) __ksym;
+
+extern struct mptcp_pm_addr_entry *
+bpf_pm_alloc_entry(struct sock *sk, struct mptcp_pm_addr_entry *entry) __ksym;
+extern void bpf_pm_free_entry(struct sock *sk,
+			      struct mptcp_pm_addr_entry *entry) __ksym;
+
+extern bool bpf_mptcp_addresses_equal(const struct mptcp_addr_info *a,
+				      const struct mptcp_addr_info *b, bool use_port) __ksym;
+extern bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
+				     const struct mptcp_addr_info *addr) __ksym;
+extern int mptcp_pm_announce_addr(struct mptcp_sock *msk,
+				  const struct mptcp_addr_info *addr,
+				  bool echo) __ksym;
+extern void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk) __ksym;
+
+extern void bpf_bitmap_zero(struct mptcp_id_bitmap *bitmap) __ksym;
+extern bool bpf_test_bit(u8 nr, struct mptcp_id_bitmap *bitmap) __ksym;
+extern void bpf_set_bit(u8 nr, struct mptcp_id_bitmap *bitmap) __ksym;
+extern u8 bpf_next_bit(struct mptcp_id_bitmap *bitmap) __ksym;
+
+extern int mptcp_pm_remove_addr(struct mptcp_sock *msk,
+				const struct mptcp_rm_list *rm_list) __ksym;
+extern void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
+				       struct mptcp_pm_addr_entry *entry) __ksym;
+
+extern bool bpf_mptcp_pm_addr_families_match(const struct sock *sk,
+					     const struct mptcp_addr_info *loc,
+					     const struct mptcp_addr_info *rem) __ksym;
+extern int __mptcp_subflow_connect(struct sock *sk,
+				   const struct mptcp_pm_addr_entry *local,
+				   const struct mptcp_addr_info *remote) __ksym;
+
+extern struct ipv6_pinfo *bpf_inet6_sk(const struct sock *sk) __ksym;
+extern bool bpf_ipv6_addr_equal(const struct mptcp_addr_info *a1,
+				const struct in6_addr *a2) __ksym;
+extern void bpf_ipv6_addr_set_v4mapped(const __be32 addr,
+				       struct mptcp_addr_info *v4mapped) __ksym;
+extern void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how) __ksym;
+extern void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+			    struct mptcp_subflow_context *subflow) __ksym;
+
+extern int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+					struct mptcp_addr_info *addr,
+					struct mptcp_addr_info *rem,
+					u8 bkup) __ksym;
+
 extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
 					bool scheduled) __ksym;
 
diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c b/tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c
new file mode 100644
index 000000000000..9aedbafe9b7c
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024, Kylin Software */
+
+#include "bpf_tracing_net.h"
+#include "mptcp_bpf.h"
+
+char _license[] SEC("license") = "GPL";
+
+SEC("struct_ops")
+void BPF_PROG(mptcp_pm_init, struct mptcp_sock *msk)
+{
+	bpf_printk("BPF userspace PM (%s)",
+		   CONFIG_MPTCP_IPV6 ? "IPv6" : "IPv4");
+}
+
+SEC("struct_ops")
+void BPF_PROG(mptcp_pm_release, struct mptcp_sock *msk)
+{
+}
+
+static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
+						    struct mptcp_pm_addr_entry *entry,
+						    bool needs_id)
+{
+	struct mptcp_pm_addr_entry *match = NULL;
+	struct sock *sk = (struct sock *)msk;
+	struct mptcp_id_bitmap id_bitmap;
+	struct mptcp_pm_addr_entry *e;
+	bool addr_match = false;
+	bool id_match = false;
+	int ret = -EINVAL;
+
+	bpf_bitmap_zero(&id_bitmap);
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	bpf_for_each(mptcp_address, e, msk) {
+		addr_match = bpf_mptcp_addresses_equal(&e->addr, &entry->addr, true);
+		if (addr_match && entry->addr.id == 0 && needs_id)
+			entry->addr.id = e->addr.id;
+		id_match = (e->addr.id == entry->addr.id);
+		if (addr_match && id_match) {
+			match = e;
+			break;
+		} else if (addr_match || id_match) {
+			break;
+		}
+		bpf_set_bit(e->addr.id, &id_bitmap);
+	}
+
+	if (!match && !addr_match && !id_match) {
+		/* Memory for the entry is allocated from the
+		 * sock option buffer.
+		 */
+		e = bpf_pm_alloc_entry(sk, entry);
+		if (!e) {
+			ret = -ENOMEM;
+			goto append_err;
+		}
+
+		if (!entry->addr.id && needs_id)
+			entry->addr.id = bpf_next_bit(&id_bitmap);
+		bpf_list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
+		msk->pm.local_addr_used++;
+		ret = e->addr.id;
+	} else if (match) {
+		ret = entry->addr.id;
+	}
+
+append_err:
+	bpf_spin_unlock_bh(&msk->pm.lock);
+	return ret;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_address_announce, struct mptcp_sock *msk,
+	     struct mptcp_pm_addr_entry *local)
+{
+	int err;
+
+	if (local->addr.id == 0 || !(local->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
+		return -EINVAL;
+
+	err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
+	if (err < 0)
+		return err;
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
+		msk->pm.add_addr_signaled++;
+		mptcp_pm_announce_addr(msk, &local->addr, false);
+		mptcp_pm_nl_addr_send_ack(msk);
+	}
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return 0;
+}
+
+static int mptcp_pm_remove_id_zero_address(struct mptcp_sock *msk)
+{
+	struct mptcp_rm_list list = { .nr = 0 };
+	struct mptcp_subflow_context *subflow;
+	bool has_id_0 = false;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		subflow = bpf_core_cast(subflow, struct mptcp_subflow_context);
+		if (subflow->local_id == 0) {
+			has_id_0 = true;
+			break;
+		}
+	}
+	if (!has_id_0)
+		return -EINVAL;
+
+	list.ids[list.nr++] = 0;
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	mptcp_pm_remove_addr(msk, &list);
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return 0;
+}
+
+static struct mptcp_pm_addr_entry *
+mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	bpf_for_each(mptcp_address, entry, msk) {
+		if (entry->addr.id == id)
+			return entry;
+	}
+	return NULL;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_address_remove, struct mptcp_sock *msk, u8 id)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry *entry;
+
+	if (id == 0)
+		return mptcp_pm_remove_id_zero_address(msk);
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+	bpf_spin_unlock_bh(&msk->pm.lock);
+	if (!entry)
+		return -EINVAL;
+
+	mptcp_pm_remove_addr_entry(msk, entry);
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	bpf_list_del_rcu(&entry->list);
+	bpf_pm_free_entry(sk, entry);
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return 0;
+}
+
+static struct mptcp_pm_addr_entry *
+mptcp_userspace_pm_lookup_addr(struct mptcp_sock *msk, const struct mptcp_addr_info *addr)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	bpf_for_each(mptcp_address, entry, msk) {
+		if (bpf_mptcp_addresses_equal(&entry->addr, addr, false))
+			return entry;
+	}
+	return NULL;
+}
+
+static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
+						struct mptcp_pm_addr_entry *addr)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry *entry;
+
+	entry = mptcp_userspace_pm_lookup_addr(msk, &addr->addr);
+	if (!entry)
+		return -EINVAL;
+
+	bpf_list_del_rcu(&entry->list);
+	bpf_pm_free_entry(sk, entry);
+	msk->pm.local_addr_used--;
+	return 0;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_subflow_create, struct mptcp_sock *msk,
+	     struct mptcp_pm_addr_entry *local, struct mptcp_addr_info *remote)
+{
+	struct sock *sk = (struct sock *)msk;
+	int err = -EINVAL;
+
+	if (local->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)
+		return err;
+	local->flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
+
+	if (!bpf_mptcp_pm_addr_families_match(sk, &local->addr, remote))
+		return err;
+
+	err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
+	if (err < 0)
+		return err;
+
+	err = __mptcp_subflow_connect(sk, local, remote);
+	bpf_spin_lock_bh(&msk->pm.lock);
+	if (err)
+		mptcp_userspace_pm_delete_local_addr(msk, local);
+	else
+		msk->pm.subflows++;
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return err;
+}
+
+static struct sock *mptcp_pm_find_ssk(struct mptcp_sock *msk,
+				      const struct mptcp_addr_info *local,
+				      const struct mptcp_addr_info *remote)
+{
+	struct mptcp_subflow_context *subflow;
+
+	if (local->family != remote->family)
+		return NULL;
+
+	bpf_for_each(mptcp_subflow, subflow, msk) {
+		const struct inet_sock *issk;
+		struct sock *ssk;
+
+		ssk = bpf_mptcp_subflow_tcp_sock(subflow);
+
+		if (local->family != ssk->sk_family)
+			continue;
+
+		issk = bpf_core_cast(ssk, struct inet_sock);
+
+		switch (ssk->sk_family) {
+		case AF_INET:
+			if (issk->inet_saddr != local->addr.s_addr ||
+			    issk->inet_daddr != remote->addr.s_addr)
+				continue;
+			break;
+		case AF_INET6: {
+			const struct ipv6_pinfo *pinfo = bpf_inet6_sk(ssk);
+
+			if (!bpf_ipv6_addr_equal(local, &pinfo->saddr) ||
+			    !bpf_ipv6_addr_equal(remote, &ssk->sk_v6_daddr))
+				continue;
+			break;
+		}
+		default:
+			continue;
+		}
+
+		if (issk->inet_sport == local->port &&
+		    issk->inet_dport == remote->port)
+			return ssk;
+	}
+
+	return NULL;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_subflow_destroy, struct mptcp_sock *msk,
+	     struct mptcp_pm_addr_entry *local, struct mptcp_addr_info *remote)
+{
+	struct sock *sk = (struct sock *)msk;
+	int err = -EINVAL;
+	struct sock *ssk;
+
+	if (local->addr.family == AF_INET && bpf_ipv6_addr_v4mapped(remote)) {
+		bpf_ipv6_addr_set_v4mapped(local->addr.addr.s_addr, remote);
+		local->addr.family = AF_INET6;
+	}
+	if (remote->family == AF_INET && bpf_ipv6_addr_v4mapped(&local->addr)) {
+		bpf_ipv6_addr_set_v4mapped(remote->addr.s_addr, &local->addr);
+		remote->family = AF_INET6;
+	}
+
+	if (local->addr.family != remote->family)
+		return err;
+
+	if (!local->addr.port || !remote->port)
+		return err;
+
+	ssk = mptcp_pm_find_ssk(msk, &local->addr, remote);
+	if (ssk) {
+		struct mptcp_subflow_context *subflow = bpf_mptcp_subflow_ctx(ssk);
+
+		bpf_spin_lock_bh(&msk->pm.lock);
+		err = mptcp_userspace_pm_delete_local_addr(msk, local);
+		bpf_spin_unlock_bh(&msk->pm.lock);
+		mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
+		mptcp_close_ssk(sk, ssk, subflow);
+	}
+
+	return err;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_get_local_id, struct mptcp_sock *msk,
+	     struct mptcp_pm_addr_entry *local)
+{
+	const struct inet_sock *issk = bpf_core_cast((struct sock *)msk,
+						     struct inet_sock);
+	__be16 msk_sport = issk->inet_sport;
+	struct mptcp_pm_addr_entry *entry;
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
+	bpf_spin_unlock_bh(&msk->pm.lock);
+	if (entry)
+		return entry->addr.id;
+
+	if (local->addr.port == msk_sport)
+		local->addr.port = 0;
+
+	return mptcp_userspace_pm_append_new_local_addr(msk, local, true);
+}
+
+SEC("struct_ops")
+u8 BPF_PROG(mptcp_pm_get_flags, struct mptcp_sock *msk,
+	    struct mptcp_addr_info *skc)
+{
+	struct mptcp_pm_addr_entry *entry;
+	u8 flags = 0;
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
+	if (entry)
+		flags = entry->flags;
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return flags;
+}
+
+SEC("struct_ops")
+struct mptcp_pm_addr_entry *
+BPF_PROG(mptcp_pm_get_addr, struct mptcp_sock *msk, u8 id)
+{
+	return mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+}
+
+static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
+					 struct mptcp_id_bitmap *bitmap)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	mptcp_for_each_address(msk, entry) {
+		entry = bpf_core_cast(entry, struct mptcp_pm_addr_entry);
+
+		if (bpf_test_bit(entry->addr.id, bitmap))
+			continue;
+
+		bpf_set_bit(entry->addr.id, bitmap);
+	}
+
+	return 0;
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_dump_addr, struct mptcp_sock *msk,
+	     struct mptcp_id_bitmap *bitmap)
+{
+	return mptcp_userspace_pm_set_bitmap(msk, bitmap);
+}
+
+SEC("struct_ops")
+int BPF_PROG(mptcp_pm_set_flags, struct mptcp_sock *msk,
+	     struct mptcp_pm_addr_entry *local, struct mptcp_addr_info *remote)
+{
+	struct mptcp_pm_addr_entry *entry;
+	u8 bkup = 0;
+
+	if (local->addr.family == AF_UNSPEC ||
+	    remote->family == AF_UNSPEC)
+		return -EINVAL;
+
+	if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+		bkup = 1;
+
+	bpf_spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
+	if (entry) {
+		if (bkup)
+			entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
+		else
+			entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
+	}
+	bpf_spin_unlock_bh(&msk->pm.lock);
+
+	return mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, remote, bkup);
+}
+
+SEC(".struct_ops.link")
+struct mptcp_pm_ops userspace_pm = {
+	.address_announce	= (void *)mptcp_pm_address_announce,
+	.address_remove		= (void *)mptcp_pm_address_remove,
+	.subflow_create		= (void *)mptcp_pm_subflow_create,
+	.subflow_destroy	= (void *)mptcp_pm_subflow_destroy,
+	.get_local_id		= (void *)mptcp_pm_get_local_id,
+	.get_flags		= (void *)mptcp_pm_get_flags,
+	.get_addr		= (void *)mptcp_pm_get_addr,
+	.dump_addr		= (void *)mptcp_pm_dump_addr,
+	.set_flags		= (void *)mptcp_pm_set_flags,
+	.init			= (void *)mptcp_pm_init,
+	.release		= (void *)mptcp_pm_release,
+	.type			= MPTCP_PM_TYPE_BPF,
+};
-- 
2.45.2


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

* Re: [PATCH mptcp-next v2 00/36] BPF path manager
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (35 preceding siblings ...)
  2024-10-22  9:14 ` [PATCH mptcp-next v2 36/36] selftests/bpf: Add mptcp bpf path manager subtest Geliang Tang
@ 2024-10-22 10:12 ` MPTCP CI
  2024-10-22 10:24 ` MPTCP CI
  2024-11-04 19:31 ` Matthieu Baerts
  38 siblings, 0 replies; 77+ messages in thread
From: MPTCP CI @ 2024-10-22 10:12 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

Hi Geliang,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/11457329322

Status: failure
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/9def5a043f12
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=901761

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

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

* Re: [PATCH mptcp-next v2 00/36] BPF path manager
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (36 preceding siblings ...)
  2024-10-22 10:12 ` [PATCH mptcp-next v2 00/36] BPF path manager MPTCP CI
@ 2024-10-22 10:24 ` MPTCP CI
  2024-11-04 19:31 ` Matthieu Baerts
  38 siblings, 0 replies; 77+ messages in thread
From: MPTCP CI @ 2024-10-22 10:24 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

Hi Geliang,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal: Success! ✅
- KVM Validation: debug: Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/11457329343

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/9def5a043f12
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=901761


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

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

* Re: [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match
  2024-10-22  9:14 ` [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match Geliang Tang
@ 2024-10-22 17:01   ` Matthieu Baerts
  2024-10-23  9:53     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-22 17:01 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The helper mptcp_pm_addr_families_match() uses "if-else" to handle IPv6
> and IPv4 addresses separately. But the last line of "if" code block is
> a "return" statement. In this case, no need to use an "else" statement.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 16c336c51940..f3d354a72c94 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -495,9 +495,8 @@ bool mptcp_pm_addr_families_match(const struct 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
> +	return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET;

I think some static analytic tools will complain because if
CONFIG_MPTCP_IPV6 is enabled, the code will look like this:

  return loc_is_v4 == rem_is_v4;
  return mptcp_is_v4 && (...)

Two 'return' in a row, the 2nd return is never used, there will be a
warning somewhere.

Also, I don't it is worth it, and it looks clearer with the #else. Is it
OK to drop this patch when applying the series?

>  }
>  
>  void mptcp_pm_data_reset(struct mptcp_sock *msk)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink
  2024-10-22  9:14 ` [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink Geliang Tang
@ 2024-10-22 17:09   ` Matthieu Baerts
  2024-10-23  9:59     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-22 17:09 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The helper __lookup_addr() can be used in mptcp_pm_nl_get_local_id()
> and mptcp_pm_nl_is_backup() to simplify the code if using
> list_for_each_entry_rcu() instead of list_for_each_entry() in it.

Mmh, please justify why it is OK to use the _rcu() variant without
having to modify the caller.

Did you check everything was OK when running the tests with these kconfig:

  CONFIG_RCU_EXPERT=y
  CONFIG_PROVE_RCU_LIST=y

I guess you will get new issues, no?

We might need to have __lookup_addr() and __lookup_addr_rcu() if you
want to avoid duplicated code.

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match
  2024-10-22 17:01   ` Matthieu Baerts
@ 2024-10-23  9:53     ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-23  9:53 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

Thanks for your review.

On Tue, 2024-10-22 at 19:01 +0200, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The helper mptcp_pm_addr_families_match() uses "if-else" to handle
> > IPv6
> > and IPv4 addresses separately. But the last line of "if" code block
> > is
> > a "return" statement. In this case, no need to use an "else"
> > statement.
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> >  net/mptcp/pm.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > index 16c336c51940..f3d354a72c94 100644
> > --- a/net/mptcp/pm.c
> > +++ b/net/mptcp/pm.c
> > @@ -495,9 +495,8 @@ bool mptcp_pm_addr_families_match(const struct
> > 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
> > +	return mptcp_is_v4 && loc->family == AF_INET && rem-
> > >family == AF_INET;
> 
> I think some static analytic tools will complain because if
> CONFIG_MPTCP_IPV6 is enabled, the code will look like this:
> 
>   return loc_is_v4 == rem_is_v4;
>   return mptcp_is_v4 && (...)
> 
> Two 'return' in a row, the 2nd return is never used, there will be a
> warning somewhere.
> 
> Also, I don't it is worth it, and it looks clearer with the #else. Is
> it
> OK to drop this patch when applying the series?

Let's drop it then. It has nothing to do with the entire BPF path
manager set, and other patches have no dependencies on it too.

Thanks,
-Geliang

> 
> >  }
> >  
> >  void mptcp_pm_data_reset(struct mptcp_sock *msk)
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink
  2024-10-22 17:09   ` Matthieu Baerts
@ 2024-10-23  9:59     ` Geliang Tang
  2024-10-23 10:03       ` Matthieu Baerts
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-23  9:59 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Tue, 2024-10-22 at 19:09 +0200, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The helper __lookup_addr() can be used in
> > mptcp_pm_nl_get_local_id()
> > and mptcp_pm_nl_is_backup() to simplify the code if using
> > list_for_each_entry_rcu() instead of list_for_each_entry() in it.
> 
> Mmh, please justify why it is OK to use the _rcu() variant without
> having to modify the caller.
> 
> Did you check everything was OK when running the tests with these
> kconfig:
> 
>   CONFIG_RCU_EXPERT=y
>   CONFIG_PROVE_RCU_LIST=y
> 
> I guess you will get new issues, no?

Indeed.

> 
> We might need to have __lookup_addr() and __lookup_addr_rcu() if you
> want to avoid duplicated code.

Also remove this patch from this series, it has nothing to do with the
entire BPF path manager set, and other paths have no dependencies on
it.

I will release a v2 later separately.

Thanks,
-Geliang

> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink
  2024-10-23  9:59     ` Geliang Tang
@ 2024-10-23 10:03       ` Matthieu Baerts
  2024-10-23 10:06         ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-23 10:03 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

On 23/10/2024 11:59, Geliang Tang wrote:
> On Tue, 2024-10-22 at 19:09 +0200, Matthieu Baerts wrote:
>> Hi Geliang,
>>
>> On 22/10/2024 11:14, Geliang Tang wrote:
>>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>>
>>> The helper __lookup_addr() can be used in
>>> mptcp_pm_nl_get_local_id()
>>> and mptcp_pm_nl_is_backup() to simplify the code if using
>>> list_for_each_entry_rcu() instead of list_for_each_entry() in it.
>>
>> Mmh, please justify why it is OK to use the _rcu() variant without
>> having to modify the caller.
>>
>> Did you check everything was OK when running the tests with these
>> kconfig:
>>
>>   CONFIG_RCU_EXPERT=y
>>   CONFIG_PROVE_RCU_LIST=y
>>
>> I guess you will get new issues, no?
> 
> Indeed.
> 
>>
>> We might need to have __lookup_addr() and __lookup_addr_rcu() if you
>> want to avoid duplicated code.
> 
> Also remove this patch from this series, it has nothing to do with the
> entire BPF path manager set, and other paths have no dependencies on
> it.

Will do!

Note that you could use __lookup_addr_rcu() that is being added with the
following patch (if it is accepted):

https://patchwork.kernel.org/project/mptcp/patch/20241022-mptcp-pm-lookup_addr_rcu-v1-1-19d45f26c872@kernel.org/

> I will release a v2 later separately.

Please wait for the v3, I'm still looking at the series (... doing that
slowly, when I have time :-/)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink
  2024-10-23 10:03       ` Matthieu Baerts
@ 2024-10-23 10:06         ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-23 10:06 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Wed, 2024-10-23 at 12:03 +0200, Matthieu Baerts wrote:
> On 23/10/2024 11:59, Geliang Tang wrote:
> > On Tue, 2024-10-22 at 19:09 +0200, Matthieu Baerts wrote:
> > > Hi Geliang,
> > > 
> > > On 22/10/2024 11:14, Geliang Tang wrote:
> > > > From: Geliang Tang <tanggeliang@kylinos.cn>
> > > > 
> > > > The helper __lookup_addr() can be used in
> > > > mptcp_pm_nl_get_local_id()
> > > > and mptcp_pm_nl_is_backup() to simplify the code if using
> > > > list_for_each_entry_rcu() instead of list_for_each_entry() in
> > > > it.
> > > 
> > > Mmh, please justify why it is OK to use the _rcu() variant
> > > without
> > > having to modify the caller.
> > > 
> > > Did you check everything was OK when running the tests with these
> > > kconfig:
> > > 
> > >   CONFIG_RCU_EXPERT=y
> > >   CONFIG_PROVE_RCU_LIST=y
> > > 
> > > I guess you will get new issues, no?
> > 
> > Indeed.
> > 
> > > 
> > > We might need to have __lookup_addr() and __lookup_addr_rcu() if
> > > you
> > > want to avoid duplicated code.
> > 
> > Also remove this patch from this series, it has nothing to do with
> > the
> > entire BPF path manager set, and other paths have no dependencies
> > on
> > it.
> 
> Will do!
> 
> Note that you could use __lookup_addr_rcu() that is being added with
> the
> following patch (if it is accepted):
> 
> https://patchwork.kernel.org/project/mptcp/patch/20241022-mptcp-pm-lookup_addr_rcu-v1-1-19d45f26c872@kernel.org/
> 
> > I will release a v2 later separately.
> 
> Please wait for the v3, I'm still looking at the series (... doing
> that
> slowly, when I have time :-/)

Great, I appreciate it.

> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros
  2024-10-22  9:14 ` [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros Geliang Tang
@ 2024-10-30 18:20   ` Matthieu Baerts
  2024-10-31  7:55     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-30 18:20 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Similar to mptcp_for_each_subflow() and mptcp_for_each_subflow_safe()
> macros, this patch adds two new macros mptcp_for_each_address() and
> mptcp_for_each_address_safe() to iterate over the address entries on
> userspace_pm_local_addr_list of the mptcp socket.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 12 ++++++------
>  net/mptcp/protocol.h     |  5 +++++
>  2 files changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 2cceded3a83a..00a7f9dd90cf 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -41,7 +41,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
>  	bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address(msk, e) {
>  		addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true);
>  		if (addr_match && entry->addr.id == 0 && needs_id)
>  			entry->addr.id = e->addr.id;
> @@ -92,7 +92,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
>  {
>  	struct mptcp_pm_addr_entry *entry, *tmp;
>  
> -	list_for_each_entry_safe(entry, tmp, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address_safe(msk, entry, tmp) {
>  		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
>  			/* TODO: a refcount is needed because the entry can
>  			 * be used multiple times (e.g. fullmesh mode).
> @@ -112,7 +112,7 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
>  {
>  	struct mptcp_pm_addr_entry *entry;
>  
> -	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address(msk, entry) {
>  		if (entry->addr.id == id)
>  			return entry;
>  	}
> @@ -127,7 +127,7 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
>  			     inet_sk((struct sock *)msk))->inet_sport;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address(msk, e) {
>  		if (mptcp_addresses_equal(&e->addr, skc, false)) {
>  			entry = e;
>  			break;
> @@ -155,7 +155,7 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
>  	bool backup = false;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address(msk, entry) {
>  		if (mptcp_addresses_equal(&entry->addr, skc, false)) {
>  			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
>  			break;
> @@ -642,7 +642,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  
>  	lock_sock(sk);
>  	spin_lock_bh(&msk->pm.lock);
> -	list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
> +	mptcp_for_each_address(msk, entry) {
>  		if (test_bit(entry->addr.id, bitmap->map))
>  			continue;
>  
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index b4c72a73594f..ce3b12778b3f 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -354,6 +354,11 @@ struct mptcp_sock {
>  #define mptcp_for_each_subflow_safe(__msk, __subflow, __tmp)			\
>  	list_for_each_entry_safe(__subflow, __tmp, &((__msk)->conn_list), node)
>  
> +#define mptcp_for_each_address(__msk, __entry)			\
> +	list_for_each_entry(__entry, &((__msk)->pm.userspace_pm_local_addr_list), list)
> +#define mptcp_for_each_address_safe(__msk, __entry, __tmp)			\
> +	list_for_each_entry_safe(__entry, __tmp, &((__msk)->pm.userspace_pm_local_addr_list), list)

If it is specific to the userspace PM, maybe best to declare them in
pm_userspace.c, no?

Also, the name is very generic for something so specific. Maybe:

  mptcp_for_each_pm_userspace_local_addr(_safe)

Otherwise, if we see "mptcp_for_each_address(msk, entry)" in the code,
it is really not clear what you are looking at I think, no?

> +
>  extern struct genl_family mptcp_genl_family;
>  
>  static inline void msk_owned_by_me(const struct mptcp_sock *msk)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree
  2024-10-22  9:14 ` [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree Geliang Tang
@ 2024-10-30 18:21   ` Matthieu Baerts
  2024-10-31  7:43     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-30 18:21 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The local address entries on the userspace_pm_local_addr_list are allocated
> by sock_kmalloc(). It's better to use sock_kfree_s() to free them, instead

Good catch! Do you mind developing a bit why "it is better to use
sock_kfree_s()"?

To me, it looks like a bug fix: we should use sock_kfree_s() to adjust
the allocated size. In this case, a 'Fixes' tag should be added, and
target mptcp-net. WDYT?

> of using kfree().
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 00a7f9dd90cf..3fb5713cd988 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -91,6 +91,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
>  						struct mptcp_pm_addr_entry *addr)
>  {
>  	struct mptcp_pm_addr_entry *entry, *tmp;
> +	struct sock *sk = (struct sock *)msk;
>  
>  	mptcp_for_each_address_safe(msk, entry, tmp) {
>  		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
> @@ -98,7 +99,7 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
>  			 * be used multiple times (e.g. fullmesh mode).
>  			 */
>  			list_del_rcu(&entry->list);
> -			kfree(entry);
> +			sock_kfree_s(sk, entry, sizeof(*entry));
>  			msk->pm.local_addr_used--;
>  			return 0;
>  		}

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm
  2024-10-22  9:14 ` [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm Geliang Tang
@ 2024-10-30 18:21   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-30 18:21 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Like __lookup_addr() helper in pm_netlink.c, a new helper
> mptcp_userspace_pm_lookup_addr() is also defined in pm_userspace.c.
> It looks up the corresponding mptcp_pm_addr_entry address in
> userspace_pm_local_addr_list through the passed "addr" parameter
> and returns it.
> 
> This helper can be used in mptcp_userspace_pm_delete_local_addr(),
> mptcp_userspace_pm_get_local_id() and mptcp_userspace_pm_is_backup()
> to simplify the code.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 56 +++++++++++++++++++++-------------------
>  1 file changed, 29 insertions(+), 27 deletions(-)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 3fb5713cd988..ce0f7131c701 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -26,6 +26,18 @@ void mptcp_free_local_addr_list(struct mptcp_sock *msk)
>  	}
>  }
>  
> +static struct mptcp_pm_addr_entry *
> +mptcp_userspace_pm_lookup_addr(struct mptcp_sock *msk, const struct mptcp_addr_info *addr)

When possible, can you try to limit to 80 chars per line?

See: https://github.com/linux-netdev/nipa/pull/41

Using more than 80 is allowed, but it should be restricted to cases
where using less than 80 chars affects the readability, e.g. not to
break 'entry->flags & MY_SPECIFIC_FLAG' in two lines, etc. The idea is
not to abuse of that.

Here for example, it is easy to go to the new line after the ','.

> +{
> +	struct mptcp_pm_addr_entry *entry, *tmp;
> +
> +	mptcp_for_each_address_safe(msk, entry, tmp) {

Why do you need the '_safe' alternative here? You only return an entry
from the list, and you stop: no need to continue after having modified
the list here as far as I can see, no?

Also, something very important: here you are presenting the modification
as a simple refactoring, but it does change the behaviour: the '_safe'
version is used everywhere, which was not the case before. When you do
something like that, please mention it in the commit message! Without
that, a reviewer might not notice it "OK, just a refactoring", and
developers might wonder later why this was done. I then recommend to
always add either something like:
- "No behaviour change intended here."
- or "Please note that now <something different is done> for <these
cases>, but that's OK to do so <because ...>."

> +		if (mptcp_addresses_equal(&entry->addr, addr, false))
> +			return entry;
> +	}
> +	return NULL;
> +}
> +
>  static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
>  						    struct mptcp_pm_addr_entry *entry,
>  						    bool needs_id)
> @@ -90,22 +102,20 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
>  static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
>  						struct mptcp_pm_addr_entry *addr)
>  {
> -	struct mptcp_pm_addr_entry *entry, *tmp;
>  	struct sock *sk = (struct sock *)msk;
> +	struct mptcp_pm_addr_entry *entry;
>  
> -	mptcp_for_each_address_safe(msk, entry, tmp) {
> -		if (mptcp_addresses_equal(&entry->addr, &addr->addr, false)) {
> -			/* TODO: a refcount is needed because the entry can
> -			 * be used multiple times (e.g. fullmesh mode).
> -			 */
> -			list_del_rcu(&entry->list);
> -			sock_kfree_s(sk, entry, sizeof(*entry));
> -			msk->pm.local_addr_used--;
> -			return 0;
> -		}
> -	}
> -
> -	return -EINVAL;
> +	entry = mptcp_userspace_pm_lookup_addr(msk, &addr->addr);
> +	if (!entry)
> +		return -EINVAL;
> +
> +	/* TODO: a refcount is needed because the entry can
> +	 * be used multiple times (e.g. fullmesh mode).
> +	 */

(Not related to this commit: I wonder if the TODO still makes sense. We
had some discussions with Mat, and I think the conclusion was that it
was OK, but I don't remember why)

> +	list_del_rcu(&entry->list);
> +	sock_kfree_s(sk, entry, sizeof(*entry));
> +	msk->pm.local_addr_used--;
> +	return 0;
>  }
>  
>  static struct mptcp_pm_addr_entry *
> @@ -123,17 +133,12 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
>  int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
>  				    struct mptcp_addr_info *skc)
>  {
> -	struct mptcp_pm_addr_entry *entry = NULL, *e, new_entry;
> +	struct mptcp_pm_addr_entry *entry = NULL, new_entry;
>  	__be16 msk_sport =  ((struct inet_sock *)
>  			     inet_sk((struct sock *)msk))->inet_sport;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	mptcp_for_each_address(msk, e) {
> -		if (mptcp_addresses_equal(&e->addr, skc, false)) {
> -			entry = e;
> -			break;
> -		}
> -	}
> +	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
>  	spin_unlock_bh(&msk->pm.lock);
>  	if (entry)
>  		return entry->addr.id;
> @@ -156,12 +161,9 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
>  	bool backup = false;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	mptcp_for_each_address(msk, entry) {
> -		if (mptcp_addresses_equal(&entry->addr, skc, false)) {
> -			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
> -			break;
> -		}
> -	}
> +	entry = mptcp_userspace_pm_lookup_addr(msk, skc);
> +	if (entry)
> +		backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
>  	spin_unlock_bh(&msk->pm.lock);
>  
>  	return backup;

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper
  2024-10-22  9:14 ` [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper Geliang Tang
@ 2024-10-30 18:23   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-30 18:23 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Each userspace pm netlink function uses nla_get_u32() to get the msk
> token value, then pass it to mptcp_token_get_sock() to get the msk.
> Finally check whether userspace PM is selected on this msk. It makes
> sense to wrap them into a helper, named mptcp_userspace_pm_get_sock(),
> to do this.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 137 +++++++++++++--------------------------
>  1 file changed, 44 insertions(+), 93 deletions(-)

Looks like a good refactoring!

> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index ce0f7131c701..79ae32c921b7 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -169,36 +169,51 @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
>  	return backup;
>  }
>  
> -int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
> +static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
>  {
>  	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
> +	struct mptcp_sock *msk = NULL;

(no need to set it to NULL, see below)

> +
> +	if (!token) {
> +		GENL_SET_ERR_MSG(info, "missing required inputs");

Maybe we can take this opportunity to mention the token: "missing
required token".

> +		goto out;

Detail: simply return 'NULL' here, there is no clean-up to do, no?

> +	}
> +
> +	msk = mptcp_token_get_sock(genl_info_net(info), nla_get_u32(token));

I see that below, we were also using sock_net(skb->sk) or even
sock_net(msg->sk). Please mention such modifications in the commit
message, explaining why it is OK to use only genl_info_net(). I guess it
is the same info, but better to be sure and not hide that.

> +	if (!msk) {
> +		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +		goto out;

Same here.

> +	}
> +
> +	if (!mptcp_pm_is_userspace(msk)) {
> +		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> +		sock_put((struct sock *)msk);

Mmh, I was not sure if it would be a good idea to do this check and
sock_put() here, but I guess that's OK as we just got the msk with the
previous call. (no need to change then)

> +		msk = NULL;

I guess you can also simply return NULL here, and remove the 'out' label.

> +	}
> +
> +out:
> +	return msk;
> +}
> +
> +int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
> +{
>  	struct nlattr *addr = info->attrs[MPTCP_PM_ATTR_ADDR];
>  	struct mptcp_pm_addr_entry addr_val;
>  	struct mptcp_sock *msk;
>  	int err = -EINVAL;
>  	struct sock *sk;
> -	u32 token_val;
>  
> -	if (!addr || !token) {
> +	if (!addr) {
>  		GENL_SET_ERR_MSG(info, "missing required inputs");

Same here, "missing required address".

>  		return err;
>  	}
>  
> -	token_val = nla_get_u32(token);
> -
> -	msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return err;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto announce_err;
> -	}
> -
>  	err = mptcp_pm_parse_entry(addr, info, true, &addr_val);
>  	if (err < 0) {
>  		GENL_SET_ERR_MSG(info, "error parsing local address");
> @@ -271,7 +286,6 @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk,
>  
>  int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  {
> -	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  	struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
>  	struct mptcp_pm_addr_entry *match;
>  	struct mptcp_pm_addr_entry *entry;
> @@ -279,30 +293,21 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  	LIST_HEAD(free_list);
>  	int err = -EINVAL;
>  	struct sock *sk;
> -	u32 token_val;
>  	u8 id_val;
>  
> -	if (!id || !token) {
> +	if (!id) {
>  		GENL_SET_ERR_MSG(info, "missing required inputs");

Same here, "missing required ID".

>  		return err;
>  	}
>  
>  	id_val = nla_get_u8(id);
> -	token_val = nla_get_u32(token);
>  
> -	msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return err;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto out;
> -	}
> -
>  	if (id_val == 0) {
>  		err = mptcp_userspace_pm_remove_id_zero_address(msk, info);
>  		goto out;
> @@ -336,7 +341,6 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>  {
>  	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> -	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
>  	struct mptcp_pm_addr_entry entry = { 0 };
>  	struct mptcp_addr_info addr_r;
> @@ -344,28 +348,18 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>  	struct mptcp_sock *msk;
>  	int err = -EINVAL;
>  	struct sock *sk;
> -	u32 token_val;
>  
> -	if (!laddr || !raddr || !token) {
> +	if (!laddr || !raddr) {
>  		GENL_SET_ERR_MSG(info, "missing required inputs");

I guess here, you could have "missing required address(es)".

>  		return err;
>  	}
>  
> -	token_val = nla_get_u32(token);
> -
> -	msk = mptcp_token_get_sock(genl_info_net(info), token_val);
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return err;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto create_err;
> -	}
> -
>  	err = mptcp_pm_parse_entry(laddr, info, true, &entry);
>  	if (err < 0) {
>  		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
> @@ -468,35 +462,24 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
>  int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
>  {
>  	struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> -	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  	struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
>  	struct mptcp_addr_info addr_l;
>  	struct mptcp_addr_info addr_r;
>  	struct mptcp_sock *msk;
>  	struct sock *sk, *ssk;
>  	int err = -EINVAL;
> -	u32 token_val;
>  
> -	if (!laddr || !raddr || !token) {
> +	if (!laddr || !raddr) {

I guess here, you could have "missing required address(es)".

>  		GENL_SET_ERR_MSG(info, "missing required inputs");
>  		return err;
>  	}
>  
> -	token_val = nla_get_u32(token);
> -
> -	msk = mptcp_token_get_sock(genl_info_net(info), token_val);
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return err;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto destroy_err;
> -	}
> -
>  	err = mptcp_pm_parse_addr(laddr, info, &addr_l);
>  	if (err < 0) {
>  		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
> @@ -559,30 +542,18 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
>  	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
>  	struct mptcp_pm_addr_entry rem = { .addr = { .family = AF_UNSPEC }, };
>  	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> -	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
> -	struct net *net = sock_net(skb->sk);
>  	struct mptcp_sock *msk;
>  	int ret = -EINVAL;
>  	struct sock *sk;
> -	u32 token_val;
>  	u8 bkup = 0;
>  
> -	token_val = nla_get_u32(token);
> -
> -	msk = mptcp_token_get_sock(net, token_val);
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return ret;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "userspace PM not selected");
> -		goto set_flags_err;
> -	}
> -
>  	ret = mptcp_pm_parse_entry(attr, info, false, &loc);
>  	if (ret < 0)
>  		goto set_flags_err;
> @@ -619,30 +590,20 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  		DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
>  	} *bitmap;
>  	const struct genl_info *info = genl_info_dump(cb);
> -	struct net *net = sock_net(msg->sk);
>  	struct mptcp_pm_addr_entry *entry;
>  	struct mptcp_sock *msk;
> -	struct nlattr *token;
>  	int ret = -EINVAL;
>  	struct sock *sk;
>  	void *hdr;
>  
>  	bitmap = (struct id_bitmap *)cb->ctx;
> -	token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  
> -	msk = mptcp_token_get_sock(net, nla_get_u32(token));
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return ret;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto out;
> -	}
> -
>  	lock_sock(sk);
>  	spin_lock_bh(&msk->pm.lock);
>  	mptcp_for_each_address(msk, entry) {
> @@ -667,7 +628,6 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  	release_sock(sk);
>  	ret = msg->len;
>  
> -out:
>  	sock_put(sk);
>  	return ret;
>  }
> @@ -676,28 +636,19 @@ int mptcp_userspace_pm_get_addr(struct sk_buff *skb,
>  				struct genl_info *info)
>  {
>  	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
> -	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>  	struct mptcp_pm_addr_entry addr, *entry;
> -	struct net *net = sock_net(skb->sk);
>  	struct mptcp_sock *msk;
>  	struct sk_buff *msg;
>  	int ret = -EINVAL;
>  	struct sock *sk;
>  	void *reply;
>  
> -	msk = mptcp_token_get_sock(net, nla_get_u32(token));
> -	if (!msk) {
> -		NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
> +	msk = mptcp_userspace_pm_get_sock(info);
> +	if (!msk)
>  		return ret;
> -	}
>  
>  	sk = (struct sock *)msk;
>  
> -	if (!mptcp_pm_is_userspace(msk)) {
> -		GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
> -		goto out;
> -	}
> -
>  	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
>  	if (ret < 0)
>  		goto out;

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static
  2024-10-22  9:14 ` [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static Geliang Tang
@ 2024-10-30 18:31   ` Matthieu Baerts
  2024-10-31  7:58     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-30 18:31 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

(I'm still reviewing the series, thank you for your patience. Please
wait for me to finish it before sending a v3.)

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Three path manager wrappers, mptcp_pm_get_addr(), mptcp_pm_dump_addr() and
> mptcp_pm_set_flags() are used to switch the interfaces between in-kernel
> PM and userspace PM. These wrappers are defined in pm.c but only used in
> pm_netlink.c. It makes more sense to move them to pm_netlink.c and make
> them all static.

These three helpers are calling userspace PM code, that looks "strange"
to do that from pm_netlink.

I didn't check, but would it not make more sense to move all the _doit()
functions calling these helpers to pm.c? Also, do we still these helpers
you were moving? Can we not instead remove them, and move their code
directly in the _doit() functions if you see what I mean?

  int mptcp_pm_nl_get_addr_doit(...)
  {
      if (info->attrs[MPTCP_PM_ATTR_TOKEN])
          return mptcp_userspace_pm_get_addr(skb, info);
      return mptcp_pm_nl_get_addr(skb, info);
  }

(in pm.c)

WDYT?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree
  2024-10-30 18:21   ` Matthieu Baerts
@ 2024-10-31  7:43     ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-31  7:43 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

Thanks for your review.

On Wed, 2024-10-30 at 19:21 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The local address entries on the userspace_pm_local_addr_list are
> > allocated
> > by sock_kmalloc(). It's better to use sock_kfree_s() to free them,
> > instead
> 
> Good catch! Do you mind developing a bit why "it is better to use
> sock_kfree_s()"?
> 
> To me, it looks like a bug fix: we should use sock_kfree_s() to
> adjust
> the allocated size. In this case, a 'Fixes' tag should be added, and
> target mptcp-net. WDYT?

I'll send a v2 of this patch alone out of "BPF path manager" set to our
ML, with "mptcp-net" prefix and "Fixes" tag, and update the commit log
too.

-Geliang

> 
> > of using kfree().
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> >  net/mptcp/pm_userspace.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> > index 00a7f9dd90cf..3fb5713cd988 100644
> > --- a/net/mptcp/pm_userspace.c
> > +++ b/net/mptcp/pm_userspace.c
> > @@ -91,6 +91,7 @@ static int
> > mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
> >  						struct
> > mptcp_pm_addr_entry *addr)
> >  {
> >  	struct mptcp_pm_addr_entry *entry, *tmp;
> > +	struct sock *sk = (struct sock *)msk;
> >  
> >  	mptcp_for_each_address_safe(msk, entry, tmp) {
> >  		if (mptcp_addresses_equal(&entry->addr, &addr-
> > >addr, false)) {
> > @@ -98,7 +99,7 @@ static int
> > mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
> >  			 * be used multiple times (e.g. fullmesh
> > mode).
> >  			 */
> >  			list_del_rcu(&entry->list);
> > -			kfree(entry);
> > +			sock_kfree_s(sk, entry, sizeof(*entry));
> >  			msk->pm.local_addr_used--;
> >  			return 0;
> >  		}
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros
  2024-10-30 18:20   ` Matthieu Baerts
@ 2024-10-31  7:55     ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-10-31  7:55 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Wed, 2024-10-30 at 19:20 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > Similar to mptcp_for_each_subflow() and
> > mptcp_for_each_subflow_safe()
> > macros, this patch adds two new macros mptcp_for_each_address() and
> > mptcp_for_each_address_safe() to iterate over the address entries
> > on
> > userspace_pm_local_addr_list of the mptcp socket.
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> >  net/mptcp/pm_userspace.c | 12 ++++++------
> >  net/mptcp/protocol.h     |  5 +++++
> >  2 files changed, 11 insertions(+), 6 deletions(-)
> > 
> > diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> > index 2cceded3a83a..00a7f9dd90cf 100644
> > --- a/net/mptcp/pm_userspace.c
> > +++ b/net/mptcp/pm_userspace.c
> > @@ -41,7 +41,7 @@ static int
> > mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
> >  	bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
> >  
> >  	spin_lock_bh(&msk->pm.lock);
> > -	list_for_each_entry(e, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address(msk, e) {
> >  		addr_match = mptcp_addresses_equal(&e->addr,
> > &entry->addr, true);
> >  		if (addr_match && entry->addr.id == 0 && needs_id)
> >  			entry->addr.id = e->addr.id;
> > @@ -92,7 +92,7 @@ static int
> > mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
> >  {
> >  	struct mptcp_pm_addr_entry *entry, *tmp;
> >  
> > -	list_for_each_entry_safe(entry, tmp, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address_safe(msk, entry, tmp) {
> >  		if (mptcp_addresses_equal(&entry->addr, &addr-
> > >addr, false)) {
> >  			/* TODO: a refcount is needed because the
> > entry can
> >  			 * be used multiple times (e.g. fullmesh
> > mode).
> > @@ -112,7 +112,7 @@ mptcp_userspace_pm_lookup_addr_by_id(struct
> > mptcp_sock *msk, unsigned int id)
> >  {
> >  	struct mptcp_pm_addr_entry *entry;
> >  
> > -	list_for_each_entry(entry, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address(msk, entry) {
> >  		if (entry->addr.id == id)
> >  			return entry;
> >  	}
> > @@ -127,7 +127,7 @@ int mptcp_userspace_pm_get_local_id(struct
> > mptcp_sock *msk,
> >  			     inet_sk((struct sock *)msk))-
> > >inet_sport;
> >  
> >  	spin_lock_bh(&msk->pm.lock);
> > -	list_for_each_entry(e, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address(msk, e) {
> >  		if (mptcp_addresses_equal(&e->addr, skc, false)) {
> >  			entry = e;
> >  			break;
> > @@ -155,7 +155,7 @@ bool mptcp_userspace_pm_is_backup(struct
> > mptcp_sock *msk,
> >  	bool backup = false;
> >  
> >  	spin_lock_bh(&msk->pm.lock);
> > -	list_for_each_entry(entry, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address(msk, entry) {
> >  		if (mptcp_addresses_equal(&entry->addr, skc,
> > false)) {
> >  			backup = !!(entry->flags &
> > MPTCP_PM_ADDR_FLAG_BACKUP);
> >  			break;
> > @@ -642,7 +642,7 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff
> > *msg,
> >  
> >  	lock_sock(sk);
> >  	spin_lock_bh(&msk->pm.lock);
> > -	list_for_each_entry(entry, &msk-
> > >pm.userspace_pm_local_addr_list, list) {
> > +	mptcp_for_each_address(msk, entry) {
> >  		if (test_bit(entry->addr.id, bitmap->map))
> >  			continue;
> >  
> > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> > index b4c72a73594f..ce3b12778b3f 100644
> > --- a/net/mptcp/protocol.h
> > +++ b/net/mptcp/protocol.h
> > @@ -354,6 +354,11 @@ struct mptcp_sock {
> >  #define mptcp_for_each_subflow_safe(__msk, __subflow,
> > __tmp)			\
> >  	list_for_each_entry_safe(__subflow, __tmp, &((__msk)-
> > >conn_list), node)
> >  
> > +#define mptcp_for_each_address(__msk, __entry)			\
> > +	list_for_each_entry(__entry, &((__msk)-
> > >pm.userspace_pm_local_addr_list), list)
> > +#define mptcp_for_each_address_safe(__msk, __entry,
> > __tmp)			\
> > +	list_for_each_entry_safe(__entry, __tmp, &((__msk)-
> > >pm.userspace_pm_local_addr_list), list)
> 
> If it is specific to the userspace PM, maybe best to declare them in
> pm_userspace.c, no?
> 
> Also, the name is very generic for something so specific. Maybe:
> 
>   mptcp_for_each_pm_userspace_local_addr(_safe)
> 
> Otherwise, if we see "mptcp_for_each_address(msk, entry)" in the
> code,
> it is really not clear what you are looking at I think, no?

Good idea! I moved it into pm_userspace.c and renamed it as
mptcp_for_each_userspace_pm_addr.

Furthermore, I renamed mptcp_address bpf_iter in another set "add
mptcp_address bpf_iter" as mptcp_userspace_pm_addr bpf_iter to keep it
consistent with this patch.

Thanks,
-Geliang

> 
> > +
> >  extern struct genl_family mptcp_genl_family;
> >  
> >  static inline void msk_owned_by_me(const struct mptcp_sock *msk)
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static
  2024-10-30 18:31   ` Matthieu Baerts
@ 2024-10-31  7:58     ` Geliang Tang
  2024-10-31 16:33       ` Matthieu Baerts
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-10-31  7:58 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Wed, 2024-10-30 at 19:31 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> (I'm still reviewing the series, thank you for your patience. Please
> wait for me to finish it before sending a v3.)
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > Three path manager wrappers, mptcp_pm_get_addr(),
> > mptcp_pm_dump_addr() and
> > mptcp_pm_set_flags() are used to switch the interfaces between in-
> > kernel
> > PM and userspace PM. These wrappers are defined in pm.c but only
> > used in
> > pm_netlink.c. It makes more sense to move them to pm_netlink.c and
> > make
> > them all static.
> 
> These three helpers are calling userspace PM code, that looks
> "strange"
> to do that from pm_netlink.

I agree.

> 
> I didn't check, but would it not make more sense to move all the
> _doit()
> functions calling these helpers to pm.c? Also, do we still these
> helpers
> you were moving? Can we not instead remove them, and move their code
> directly in the _doit() functions if you see what I mean?
> 
>   int mptcp_pm_nl_get_addr_doit(...)
>   {
>       if (info->attrs[MPTCP_PM_ATTR_TOKEN])
>           return mptcp_userspace_pm_get_addr(skb, info);
>       return mptcp_pm_nl_get_addr(skb, info);
>   }
> 
> (in pm.c)
> 
> WDYT?

I prefer to drop this patch and keep the code as is.

Thanks,
-Geliang

> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static
  2024-10-31  7:58     ` Geliang Tang
@ 2024-10-31 16:33       ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-31 16:33 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 31/10/2024 08:58, Geliang Tang wrote:
> On Wed, 2024-10-30 at 19:31 +0100, Matthieu Baerts wrote:
>> Hi Geliang,
>>
>> (I'm still reviewing the series, thank you for your patience. Please
>> wait for me to finish it before sending a v3.)
>>
>> On 22/10/2024 11:14, Geliang Tang wrote:
>>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>>
>>> Three path manager wrappers, mptcp_pm_get_addr(),
>>> mptcp_pm_dump_addr() and
>>> mptcp_pm_set_flags() are used to switch the interfaces between in-
>>> kernel
>>> PM and userspace PM. These wrappers are defined in pm.c but only
>>> used in
>>> pm_netlink.c. It makes more sense to move them to pm_netlink.c and
>>> make
>>> them all static.
>>
>> These three helpers are calling userspace PM code, that looks
>> "strange"
>> to do that from pm_netlink.
> 
> I agree.
> 
>>
>> I didn't check, but would it not make more sense to move all the
>> _doit()
>> functions calling these helpers to pm.c? Also, do we still these
>> helpers
>> you were moving? Can we not instead remove them, and move their code
>> directly in the _doit() functions if you see what I mean?
>>
>>   int mptcp_pm_nl_get_addr_doit(...)
>>   {
>>       if (info->attrs[MPTCP_PM_ATTR_TOKEN])
>>           return mptcp_userspace_pm_get_addr(skb, info);
>>       return mptcp_pm_nl_get_addr(skb, info);
>>   }
>>
>> (in pm.c)
>>
>> WDYT?
> 
> I prefer to drop this patch and keep the code as is.

Up to you. I think it still makes sense not to have a "public" function
simply calling another "public" one with the same arguments.

But the code can also stay like that for the moment, no problem.

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const
  2024-10-22  9:14 ` [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const Geliang Tang
@ 2024-10-31 18:41   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-31 18:41 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> get_addr() interfeces will be invoked by dump_addr(), which using const

(typo: s/interfeces/interfaces/)

> parameters "info", so this patch changes "info" parameters of get_addr()
> as const too.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_netlink.c   | 9 ++++++---
>  net/mptcp/pm_userspace.c | 2 +-
>  net/mptcp/protocol.h     | 2 +-
>  3 files changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 064fe4d494eb..02e4dda0dc13 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1793,12 +1793,15 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
>  }
>  
>  static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
> -				struct genl_info *info)
> +				const struct genl_info *info)
>  {
> -	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
> +	struct net *net = genl_info_net(info);
>  	struct mptcp_pm_addr_entry *entry;
> +	struct pm_nl_pernet *pernet;
>  	int ret = -EINVAL;
>  
> +	pernet = pm_nl_get_pernet(net);

Please mention this modification in the commit message: you didn't only
add the 'const' attribute, you had to do some adaptations.

I guess you can no longer use genl_info_pm_nl() because it doesn't
accept a 'const' variable, but that's OK to get pernet via
genl_info_net(), right? I think that's clearer if we don't have to guess.

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap
  2024-10-22  9:14 ` [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap Geliang Tang
@ 2024-10-31 18:45   ` Matthieu Baerts
  2024-11-04  9:12     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-10-31 18:45 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> A new struct mptcp_id_bitmap is defined to unify all bitmap type of address
> IDs for both in-kernel PM and userspace PM.
> 
> This type can be used to easily refactor dump_addr() interface of the path
> managers to accept an mptcp_id_bitmap type parameter. It also allows this
> parameter of dump_addr() can be modified by BPF program when implementing
> this interface of a BFP path manager.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>

(...)

> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 8282a6355765..4358a9a21270 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -211,6 +211,10 @@ enum mptcp_addr_signal_status {
>  /* max value of mptcp_addr_info.id */
>  #define MPTCP_PM_MAX_ADDR_ID		U8_MAX
>  
> +struct mptcp_id_bitmap {

This name is too generic, while here this bitmap is specific to the
path-manager and its PM address:

  mptcp_pm_addr_avail_id?

> +	DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);

Sorry, I'm not sure to understand this modification: why do you need a
specific structure with only one field? I didn't check the next patches
yet, but I saw that at the end of the series, the structure still only
has one field.

Do you require this dedicated structure because of a limitation of BPF?
Can we not use a typedef, a macro or something else to avoid all these
modifications here?

> +};
> +
>  struct mptcp_pm_data {
>  	struct mptcp_addr_info local;
>  	struct mptcp_addr_info remote;
> @@ -231,7 +235,7 @@ struct mptcp_pm_data {
>  	u8		pm_type;
>  	u8		subflows;
>  	u8		status;
> -	DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
> +	struct mptcp_id_bitmap id_avail_bitmap;
>  	struct mptcp_rm_list rm_list_tx;
>  	struct mptcp_rm_list rm_list_rx;
>  };

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap
  2024-10-31 18:45   ` Matthieu Baerts
@ 2024-11-04  9:12     ` Geliang Tang
  2024-11-04 10:16       ` Matthieu Baerts
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-11-04  9:12 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Thu, 2024-10-31 at 19:45 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > A new struct mptcp_id_bitmap is defined to unify all bitmap type of
> > address
> > IDs for both in-kernel PM and userspace PM.
> > 
> > This type can be used to easily refactor dump_addr() interface of
> > the path
> > managers to accept an mptcp_id_bitmap type parameter. It also
> > allows this
> > parameter of dump_addr() can be modified by BPF program when
> > implementing
> > this interface of a BFP path manager.
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> 
> (...)
> 
> > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> > index 8282a6355765..4358a9a21270 100644
> > --- a/net/mptcp/protocol.h
> > +++ b/net/mptcp/protocol.h
> > @@ -211,6 +211,10 @@ enum mptcp_addr_signal_status {
> >  /* max value of mptcp_addr_info.id */
> >  #define MPTCP_PM_MAX_ADDR_ID		U8_MAX
> >  
> > +struct mptcp_id_bitmap {
> 
> This name is too generic, while here this bitmap is specific to the
> path-manager and its PM address:
> 
>   mptcp_pm_addr_avail_id?
> 
> > +	DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
> 
> Sorry, I'm not sure to understand this modification: why do you need
> a
> specific structure with only one field? I didn't check the next
> patches
> yet, but I saw that at the end of the series, the structure still
> only
> has one field.
> 
> Do you require this dedicated structure because of a limitation of
> BPF?

Yes, defining dump_addr interface as either

int userspace_pm_dump_addr(struct mptcp_sock *msk,
                           unsigned long *bitmap)

or

int userspace_pm_dump_addr(struct mptcp_sock *msk,
			   unsigned long id_bitmap[4])

is not allowed by BPF.

> Can we not use a typedef, a macro or something else to avoid all
> these
> modifications here?

In v3 I defined a type using typedef like this:

typedef struct {
        DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1); 
} mptcp_pm_addr_id_bitmap_t;

and only used it in the parameters of the dump_addr interfaces. The
rest of the places continue to use DECLARE_BITMAP. It works well, the
only downside is that checkpatch.pl complains about it:

$ ./scripts/checkpatch.pl 0001-mptcp-add-mptcp_pm_addr_id_bitmap_t-
type.patch 
WARNING: do not add new typedefs
#31: FILE: include/net/mptcp.h:124:
+typedef struct {

total: 0 errors, 1 warnings, 0 checks, 40 lines checked

We can ignore this warning.

WDYT?

Thanks,
-Geliang

> 
> > +};
> > +
> >  struct mptcp_pm_data {
> >  	struct mptcp_addr_info local;
> >  	struct mptcp_addr_info remote;
> > @@ -231,7 +235,7 @@ struct mptcp_pm_data {
> >  	u8		pm_type;
> >  	u8		subflows;
> >  	u8		status;
> > -	DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
> > +	struct mptcp_id_bitmap id_avail_bitmap;
> >  	struct mptcp_rm_list rm_list_tx;
> >  	struct mptcp_rm_list rm_list_rx;
> >  };
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap
  2024-11-04  9:12     ` Geliang Tang
@ 2024-11-04 10:16       ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 10:16 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

Thank you for your reply!

On 04/11/2024 10:12, Geliang Tang wrote:
> Hi Matt,
> 
> On Thu, 2024-10-31 at 19:45 +0100, Matthieu Baerts wrote:
>> Hi Geliang,
>>
>> On 22/10/2024 11:14, Geliang Tang wrote:
>>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>>
>>> A new struct mptcp_id_bitmap is defined to unify all bitmap type of
>>> address
>>> IDs for both in-kernel PM and userspace PM.
>>>
>>> This type can be used to easily refactor dump_addr() interface of
>>> the path
>>> managers to accept an mptcp_id_bitmap type parameter. It also
>>> allows this
>>> parameter of dump_addr() can be modified by BPF program when
>>> implementing
>>> this interface of a BFP path manager.
>>>
>>> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
>>
>> (...)
>>
>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>>> index 8282a6355765..4358a9a21270 100644
>>> --- a/net/mptcp/protocol.h
>>> +++ b/net/mptcp/protocol.h
>>> @@ -211,6 +211,10 @@ enum mptcp_addr_signal_status {
>>>  /* max value of mptcp_addr_info.id */
>>>  #define MPTCP_PM_MAX_ADDR_ID		U8_MAX
>>>  
>>> +struct mptcp_id_bitmap {
>>
>> This name is too generic, while here this bitmap is specific to the
>> path-manager and its PM address:
>>
>>   mptcp_pm_addr_avail_id?
>>
>>> +	DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1);
>>
>> Sorry, I'm not sure to understand this modification: why do you need
>> a
>> specific structure with only one field? I didn't check the next
>> patches
>> yet, but I saw that at the end of the series, the structure still
>> only
>> has one field.
>>
>> Do you require this dedicated structure because of a limitation of
>> BPF?
> 
> Yes, defining dump_addr interface as either
> 
> int userspace_pm_dump_addr(struct mptcp_sock *msk,
>                            unsigned long *bitmap)
> 
> or
> 
> int userspace_pm_dump_addr(struct mptcp_sock *msk,
> 			   unsigned long id_bitmap[4])
> 
> is not allowed by BPF.

OK, thank you! (Do not hesitate to put such comment in commit message,
that's clearer and helpful for the reviewers :) )

>> Can we not use a typedef, a macro or something else to avoid all
>> these
>> modifications here?
> 
> In v3 I defined a type using typedef like this:
> 
> typedef struct {
>         DECLARE_BITMAP(map, MPTCP_PM_MAX_ADDR_ID + 1); 
> } mptcp_pm_addr_id_bitmap_t;
> 
> and only used it in the parameters of the dump_addr interfaces. The
> rest of the places continue to use DECLARE_BITMAP. It works well,

Just to be sure: by doing that, do you avoid adding ".map" a bit
everywhere? Because you still have a structure with a single item called
'map' at the end.
Or with that, you can use it only on BPF side and this structure can
then be declared in net/mptcp.bpf.c?

> the only downside is that checkpatch.pl complains about it:
> 
> $ ./scripts/checkpatch.pl 0001-mptcp-add-mptcp_pm_addr_id_bitmap_t-
> type.patch 
> WARNING: do not add new typedefs
> #31: FILE: include/net/mptcp.h:124:
> +typedef struct {
> 
> total: 0 errors, 1 warnings, 0 checks, 40 lines checked
> 
> We can ignore this warning.

Yes we can, but please add a comment above the typedef explaining why it
is useful.

> 
> WDYT?
> 
> Thanks,
> -Geliang
> 
>>
>>> +};
>>> +
>>>  struct mptcp_pm_data {
>>>  	struct mptcp_addr_info local;
>>>  	struct mptcp_addr_info remote;
>>> @@ -231,7 +235,7 @@ struct mptcp_pm_data {
>>>  	u8		pm_type;
>>>  	u8		subflows;
>>>  	u8		status;
>>> -	DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
>>> +	struct mptcp_id_bitmap id_avail_bitmap;
>>>  	struct mptcp_rm_list rm_list_tx;
>>>  	struct mptcp_rm_list rm_list_rx;
>>>  };
>>
>> Cheers,
>> Matt
> 

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap
  2024-10-22  9:14 ` [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap Geliang Tang
@ 2024-11-04 17:18   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 17:18 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

(I only see this patch now, and better understand the reaction you had
in [1])

[1]
https://lore.kernel.org/mptcp/20241025-mptcp-pm-lookup_addr_rcu-v2-2-1478f6c4b205@kernel.org/T/#u

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> Subject: mptcp: refactor dump_addr with id bitmap

Be careful when you use this 'refactor' word: if I'm not mistaken,
generally it means that you modified the code around to ease integration
of a new feature or the maintenance, but without changing the behaviour
or fixing anything. Here, yes you moved the code around, but to fix
something, to change the behaviour.

> With the help of get_addr(), we can refactor dump_addr() interfaces to
> reuse send_nlmsg code between the netlink PM and userspace PM.
> 
> The current dump_addr() flow looks like this:
> 
> 	lock();
> 	for_each_entry(entry)
> 		send_nlmsg(entry);
> 	unlock();
> 
> After holding the lock, get every entry by walking the address list,
> send each one looply, and finally release the lock.
> 
> This set changes the process by copying the address list to an id
> bitmap while holding the lock, then release the lock immediately.
> After that, without locking, walking the copied id bitmap to get
> every copy of entry by using get_addr(), and send each one looply.
> 
> This patch is the first part of refactoring dump_addr().
> 
> Without changing the position of the locks, the dump process is split
> into two parts: copying the ID bitmap first, and then traversing the
> ID bitmap, use lookup_addr_by_id() to get the entry, then send each
> one through nlmsg:
> 
> 	lock();
> 	for_each_entry(entry)
> 		set_bit(bitmap);
> 	for_each_bit(bitmap) {
> 		entry = lookup_addr_by_id();
> 		send_nlmsg(entry);
> 	}
> 	unlock();

After the discussions we had on [1], do you still think this
modification is needed? Do you do that for the consistency, to unify the
code, or because you require this for the BPF PM?

If it is for the consistency, please check the last question from Mat on
[1]:

> Do you see a reason that bitmap/addr_list inconsistencies would cause issues?

Also, with the modification here (mainly with the next patch), can we
not have more inconsistencies? The bitmap can point to ID that have been
freed/should not be read, no?

> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_netlink.c   |  6 ++++-
>  net/mptcp/pm_userspace.c | 54 +++++++++++++++++++++++++++++-----------
>  2 files changed, 45 insertions(+), 15 deletions(-)
> 
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index c030a79cd1dd..4cee5942200c 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1869,16 +1869,20 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
>  {
>  	struct net *net = sock_net(msg->sk);
>  	struct mptcp_pm_addr_entry *entry;
> +	struct mptcp_id_bitmap *bitmap;
>  	struct pm_nl_pernet *pernet;
>  	int id = cb->args[0];
>  	void *hdr;
>  	int i;
>  
> +	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
>  	pernet = pm_nl_get_pernet(net);
>  
>  	spin_lock_bh(&pernet->lock);
> +	if (!id)
> +		bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
>  	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
> -		if (test_bit(i, pernet->id_bitmap.map)) {
> +		if (test_bit(i, bitmap->map)) {
>  			entry = __lookup_addr_by_id(pernet, i);
>  			if (!entry)
>  				break;
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index cb4f2a174d0d..237383cfd12e 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -583,6 +583,21 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
>  	return ret;
>  }
>  
> +static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
> +					 struct mptcp_id_bitmap *bitmap)
> +{
> +	struct mptcp_pm_addr_entry *entry;
> +
> +	mptcp_for_each_address(msk, entry) {
> +		if (test_bit(entry->addr.id, bitmap->map))
> +			continue;
> +
> +		__set_bit(entry->addr.id, bitmap->map);

It is not clear to me what you are trying to do here. Is this helper
(the name is not clear) only called the first time, then when the bitmap
is reset, no? Then why do you need the 'test_bit'?

> +	}
> +
> +	return 0;
> +}
> +
>  int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  				 struct netlink_callback *cb)
>  {
> @@ -590,9 +605,11 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  	struct mptcp_pm_addr_entry *entry;
>  	struct mptcp_id_bitmap *bitmap;
>  	struct mptcp_sock *msk;
> +	int id = cb->args[0];
>  	int ret = -EINVAL;
>  	struct sock *sk;
>  	void *hdr;
> +	int i;
>  
>  	bitmap = (struct mptcp_id_bitmap *)cb->ctx;
>  
> @@ -604,24 +621,33 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
>  
>  	lock_sock(sk);
>  	spin_lock_bh(&msk->pm.lock);
> -	mptcp_for_each_address(msk, entry) {
> -		if (test_bit(entry->addr.id, bitmap->map))
> -			continue;
> +	if (!id)
> +		ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
> +	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
> +		if (test_bit(i, bitmap->map)) {
> +			entry = mptcp_userspace_pm_lookup_addr_by_id(msk, i);
> +			if (!entry)
> +				break;
> +
> +			if (id && entry->addr.id <= id)
> +				continue;
>  
> -		hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
> -				  cb->nlh->nlmsg_seq, &mptcp_genl_family,
> -				  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
> -		if (!hdr)
> -			break;
> +			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
> +					  cb->nlh->nlmsg_seq, &mptcp_genl_family,
> +					  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
> +			if (!hdr)
> +				break;
>  
> -		if (mptcp_nl_fill_addr(msg, entry) < 0) {
> -			genlmsg_cancel(msg, hdr);
> -			break;
> -		}
> +			if (mptcp_nl_fill_addr(msg, entry) < 0) {
> +				genlmsg_cancel(msg, hdr);
> +				break;
> +			}
>  
> -		__set_bit(entry->addr.id, bitmap->map);
> -		genlmsg_end(msg, hdr);
> +			id = entry->addr.id;
> +			genlmsg_end(msg, hdr);
> +		}
>  	}
> +	cb->args[0] = id;
>  	spin_unlock_bh(&msk->pm.lock);
>  	release_sock(sk);
>  	ret = msg->len;

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it
  2024-10-22  9:14 ` [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it Geliang Tang
@ 2024-11-04 18:20   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 18:20 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

Thank you for the patch.

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Just like in-kernel pm, when userspace pm does set_flags, it needs to send
> out MP_PRIO signal, and also modify the flags of the corresponding address
> entry in the local address list. This patch implements the missing logic.
> 
> Fixes: 892f396c8e68 ("mptcp: netlink: issue MP_PRIO signals from userspace PMs")

If it is a fix, can you extract this patch, and target mptcp-net please?

When you will do that, you will also need to add
mptcp_userspace_pm_lookup_addr() helper: can you do that in the same
patch, but using list_for_each_entry(), not mptcp_for_each_address()
(nor the new version)? That way, it will be easier to backport the patch
without having to depend on other patches or having too many changes.

> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index d815bfa57532..ec2ac0f9c8f5 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -543,6 +543,7 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
>  	struct mptcp_pm_addr_entry rem = { .addr = { .family = AF_UNSPEC }, };
>  	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
>  	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
> +	struct mptcp_pm_addr_entry *entry;
>  	struct mptcp_sock *msk;
>  	int ret = -EINVAL;
>  	struct sock *sk;
> @@ -574,6 +575,16 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
>  	if (loc.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
>  		bkup = 1;
>  
> +	spin_lock_bh(&msk->pm.lock);
> +	entry = mptcp_userspace_pm_lookup_addr(msk, &loc.addr);
> +	if (entry) {
> +		if (bkup)
> +			entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
> +		else
> +			entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
> +	}
> +	spin_unlock_bh(&msk->pm.lock);
> +
>  	lock_sock(sk);
>  	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc.addr, &rem.addr, bkup);
>  	release_sock(sk);

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags
  2024-10-22  9:14 ` [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags Geliang Tang
@ 2024-11-04 18:36   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 18:36 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> This patch updates the interfaces set_flags to reduce repetitive code,
> adds two more parameters "loc" and "rem" for them. These addresses are
> parsed in public helper mptcp_pm_nl_set_flags_doit(), then pass them
> to mptcp_pm_nl_set_flags() and mptcp_userspace_pm_set_flags().
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_netlink.c   | 57 ++++++++++++++++++++++++----------------
>  net/mptcp/pm_userspace.c | 28 ++++++--------------
>  net/mptcp/protocol.h     |  4 ++-
>  3 files changed, 46 insertions(+), 43 deletions(-)
> 
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 5fb1d5d8bf57..5cd5241da3c6 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -2045,10 +2045,10 @@ static int mptcp_nl_set_flags(struct net *net,
>  	return ret;
>  }
>  
> -static int mptcp_pm_nl_set_flags(struct genl_info *info)
> +static int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *loc,
> +				 struct mptcp_addr_info *rem,
> +				 struct genl_info *info)
>  {
> -	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
> -	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
>  	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
>  			   MPTCP_PM_ADDR_FLAG_FULLMESH;
>  	struct net *net = genl_info_net(info);
> @@ -2056,59 +2056,72 @@ static int mptcp_pm_nl_set_flags(struct genl_info *info)
>  	struct pm_nl_pernet *pernet;
>  	u8 lookup_by_id = 0;
>  	u8 bkup = 0;
> -	int ret;
>  
>  	pernet = pm_nl_get_pernet(net);
>  
> -	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
> -	if (ret < 0)
> -		return ret;
> -
> -	if (addr.addr.family == AF_UNSPEC) {
> +	if (loc->addr.family == AF_UNSPEC) {
>  		lookup_by_id = 1;
> -		if (!addr.addr.id) {
> +		if (!loc->addr.id) {
>  			GENL_SET_ERR_MSG(info, "missing required inputs");
>  			return -EOPNOTSUPP;
>  		}
>  	}
>  
> -	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> +	if (loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
>  		bkup = 1;
>  
>  	spin_lock_bh(&pernet->lock);
> -	entry = lookup_by_id ? __lookup_addr_by_id(pernet, addr.addr.id) :
> -			       __lookup_addr(pernet, &addr.addr);
> +	entry = lookup_by_id ? __lookup_addr_by_id(pernet, loc->addr.id) :
> +			       __lookup_addr(pernet, &loc->addr);
>  	if (!entry) {
>  		spin_unlock_bh(&pernet->lock);
>  		GENL_SET_ERR_MSG(info, "address not found");
>  		return -EINVAL;
>  	}
> -	if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
> +	if ((loc->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
>  	    (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
>  		spin_unlock_bh(&pernet->lock);
>  		GENL_SET_ERR_MSG(info, "invalid addr flags");
>  		return -EINVAL;
>  	}
>  
> -	changed = (addr.flags ^ entry->flags) & mask;
> -	entry->flags = (entry->flags & ~mask) | (addr.flags & mask);
> -	addr = *entry;
> +	changed = (loc->flags ^ entry->flags) & mask;
> +	entry->flags = (entry->flags & ~mask) | (loc->flags & mask);
> +	*loc = *entry;
>  	spin_unlock_bh(&pernet->lock);
>  
> -	mptcp_nl_set_flags(net, &addr.addr, bkup, changed);
> +	mptcp_nl_set_flags(net, &loc->addr, bkup, changed);
>  	return 0;
>  }
>  
> -static int mptcp_pm_set_flags(struct genl_info *info)
> +static int mptcp_pm_set_flags(struct mptcp_pm_addr_entry *loc,
> +			      struct mptcp_addr_info *rem,
> +			      struct genl_info *info)
>  {
>  	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
> -		return mptcp_userspace_pm_set_flags(info);
> -	return mptcp_pm_nl_set_flags(info);
> +		return mptcp_userspace_pm_set_flags(loc, rem, info);
> +	return mptcp_pm_nl_set_flags(loc, rem, info);
>  }
>  
>  int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
>  {
> -	return mptcp_pm_set_flags(info);
> +	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
> +	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> +	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];

(detail: maybe clearer to call it "attr_loc", similar to "attr_rem")

> +	struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
> +	int ret;
> +
> +	ret = mptcp_pm_parse_entry(attr, info, false, &loc);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (attr_rem) {
> +		ret = mptcp_pm_parse_addr(attr_rem, info, &rem);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	return mptcp_pm_set_flags(&loc, &rem, info);

Nothing to change here, but linked to a previous comment for another
patch of this series: I think it would be clearer to move
mptcp_pm_nl_set_flags_doit() and similar (mptcp_pm_nl_get_addr_dumpit()
+ mptcp_pm_nl_get_addr_doit()) to pm.c: these helpers are generic,
implemented for each PM.

Similarly, we can move the content of their linked function
(mptcp_pm_set_flags(), mptcp_pm_dump_addr() and mptcp_pm_get_addr()) in
there. If this last step makes sense for the future changes of course,
but for the moment, these helpers are only used in one place, just next
to, and only 3 basic lines: 'if (X) return A; return B'.

>  }
>  
>  static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
(...)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id
  2024-10-22  9:14 ` [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id Geliang Tang
@ 2024-11-04 18:48   ` Matthieu Baerts
  2024-11-07  7:35     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 18:48 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The following code in mptcp_userspace_pm_get_local_id() that assigns "skc"
> to "new_entry" is not allowed in BPF if we use the same code to implement
> the get_local_id() interface of a BFP path manager:

Can you give more details about the fact it is not allowed please?

Do you mean you cannot do the following code in BPF? Why?

> 	memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
> 	new_entry.addr = *skc;
> 	new_entry.addr.id = 0;
> 	new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
> 
> To solve the issue, this patch moves this assignment to "new_entry" forward
> to mptcp_pm_get_local_id(), and then passing "new_entry" as a parameter to
> both mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id().
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm.c           | 10 ++++++++--
>  net/mptcp/pm_netlink.c   | 11 +++--------
>  net/mptcp/pm_userspace.c | 17 ++++++-----------
>  net/mptcp/protocol.h     |  4 ++--
>  4 files changed, 19 insertions(+), 23 deletions(-)
> 
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index b6e6859903ef..d28e844eba2d 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -404,6 +404,7 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
>  {
>  	struct mptcp_addr_info skc_local;
>  	struct mptcp_addr_info msk_local;
> +	struct mptcp_pm_addr_entry local;
>  
>  	if (WARN_ON_ONCE(!msk))
>  		return -1;
> @@ -416,9 +417,14 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
>  	if (mptcp_addresses_equal(&msk_local, &skc_local, false))
>  		return 0;
>  
> +	memset(&local, 0, sizeof(struct mptcp_pm_addr_entry));

Out of curiosity: do you need to call memset() here? Can you not init
"local" when you declare it?

  struct mptcp_pm_addr_entry local = { 0 };

(Or maybe that's not working with C99 with inner structures? I thought
it was, but not sure).

> +	local.addr = skc_local;

Do you still need skc_local? Can you not use 'local.addr' directly
instead above?

> +	local.addr.id = 0;

In pm_netlink.c, 'addr.port' is also reset. Should you not do that here
too? I guess that's fine for the userspace pm, no?

> +	local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
> +
>  	if (mptcp_pm_is_userspace(msk))
> -		return mptcp_userspace_pm_get_local_id(msk, &skc_local);
> -	return mptcp_pm_nl_get_local_id(msk, &skc_local);
> +		return mptcp_userspace_pm_get_local_id(msk, &local);
> +	return mptcp_pm_nl_get_local_id(msk, &local);
>  }
>  
>  bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
(...)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags
  2024-10-22  9:14 ` [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags Geliang Tang
@ 2024-11-04 18:55   ` Matthieu Baerts
  2025-01-14  9:27     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 18:55 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The is_backup() interface of path manager is not very common. A more
> common approach is to add a get_flags() interface to obtain the flags
> value of a given address. Then is_backup() can be implemented through
> get_flags() by test whether backup flag is set in the flags value.

Out of curiosity, is this going to simplify something later on? Because
with this description, it is hard to see the value of this patch.

The backup flag is special: that's the only one that is linked to a bit
that will appear in the packets, the only one that needs to be known by
the other peer. In this case, I think it makes sense to have dedicated
helpers to retrieve this info, and not the rest.

Except if you think we will need to extract the other flags later?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-10-22  9:14 ` [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local Geliang Tang
@ 2024-11-04 19:08   ` Matthieu Baerts
  2024-11-07  7:29     ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:08 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> The following code in mptcp_pm_nl_subflow_create_doit() that assigns struct
> mptcp_pm_addr_entry "entry" to the local struct mptcp_pm_local variable
> "local" is not allowed in BPF if we use the same code to implement the
> subflow_create() interface of a BFP path manager:
> 
> 	struct mptcp_pm_local local;
> 
> 	local.addr = entry.addr;
> 	local.flags = entry.flags;
> 	local.ifindex = entry.ifindex;

Here as well, I'm not sure to understand the issue. Is it because you
cannot allocate this structure locally with BPF? No alternatives?

> We should avoid this type of assignment from struct mptcp_pm_addr_entry to
> struct mptcp_pm_local.
> 
> In fact, there is no need to add a dedicated address entry type for local
> address entry. All its fields are the same as struct mptcp_pm_addr_entry,
> except that it lacks a "lsk" for the listening socket. So we can use struct
> mptcp_pm_addr_entry directly. This makes the path manager code simpler.

There was a need for this structure, see this discussion:


https://lore.kernel.org/mptcp/587e096f-0e76-40fd-9220-6d8dd2930838@redhat.com/

and the changelog in v5:


https://lore.kernel.org/mptcp/20240726-mptcp-pm-avail-v5-13-fb1117ddeef6@kernel.org/

In short ...

> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_netlink.c   | 22 ++++++++--------------
>  net/mptcp/pm_userspace.c |  7 +------
>  net/mptcp/protocol.h     |  8 +-------
>  net/mptcp/subflow.c      |  2 +-
>  4 files changed, 11 insertions(+), 28 deletions(-)
> 
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 287e715bcf68..15f97e7af182 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c

(...)

> @@ -721,7 +715,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
>  
>  static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
>  {
> -	struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
> +	struct mptcp_pm_addr_entry locals[MPTCP_PM_ADDR_MAX];

... we don't want that: that's reserving too much memory, and we don't
need half of it.

*If* it is really needed to change it for BPF (I'm surprised there are
no alternatives), then maybe we can change the signature of
__mptcp_subflow_connect(), but not change the code here.

In this case, only one "struct mptcp_pm_addr_entry" will be needed, and
the "struct mptcp_pm_local" can be defined in this pm_netlink.c file if
it is only used here.

But please mention that in the commit message.

>  	struct sock *sk = (struct sock *)msk;
>  	unsigned int add_addr_accept_max;
>  	struct mptcp_addr_info remote;
(...)

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry
  2024-10-22  9:14 ` [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry Geliang Tang
@ 2024-11-04 19:13   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:13 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> There is no need to add a dedicated address entry type "mptcp_pm_add_entry"
> to represent ADD_ADDR addresses. Additional fields for ADD_ADDR addresses
> can be added into struct mptcp_pm_addr_entry directly. This makes the path
> manager code simpler.
> 
> Here "union" can be used to merge struct mptcp_pm_addr_entry and struct
> mptcp_pm_add_entry into one. Then all mptcp_pm_add_entry can be replaced by
> mptcp_pm_addr_entry.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>

(...)

> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index d9badf270b15..9dc01140af23 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -243,9 +243,19 @@ struct mptcp_pm_data {
>  struct mptcp_pm_addr_entry {
>  	struct list_head	list;
>  	struct mptcp_addr_info	addr;
> -	u8			flags;
> -	int			ifindex;
> -	struct socket		*lsk;
> +	union {
> +		struct {
> +			u8			flags;
> +			int			ifindex;
> +			struct socket		*lsk;
> +		};
> +		/* mptcp_pm_add_entry */
> +		struct {
> +			u8			retrans_times;
> +			struct timer_list	add_timer;

This will increase the size of the structure even more. Please make sure
it is not used in an array (linked to my comment on the previous commit).

> +			struct mptcp_sock	*sock;
> +		};
> +	};
>  };
>  
>  struct mptcp_data_frag {
> @@ -1028,10 +1038,10 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
>  			      const struct mptcp_addr_info *addr);
>  void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
>  bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
> -struct mptcp_pm_add_entry *
> +struct mptcp_pm_addr_entry *
>  mptcp_pm_del_add_timer(struct mptcp_sock *msk,
>  		       const struct mptcp_addr_info *addr, bool check_id);
> -struct mptcp_pm_add_entry *
> +struct mptcp_pm_addr_entry *
>  mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
>  				const struct mptcp_addr_info *addr);
>  int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc,

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry
  2024-10-22  9:14 ` [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry Geliang Tang
@ 2024-11-04 19:17   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:17 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

Good catch!

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> When traversing userspace_pm_local_addr_list and deleting an entry from
> it in mptcp_pm_nl_remove_doit(), msk->pm.lock should be held.
> 
> Fixes: d9a4594edabf ("mptcp: netlink: Add MPTCP_PM_CMD_REMOVE")

Same here, because it is a fix, please extract this patch and target
mptcp-net.

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs
  2024-10-22  9:14 ` [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs Geliang Tang
@ 2024-11-04 19:24   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:24 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> mptcp_pm_remove_addrs() actually only deletes one address, which does
> not match its name. This patch renames it to mptcp_pm_remove_addr_entry()
> and changes the parameter "rm_list" to "entry".
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_netlink.c   | 24 ++++++++++--------------
>  net/mptcp/pm_userspace.c |  2 +-
>  net/mptcp/protocol.h     |  3 ++-
>  3 files changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 06f0c7df575e..852706e43f13 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1615,26 +1615,22 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
>  }
>  
>  /* Called from the userspace PM only */

(out of curiosity: after the modifications you did, could this helper
not be "easily" moved to pm_userspace.c?)

> -void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
> +void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
> +				struct mptcp_pm_addr_entry *entry)
>  {
>  	struct mptcp_rm_list alist = { .nr = 0 };
> -	struct mptcp_pm_addr_entry *entry;
>  	int anno_nr = 0;
>  
> -	list_for_each_entry(entry, rm_list, list) {
> -		if (alist.nr >= MPTCP_RM_IDS_MAX)
> -			break;
> -
> -		/* only delete if either announced or matching a subflow */
> -		if (remove_anno_list_by_saddr(msk, &entry->addr))
> -			anno_nr++;
> -		else if (!lookup_subflow_by_saddr(&msk->conn_list,
> -						  &entry->addr))
> -			continue;
> +	/* only delete if either announced or matching a subflow */
> +	if (remove_anno_list_by_saddr(msk, &entry->addr))
> +		anno_nr++;
> +	else if (!lookup_subflow_by_saddr(&msk->conn_list,
> +					  &entry->addr))

(maybe this can move to the previous line if it is under 80 chars?)

> +		goto out;
>  
> -		alist.ids[alist.nr++] = entry->addr.id;
> -	}
> +	alist.ids[alist.nr++] = entry->addr.id;
>  
> +out:
>  	if (alist.nr) {
>  		spin_lock_bh(&msk->pm.lock);
>  		msk->pm.add_addr_signaled -= anno_nr;
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 3ad10d8062d9..21b2a3b02cfe 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -322,7 +322,7 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  	list_move(&match->list, &free_list);

Do you still need to do this move? Do you still need "free_list"? Can
you just remove the entry from the list?

>  	spin_unlock_bh(&msk->pm.lock);
>  
> -	mptcp_pm_remove_addrs(msk, &free_list);
> +	mptcp_pm_remove_addr_entry(msk, match);
>  
>  	release_sock(sk);
>  
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 9dc01140af23..13cd97f9e0f7 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -1051,7 +1051,8 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
>  			   const struct mptcp_addr_info *addr,
>  			   bool echo);
>  int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
> -void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
> +void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
> +				struct mptcp_pm_addr_entry *entry);
>  
>  void mptcp_free_local_addr_list(struct mptcp_sock *msk);
>  

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries
  2024-10-22  9:14 ` [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries Geliang Tang
@ 2024-11-04 19:27   ` Matthieu Baerts
  0 siblings, 0 replies; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:27 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> With the help of mptcp_pm_remove_addr_entry(), it's no longer necessary to
> move the entry to be deleted to free_list and then traverse the list to
> delete the entry, which is not allowed in BPF. The entry can be directly
> deleted through list_del_rcu() and sock_kfree_s() now.

Maybe clearer to squash this in the previous commit.

> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 14 +++++---------
>  1 file changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 21b2a3b02cfe..e5dfa1a6db31 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -283,9 +283,7 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  {
>  	struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
>  	struct mptcp_pm_addr_entry *match;
> -	struct mptcp_pm_addr_entry *entry;
>  	struct mptcp_sock *msk;
> -	LIST_HEAD(free_list);
>  	int err = -EINVAL;
>  	struct sock *sk;
>  	u8 id_val;
> @@ -312,23 +310,21 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
>  
>  	spin_lock_bh(&msk->pm.lock);
>  	match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);

Can you not remove the entry from the list here (if there is a match?)

> +	spin_unlock_bh(&msk->pm.lock);
>  	if (!match) {
>  		GENL_SET_ERR_MSG(info, "address with specified id not found");
> -		spin_unlock_bh(&msk->pm.lock);
>  		release_sock(sk);
>  		goto out;
>  	}
>  
> -	list_move(&match->list, &free_list);

(or keep the del here, no?)

> -	spin_unlock_bh(&msk->pm.lock);
> -
>  	mptcp_pm_remove_addr_entry(msk, match);
>  
>  	release_sock(sk);
>  
> -	list_for_each_entry_safe(match, entry, &free_list, list) {
> -		sock_kfree_s(sk, match, sizeof(*match));
> -	}
> +	spin_lock_bh(&msk->pm.lock);
> +	list_del_rcu(&match->list);
> +	sock_kfree_s(sk, match, sizeof(*match));
> +	spin_unlock_bh(&msk->pm.lock);
>  
>  	err = 0;
>  out:

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 00/36] BPF path manager
  2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
                   ` (37 preceding siblings ...)
  2024-10-22 10:24 ` MPTCP CI
@ 2024-11-04 19:31 ` Matthieu Baerts
  2024-11-05 10:12   ` Geliang Tang
  38 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-04 19:31 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 22/10/2024 11:14, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> v2:
>  - add BPF-related code in this set (32-36).

I did a review of the patches up to 28/36 included.

If you want, you can send a v3 without patches 29-36: the series is very
long, that's hard to review such long series. We can check this part
later. WDYT?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 00/36] BPF path manager
  2024-11-04 19:31 ` Matthieu Baerts
@ 2024-11-05 10:12   ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-11-05 10:12 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Mon, 2024-11-04 at 20:31 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > v2:
> >  - add BPF-related code in this set (32-36).
> 
> I did a review of the patches up to 28/36 included.
> 
> If you want, you can send a v3 without patches 29-36: the series is

Thanks Matt, please send a v3 of "mptcp: pm: use _rcu variant under
rcu_read_lock" first. Then I'll send a v3 of this set based on it.

-Geliang

> very
> long, that's hard to review such long series. We can check this part
> later. WDYT?
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-11-04 19:08   ` Matthieu Baerts
@ 2024-11-07  7:29     ` Geliang Tang
  2024-11-07 10:00       ` Matthieu Baerts
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-11-07  7:29 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Mon, 2024-11-04 at 20:08 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The following code in mptcp_pm_nl_subflow_create_doit() that
> > assigns struct
> > mptcp_pm_addr_entry "entry" to the local struct mptcp_pm_local
> > variable
> > "local" is not allowed in BPF if we use the same code to implement
> > the
> > subflow_create() interface of a BFP path manager:
> > 
> > 	struct mptcp_pm_local local;
> > 
> > 	local.addr = entry.addr;
> > 	local.flags = entry.flags;
> > 	local.ifindex = entry.ifindex;
> 
> Here as well, I'm not sure to understand the issue. Is it because you
> cannot allocate this structure locally with BPF? No alternatives?

Here "struct mptcp_pm_local local" is a "scalar", when passing it to
__mptcp_subflow_connect(), this error occurs:

# ; err = __mptcp_subflow_connect(sk, &local, remote); @
mptcp_bpf_userspace_pm.c:242
# 53: (bf) r1 = r6                      ; R1_w=trusted_ptr_mptcp_sock()
R6=trusted_ptr_mptcp_sock()
# 54: (bf) r3 = r8                      ;
R3_w=trusted_ptr_mptcp_addr_info() R8=trusted_ptr_mptcp_addr_info()
# 55: (85) call __mptcp_subflow_connect#34404
# max struct nesting depth exceeded
# arg#1 pointer type STRUCT mptcp_pm_local must point to scalar, or
struct with scalar

Also, assigning an address to an address like this is not allowed in
BPF:

	local.addr = entry.addr;

> 
> > We should avoid this type of assignment from struct
> > mptcp_pm_addr_entry to
> > struct mptcp_pm_local.
> > 
> > In fact, there is no need to add a dedicated address entry type for
> > local
> > address entry. All its fields are the same as struct
> > mptcp_pm_addr_entry,
> > except that it lacks a "lsk" for the listening socket. So we can
> > use struct
> > mptcp_pm_addr_entry directly. This makes the path manager code
> > simpler.
> 
> There was a need for this structure, see this discussion:
> 
> 
> https://lore.kernel.org/mptcp/587e096f-0e76-40fd-9220-6d8dd2930838@redhat.com/
> 
> and the changelog in v5:
> 
> 
> https://lore.kernel.org/mptcp/20240726-mptcp-pm-avail-v5-13-fb1117ddeef6@kernel.org/
> 
> In short ...
> 
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> >  net/mptcp/pm_netlink.c   | 22 ++++++++--------------
> >  net/mptcp/pm_userspace.c |  7 +------
> >  net/mptcp/protocol.h     |  8 +-------
> >  net/mptcp/subflow.c      |  2 +-
> >  4 files changed, 11 insertions(+), 28 deletions(-)
> > 
> > diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> > index 287e715bcf68..15f97e7af182 100644
> > --- a/net/mptcp/pm_netlink.c
> > +++ b/net/mptcp/pm_netlink.c
> 
> (...)
> 
> > @@ -721,7 +715,7 @@ static unsigned int
> > fill_local_addresses_vec(struct mptcp_sock *msk,
> >  
> >  static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
> >  {
> > -	struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
> > +	struct mptcp_pm_addr_entry locals[MPTCP_PM_ADDR_MAX];
> 
> ... we don't want that: that's reserving too much memory, and we
> don't
> need half of it.

Thanks for your information.

> 
> *If* it is really needed to change it for BPF (I'm surprised there
> are
> no alternatives), then maybe we can change the signature of
> __mptcp_subflow_connect(), but not change the code here.
> 
> In this case, only one "struct mptcp_pm_addr_entry" will be needed,
> and
> the "struct mptcp_pm_local" can be defined in this pm_netlink.c file
> if
> it is only used here.
> 
> But please mention that in the commit message.

I updated it in v3 as you suggested.

Thanks,
-Geliang

> 
> >  	struct sock *sk = (struct sock *)msk;
> >  	unsigned int add_addr_accept_max;
> >  	struct mptcp_addr_info remote;
> (...)
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id
  2024-11-04 18:48   ` Matthieu Baerts
@ 2024-11-07  7:35     ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-11-07  7:35 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Mon, 2024-11-04 at 19:48 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The following code in mptcp_userspace_pm_get_local_id() that
> > assigns "skc"
> > to "new_entry" is not allowed in BPF if we use the same code to
> > implement
> > the get_local_id() interface of a BFP path manager:
> 
> Can you give more details about the fact it is not allowed please?
> 
> Do you mean you cannot do the following code in BPF? Why?

Same as in patch 23, passing "new_entry" to
mptcp_userspace_pm_append_new_local_addr() will get an error:

"pointer type STRUCT mptcp_pm_addr_entry must point to scalar, or
struct with scalar".

And assigning an address to an address like this is not allowed in
BPF:

	new_entry.addr = *skc;

> 
> > 	memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
> > 	new_entry.addr = *skc;
> > 	new_entry.addr.id = 0;
> > 	new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
> > 
> > To solve the issue, this patch moves this assignment to "new_entry"
> > forward
> > to mptcp_pm_get_local_id(), and then passing "new_entry" as a
> > parameter to
> > both mptcp_pm_nl_get_local_id() and
> > mptcp_userspace_pm_get_local_id().
> > 
> > Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> > ---
> >  net/mptcp/pm.c           | 10 ++++++++--
> >  net/mptcp/pm_netlink.c   | 11 +++--------
> >  net/mptcp/pm_userspace.c | 17 ++++++-----------
> >  net/mptcp/protocol.h     |  4 ++--
> >  4 files changed, 19 insertions(+), 23 deletions(-)
> > 
> > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > index b6e6859903ef..d28e844eba2d 100644
> > --- a/net/mptcp/pm.c
> > +++ b/net/mptcp/pm.c
> > @@ -404,6 +404,7 @@ int mptcp_pm_get_local_id(struct mptcp_sock
> > *msk, struct sock_common *skc)
> >  {
> >  	struct mptcp_addr_info skc_local;
> >  	struct mptcp_addr_info msk_local;
> > +	struct mptcp_pm_addr_entry local;
> >  
> >  	if (WARN_ON_ONCE(!msk))
> >  		return -1;
> > @@ -416,9 +417,14 @@ int mptcp_pm_get_local_id(struct mptcp_sock
> > *msk, struct sock_common *skc)
> >  	if (mptcp_addresses_equal(&msk_local, &skc_local, false))
> >  		return 0;
> >  
> > +	memset(&local, 0, sizeof(struct mptcp_pm_addr_entry));
> 
> Out of curiosity: do you need to call memset() here? Can you not init
> "local" when you declare it?
> 
>   struct mptcp_pm_addr_entry local = { 0 };

Updated in v3.

> 
> (Or maybe that's not working with C99 with inner structures? I
> thought
> it was, but not sure).
> 
> > +	local.addr = skc_local;
> 
> Do you still need skc_local? Can you not use 'local.addr' directly
> instead above?
> 
> > +	local.addr.id = 0;
> 
> In pm_netlink.c, 'addr.port' is also reset. Should you not do that
> here
> too? I guess that's fine for the userspace pm, no?

Updated in v3.

Thanks,
-Geliang

> 
> > +	local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
> > +
> >  	if (mptcp_pm_is_userspace(msk))
> > -		return mptcp_userspace_pm_get_local_id(msk,
> > &skc_local);
> > -	return mptcp_pm_nl_get_local_id(msk, &skc_local);
> > +		return mptcp_userspace_pm_get_local_id(msk,
> > &local);
> > +	return mptcp_pm_nl_get_local_id(msk, &local);
> >  }
> >  
> >  bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common
> > *skc)
> (...)
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-11-07  7:29     ` Geliang Tang
@ 2024-11-07 10:00       ` Matthieu Baerts
  2024-11-07 10:19         ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Matthieu Baerts @ 2024-11-07 10:00 UTC (permalink / raw)
  To: Geliang Tang, mptcp; +Cc: Geliang Tang

Hi Geliang,

On 07/11/2024 08:29, Geliang Tang wrote:
> Hi Matt,
> 
> On Mon, 2024-11-04 at 20:08 +0100, Matthieu Baerts wrote:
>> Hi Geliang,
>>
>> On 22/10/2024 11:14, Geliang Tang wrote:
>>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>>
>>> The following code in mptcp_pm_nl_subflow_create_doit() that
>>> assigns struct
>>> mptcp_pm_addr_entry "entry" to the local struct mptcp_pm_local
>>> variable
>>> "local" is not allowed in BPF if we use the same code to implement
>>> the
>>> subflow_create() interface of a BFP path manager:
>>>
>>> 	struct mptcp_pm_local local;
>>>
>>> 	local.addr = entry.addr;
>>> 	local.flags = entry.flags;
>>> 	local.ifindex = entry.ifindex;
>>
>> Here as well, I'm not sure to understand the issue. Is it because you
>> cannot allocate this structure locally with BPF? No alternatives?
> 
> Here "struct mptcp_pm_local local" is a "scalar", when passing it to
> __mptcp_subflow_connect(), this error occurs:
> 
> # ; err = __mptcp_subflow_connect(sk, &local, remote); @
> mptcp_bpf_userspace_pm.c:242
> # 53: (bf) r1 = r6                      ; R1_w=trusted_ptr_mptcp_sock()
> R6=trusted_ptr_mptcp_sock()
> # 54: (bf) r3 = r8                      ;
> R3_w=trusted_ptr_mptcp_addr_info() R8=trusted_ptr_mptcp_addr_info()
> # 55: (85) call __mptcp_subflow_connect#34404
> # max struct nesting depth exceeded
> # arg#1 pointer type STRUCT mptcp_pm_local must point to scalar, or
> struct with scalar
> 
> Also, assigning an address to an address like this is not allowed in
> BPF:
> 
> 	local.addr = entry.addr;

OK, thank you, that's a bit clearer (even if it is not clear what BPF
code was causing that). For this kind of issue, would it work to add a
BPF-specific kfunc, eventually with additional annotations or arguments,
or taking a "struct mptcp_pm_addr_entry" in argument, and "simply"
calling __mptcp_subflow_connect() with a "struct mptcp_pm_local"?

So something specific to BPF, without impacting the rest?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-11-07 10:00       ` Matthieu Baerts
@ 2024-11-07 10:19         ` Geliang Tang
  2024-11-10  4:32           ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-11-07 10:19 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Thu, 2024-11-07 at 11:00 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 07/11/2024 08:29, Geliang Tang wrote:
> > Hi Matt,
> > 
> > On Mon, 2024-11-04 at 20:08 +0100, Matthieu Baerts wrote:
> > > Hi Geliang,
> > > 
> > > On 22/10/2024 11:14, Geliang Tang wrote:
> > > > From: Geliang Tang <tanggeliang@kylinos.cn>
> > > > 
> > > > The following code in mptcp_pm_nl_subflow_create_doit() that
> > > > assigns struct
> > > > mptcp_pm_addr_entry "entry" to the local struct mptcp_pm_local
> > > > variable
> > > > "local" is not allowed in BPF if we use the same code to
> > > > implement
> > > > the
> > > > subflow_create() interface of a BFP path manager:
> > > > 
> > > > 	struct mptcp_pm_local local;
> > > > 
> > > > 	local.addr = entry.addr;
> > > > 	local.flags = entry.flags;
> > > > 	local.ifindex = entry.ifindex;
> > > 
> > > Here as well, I'm not sure to understand the issue. Is it because
> > > you
> > > cannot allocate this structure locally with BPF? No alternatives?
> > 
> > Here "struct mptcp_pm_local local" is a "scalar", when passing it
> > to
> > __mptcp_subflow_connect(), this error occurs:
> > 
> > # ; err = __mptcp_subflow_connect(sk, &local, remote); @
> > mptcp_bpf_userspace_pm.c:242
> > # 53: (bf) r1 = r6                      ;
> > R1_w=trusted_ptr_mptcp_sock()
> > R6=trusted_ptr_mptcp_sock()
> > # 54: (bf) r3 = r8                      ;
> > R3_w=trusted_ptr_mptcp_addr_info() R8=trusted_ptr_mptcp_addr_info()
> > # 55: (85) call __mptcp_subflow_connect#34404
> > # max struct nesting depth exceeded
> > # arg#1 pointer type STRUCT mptcp_pm_local must point to scalar, or
> > struct with scalar
> > 
> > Also, assigning an address to an address like this is not allowed
> > in
> > BPF:
> > 
> > 	local.addr = entry.addr;
> 
> OK, thank you, that's a bit clearer (even if it is not clear what BPF
> code was causing that). For this kind of issue, would it work to add
> a
> BPF-specific kfunc, eventually with additional annotations or
> arguments,
> or taking a "struct mptcp_pm_addr_entry" in argument, and "simply"
> calling __mptcp_subflow_connect() with a "struct mptcp_pm_local"?

It works indeed. But I prefer the version in v3, "mptcp: use
mptcp_pm_local in pm_netlink only". It makes more sense to move
mptcp_pm_local in pm_netlink.c.

WDYT?

Thanks,
-Geliang

> 
> So something specific to BPF, without impacting the rest?
> 
> Cheers,
> Matt


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-11-07 10:19         ` Geliang Tang
@ 2024-11-10  4:32           ` Geliang Tang
  2024-11-27  6:17             ` Geliang Tang
  0 siblings, 1 reply; 77+ messages in thread
From: Geliang Tang @ 2024-11-10  4:32 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Thu, 2024-11-07 at 18:19 +0800, Geliang Tang wrote:
> Hi Matt,
> 
> On Thu, 2024-11-07 at 11:00 +0100, Matthieu Baerts wrote:
> > Hi Geliang,
> > 
> > On 07/11/2024 08:29, Geliang Tang wrote:
> > > Hi Matt,
> > > 
> > > On Mon, 2024-11-04 at 20:08 +0100, Matthieu Baerts wrote:
> > > > Hi Geliang,
> > > > 
> > > > On 22/10/2024 11:14, Geliang Tang wrote:
> > > > > From: Geliang Tang <tanggeliang@kylinos.cn>
> > > > > 
> > > > > The following code in mptcp_pm_nl_subflow_create_doit() that
> > > > > assigns struct
> > > > > mptcp_pm_addr_entry "entry" to the local struct
> > > > > mptcp_pm_local
> > > > > variable
> > > > > "local" is not allowed in BPF if we use the same code to
> > > > > implement
> > > > > the
> > > > > subflow_create() interface of a BFP path manager:
> > > > > 
> > > > > 	struct mptcp_pm_local local;
> > > > > 
> > > > > 	local.addr = entry.addr;
> > > > > 	local.flags = entry.flags;
> > > > > 	local.ifindex = entry.ifindex;
> > > > 
> > > > Here as well, I'm not sure to understand the issue. Is it
> > > > because
> > > > you
> > > > cannot allocate this structure locally with BPF? No
> > > > alternatives?
> > > 
> > > Here "struct mptcp_pm_local local" is a "scalar", when passing it
> > > to
> > > __mptcp_subflow_connect(), this error occurs:
> > > 
> > > # ; err = __mptcp_subflow_connect(sk, &local, remote); @
> > > mptcp_bpf_userspace_pm.c:242
> > > # 53: (bf) r1 = r6                      ;
> > > R1_w=trusted_ptr_mptcp_sock()
> > > R6=trusted_ptr_mptcp_sock()
> > > # 54: (bf) r3 = r8                      ;
> > > R3_w=trusted_ptr_mptcp_addr_info()
> > > R8=trusted_ptr_mptcp_addr_info()
> > > # 55: (85) call __mptcp_subflow_connect#34404
> > > # max struct nesting depth exceeded
> > > # arg#1 pointer type STRUCT mptcp_pm_local must point to scalar,
> > > or
> > > struct with scalar
> > > 
> > > Also, assigning an address to an address like this is not allowed
> > > in
> > > BPF:
> > > 
> > > 	local.addr = entry.addr;
> > 
> > OK, thank you, that's a bit clearer (even if it is not clear what
> > BPF
> > code was causing that). For this kind of issue, would it work to
> > add
> > a
> > BPF-specific kfunc, eventually with additional annotations or
> > arguments,
> > or taking a "struct mptcp_pm_addr_entry" in argument, and "simply"
> > calling __mptcp_subflow_connect() with a "struct mptcp_pm_local"?
> 
> It works indeed. But I prefer the version in v3, "mptcp: use
> mptcp_pm_local in pm_netlink only". It makes more sense to move
> mptcp_pm_local in pm_netlink.c.

I thought about it again and felt that "mptcp: use mptcp_pm_local in
pm_netlink only" was not a good solution. If we want to add fullmesh
support to userspace pm in the future, we also need to use struct
mptcp_pm_local in pm_netlink.c.

So I decided to deprecate "mptcp: use mptcp_pm_local in pm_netlink
only" and keep the code for struct mptcp_pm_local as it is. As you
suggested, add a BPF-specific kfunc to solve the issue.

Thanks,
-Geliang

> 
> WDYT?
> 
> Thanks,
> -Geliang
> 
> > 
> > So something specific to BPF, without impacting the rest?
> > 
> > Cheers,
> > Matt
> 
> 


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

* Re: [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local
  2024-11-10  4:32           ` Geliang Tang
@ 2024-11-27  6:17             ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2024-11-27  6:17 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

Hi Matt,

On Sun, 2024-11-10 at 12:32 +0800, Geliang Tang wrote:
> Hi Matt,
> 
> On Thu, 2024-11-07 at 18:19 +0800, Geliang Tang wrote:
> > Hi Matt,
> > 
> > On Thu, 2024-11-07 at 11:00 +0100, Matthieu Baerts wrote:
> > > Hi Geliang,
> > > 
> > > On 07/11/2024 08:29, Geliang Tang wrote:
> > > > Hi Matt,
> > > > 
> > > > On Mon, 2024-11-04 at 20:08 +0100, Matthieu Baerts wrote:
> > > > > Hi Geliang,
> > > > > 
> > > > > On 22/10/2024 11:14, Geliang Tang wrote:
> > > > > > From: Geliang Tang <tanggeliang@kylinos.cn>
> > > > > > 
> > > > > > The following code in mptcp_pm_nl_subflow_create_doit()
> > > > > > that
> > > > > > assigns struct
> > > > > > mptcp_pm_addr_entry "entry" to the local struct
> > > > > > mptcp_pm_local
> > > > > > variable
> > > > > > "local" is not allowed in BPF if we use the same code to
> > > > > > implement
> > > > > > the
> > > > > > subflow_create() interface of a BFP path manager:
> > > > > > 
> > > > > > 	struct mptcp_pm_local local;
> > > > > > 
> > > > > > 	local.addr = entry.addr;
> > > > > > 	local.flags = entry.flags;
> > > > > > 	local.ifindex = entry.ifindex;
> > > > > 
> > > > > Here as well, I'm not sure to understand the issue. Is it
> > > > > because
> > > > > you
> > > > > cannot allocate this structure locally with BPF? No
> > > > > alternatives?
> > > > 
> > > > Here "struct mptcp_pm_local local" is a "scalar", when passing
> > > > it
> > > > to
> > > > __mptcp_subflow_connect(), this error occurs:
> > > > 
> > > > # ; err = __mptcp_subflow_connect(sk, &local, remote); @
> > > > mptcp_bpf_userspace_pm.c:242
> > > > # 53: (bf) r1 = r6                      ;
> > > > R1_w=trusted_ptr_mptcp_sock()
> > > > R6=trusted_ptr_mptcp_sock()
> > > > # 54: (bf) r3 = r8                      ;
> > > > R3_w=trusted_ptr_mptcp_addr_info()
> > > > R8=trusted_ptr_mptcp_addr_info()
> > > > # 55: (85) call __mptcp_subflow_connect#34404
> > > > # max struct nesting depth exceeded
> > > > # arg#1 pointer type STRUCT mptcp_pm_local must point to
> > > > scalar,
> > > > or
> > > > struct with scalar
> > > > 
> > > > Also, assigning an address to an address like this is not
> > > > allowed
> > > > in
> > > > BPF:
> > > > 
> > > > 	local.addr = entry.addr;
> > > 
> > > OK, thank you, that's a bit clearer (even if it is not clear what
> > > BPF
> > > code was causing that). For this kind of issue, would it work to
> > > add
> > > a
> > > BPF-specific kfunc, eventually with additional annotations or
> > > arguments,
> > > or taking a "struct mptcp_pm_addr_entry" in argument, and
> > > "simply"
> > > calling __mptcp_subflow_connect() with a "struct mptcp_pm_local"?
> > 
> > It works indeed. But I prefer the version in v3, "mptcp: use
> > mptcp_pm_local in pm_netlink only". It makes more sense to move
> > mptcp_pm_local in pm_netlink.c.
> 
> I thought about it again and felt that "mptcp: use mptcp_pm_local in
> pm_netlink only" was not a good solution. If we want to add fullmesh
> support to userspace pm in the future, we also need to use struct

I remember that we have implemented fullmesh in userspace pm in [1]. It
seems that struct mptcp_pm_local is indeed not needed in userspace_pm.
I am a little confused about whether to use "mptcp: use mptcp_pm_local
in pm_netlink only". I would like to hear your opinion.

[1]
https://patchwork.kernel.org/project/mptcp/patch/212f56895715a7e17577076cbe3a7dff9e3ea360.1695631132.git.geliang.tang@suse.com/


> mptcp_pm_local in pm_netlink.c.

It should be "in userspace_pm.c" in this line, not pm_netlink.c.

Thanks,
-Geliang

> 
> So I decided to deprecate "mptcp: use mptcp_pm_local in pm_netlink
> only" and keep the code for struct mptcp_pm_local as it is. As you
> suggested, add a BPF-specific kfunc to solve the issue.
> 
> Thanks,
> -Geliang
> 
> > 
> > WDYT?
> > 
> > Thanks,
> > -Geliang
> > 
> > > 
> > > So something specific to BPF, without impacting the rest?
> > > 
> > > Cheers,
> > > Matt
> > 
> > 
> 
> 


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

* Re: [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags
  2024-11-04 18:55   ` Matthieu Baerts
@ 2025-01-14  9:27     ` Geliang Tang
  0 siblings, 0 replies; 77+ messages in thread
From: Geliang Tang @ 2025-01-14  9:27 UTC (permalink / raw)
  To: Matthieu Baerts, mptcp; +Cc: Geliang Tang

On Mon, 2024-11-04 at 19:55 +0100, Matthieu Baerts wrote:
> Hi Geliang,
> 
> On 22/10/2024 11:14, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> > 
> > The is_backup() interface of path manager is not very common. A
> > more
> > common approach is to add a get_flags() interface to obtain the
> > flags
> > value of a given address. Then is_backup() can be implemented
> > through
> > get_flags() by test whether backup flag is set in the flags value.
> 
> Out of curiosity, is this going to simplify something later on?
> Because
> with this description, it is hard to see the value of this patch.
> 
> The backup flag is special: that's the only one that is linked to a
> bit
> that will appear in the packets, the only one that needs to be known
> by
> the other peer. In this case, I think it makes sense to have
> dedicated
> helpers to retrieve this info, and not the rest.
> 
> Except if you think we will need to extract the other flags later?

Yes, I am preparing for the use of other flags in the future. In that
case, we don't need to add another function pointer interface in struct
mptcp_pm_ops.

This patch is resent in "BPF path manager, part 3".

Thanks,
-Geliang

> 
> Cheers,
> Matt


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

end of thread, other threads:[~2025-01-14  9:27 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-22  9:14 [PATCH mptcp-next v2 00/36] BPF path manager Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 01/36] mptcp: drop else in mptcp_pm_addr_families_match Geliang Tang
2024-10-22 17:01   ` Matthieu Baerts
2024-10-23  9:53     ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 02/36] mptcp: use __lookup_addr in pm_netlink Geliang Tang
2024-10-22 17:09   ` Matthieu Baerts
2024-10-23  9:59     ` Geliang Tang
2024-10-23 10:03       ` Matthieu Baerts
2024-10-23 10:06         ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 03/36] mptcp: add mptcp_for_each_address macros Geliang Tang
2024-10-30 18:20   ` Matthieu Baerts
2024-10-31  7:55     ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 04/36] mptcp: use sock_kfree_s instead of kfree Geliang Tang
2024-10-30 18:21   ` Matthieu Baerts
2024-10-31  7:43     ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 05/36] mptcp: add lookup_addr for userspace pm Geliang Tang
2024-10-30 18:21   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 06/36] mptcp: add mptcp_userspace_pm_get_sock helper Geliang Tang
2024-10-30 18:23   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 07/36] mptcp: make three pm wrappers static Geliang Tang
2024-10-30 18:31   ` Matthieu Baerts
2024-10-31  7:58     ` Geliang Tang
2024-10-31 16:33       ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 08/36] mptcp: drop skb parameter of get_addr Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 09/36] mptcp: add id parameter for get_addr Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 10/36] mptcp: add addr " Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 11/36] mptcp: reuse sending nlmsg code in get_addr Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 12/36] mptcp: change info of get_addr as const Geliang Tang
2024-10-31 18:41   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 13/36] mptcp: add struct mptcp_id_bitmap Geliang Tang
2024-10-31 18:45   ` Matthieu Baerts
2024-11-04  9:12     ` Geliang Tang
2024-11-04 10:16       ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 14/36] mptcp: refactor dump_addr with id bitmap Geliang Tang
2024-11-04 17:18   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 15/36] mptcp: refactor dump_addr with get_addr Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 16/36] mptcp: reuse sending nlmsg code in dump_addr Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 17/36] mptcp: update local address flags when setting it Geliang Tang
2024-11-04 18:20   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 18/36] mptcp: change rem type of set_flags Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 19/36] mptcp: drop skb parameter " Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 20/36] mptcp: add loc and rem for set_flags Geliang Tang
2024-11-04 18:36   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 21/36] mptcp: update address type of get_local_id Geliang Tang
2024-11-04 18:48   ` Matthieu Baerts
2024-11-07  7:35     ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 22/36] mptcp: change is_backup interfaces as get_flags Geliang Tang
2024-11-04 18:55   ` Matthieu Baerts
2025-01-14  9:27     ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 23/36] mptcp: drop struct mptcp_pm_local Geliang Tang
2024-11-04 19:08   ` Matthieu Baerts
2024-11-07  7:29     ` Geliang Tang
2024-11-07 10:00       ` Matthieu Baerts
2024-11-07 10:19         ` Geliang Tang
2024-11-10  4:32           ` Geliang Tang
2024-11-27  6:17             ` Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 24/36] mptcp: drop struct mptcp_pm_add_entry Geliang Tang
2024-11-04 19:13   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 25/36] mptcp: change local type of subflow_destroy Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 26/36] mptcp: hold pm lock when deleting entry Geliang Tang
2024-11-04 19:17   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 27/36] mptcp: rename mptcp_pm_remove_addrs Geliang Tang
2024-11-04 19:24   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 28/36] mptcp: drop free_list for deleting entries Geliang Tang
2024-11-04 19:27   ` Matthieu Baerts
2024-10-22  9:14 ` [PATCH mptcp-next v2 29/36] mptcp: define struct mptcp_pm_ops Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 30/36] mptcp: implement userspace pm interfaces Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 31/36] mptcp: register default userspace pm Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 32/36] bpf: Add mptcp path manager struct_ops Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 33/36] bpf: Register mptcp struct_ops kfunc set Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 34/36] Squash to "bpf: Export mptcp packet scheduler helpers" Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 35/36] selftests/bpf: Add mptcp userspace pm subtest Geliang Tang
2024-10-22  9:14 ` [PATCH mptcp-next v2 36/36] selftests/bpf: Add mptcp bpf path manager subtest Geliang Tang
2024-10-22 10:12 ` [PATCH mptcp-next v2 00/36] BPF path manager MPTCP CI
2024-10-22 10:24 ` MPTCP CI
2024-11-04 19:31 ` Matthieu Baerts
2024-11-05 10:12   ` Geliang Tang

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.