* [PATCH mptcp-next v2 0/3] BPF path manager, part 4
@ 2025-01-15 10:09 Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 1/3] mptcp: define struct mptcp_pm_ops Geliang Tang
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-15 10:09 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
v2:
- update get_local_id interface in patch 2.
Depends on: "BPF path manager, part 3" v3
Based-on: <cover.1736935086.git.tanggeliang@kylinos.cn>
get_addr() and dump_addr() interfaces of BPF userspace pm are dropped
as Matt suggested.
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);
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
Geliang Tang (3):
mptcp: define struct mptcp_pm_ops
mptcp: register default userspace pm
mptcp: init and release mptcp_pm_ops
include/net/mptcp.h | 27 +++
net/mptcp/pm.c | 8 +
net/mptcp/pm_userspace.c | 376 ++++++++++++++++++++++++++++-----------
net/mptcp/protocol.c | 1 +
net/mptcp/protocol.h | 9 +
5 files changed, 317 insertions(+), 104 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH mptcp-next v2 1/3] mptcp: define struct mptcp_pm_ops
2025-01-15 10:09 [PATCH mptcp-next v2 0/3] BPF path manager, part 4 Geliang Tang
@ 2025-01-15 10:09 ` Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm Geliang Tang
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-15 10:09 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 | 27 +++++++++++++++++++
net/mptcp/pm_userspace.c | 57 ++++++++++++++++++++++++++++++++++++++++
net/mptcp/protocol.h | 5 ++++
3 files changed, 89 insertions(+)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 94d5976f7b8d..0918b91a29ab 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -14,6 +14,7 @@
struct mptcp_info;
struct mptcp_sock;
+struct mptcp_pm_addr_entry;
struct seq_file;
/* MPTCP sk_buff extension data */
@@ -120,6 +121,32 @@ 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);
+ 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 1713e9bb6945..2fdee6f22113 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -4,6 +4,8 @@
* Copyright (c) 2022, Intel Corporation.
*/
+#include <linux/rculist.h>
+#include <linux/spinlock.h>
#include "protocol.h"
#include "mib.h"
#include "mptcp_pm_gen.h"
@@ -12,6 +14,9 @@
list_for_each_entry(__entry, \
&((__msk)->pm.userspace_pm_local_addr_list), list)
+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;
@@ -681,3 +686,55 @@ 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->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 e8d8236a40e1..64254c57be01 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1048,6 +1048,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.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm
2025-01-15 10:09 [PATCH mptcp-next v2 0/3] BPF path manager, part 4 Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 1/3] mptcp: define struct mptcp_pm_ops Geliang Tang
@ 2025-01-15 10:09 ` Geliang Tang
2025-01-16 2:43 ` Geliang Tang
2025-01-16 3:06 ` Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 3/3] mptcp: init and release mptcp_pm_ops Geliang Tang
2025-01-15 11:16 ` [PATCH mptcp-next v2 0/3] BPF path manager, part 4 MPTCP CI
3 siblings, 2 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-15 10:09 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().
Extract address_announce() interface of the userspace PM 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 of the userspace PM 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.
Extract subflow_create() interface of the userspace PM 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 of the userspace PM 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.
Extract set_flags() interface of the userspace PM from function
mptcp_userspace_pm_set_flags(), only leave the code for obtaining
msk through "info" in this function.
All fives interfaces are invoked under holding the msk socket lock.
Extract get_local_id() interface of the userspace PM from function
mptcp_userspace_pm_get_local_id(), only leave the code for setting
new address entry in this function.
get_flags() interface of the userspace PM is defined as the same as
the function mptcp_userspace_pm_get_flags(), then this function
becomes a wrapper.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/pm.c | 1 +
net/mptcp/pm_userspace.c | 275 ++++++++++++++++++++++++---------------
net/mptcp/protocol.h | 1 +
3 files changed, 173 insertions(+), 104 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index e275be73b963..3b47c2380a44 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -646,4 +646,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 2fdee6f22113..c03201c95fea 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -135,32 +135,40 @@ 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_addr_info *skc)
+static int userspace_pm_get_local_id(struct mptcp_sock *msk,
+ struct mptcp_pm_addr_entry *local)
{
- struct mptcp_pm_addr_entry *entry = NULL, new_entry;
__be16 msk_sport = ((struct inet_sock *)
inet_sk((struct sock *)msk))->inet_sport;
+ struct mptcp_pm_addr_entry *entry;
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;
+ if (local->addr.port == msk_sport)
+ local->addr.port = 0;
+
+ return mptcp_userspace_pm_append_new_local_addr(msk, local, true);
+}
+
+int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
+ struct mptcp_addr_info *skc)
+{
+ struct mptcp_pm_addr_entry new_entry;
+
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;
-
- return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
+ return userspace_pm_get_local_id(msk, &new_entry);
}
-u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
- struct mptcp_addr_info *skc)
+static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
+ struct mptcp_addr_info *skc)
{
struct mptcp_pm_addr_entry *entry;
u8 flags;
@@ -173,6 +181,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 mptcp_sock *msk;
@@ -198,6 +212,28 @@ 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;
+
+ 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 mptcp_pm_addr_entry addr_val;
@@ -232,26 +268,13 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
goto announce_err;
}
- err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
- if (err < 0) {
- NL_SET_ERR_MSG_ATTR(info->extack, addr,
- "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)
+ NL_SET_ERR_MSG_ATTR(info->extack, addr,
+ "did not match address and id");
- err = 0;
announce_err:
sock_put(sk);
return err;
@@ -301,9 +324,32 @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
spin_unlock_bh(&msk->pm.lock);
}
+static int userspace_pm_address_remove(struct mptcp_sock *msk, u8 id)
+{
+ struct mptcp_pm_addr_entry *entry;
+
+ if (id == 0)
+ return mptcp_userspace_pm_remove_id_zero_address(msk);
+
+ spin_lock_bh(&msk->pm.lock);
+ entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+ if (!entry) {
+ spin_unlock_bh(&msk->pm.lock);
+ return -EINVAL;
+ }
+
+ list_del_rcu(&entry->list);
+ spin_unlock_bh(&msk->pm.lock);
+
+ mptcp_pm_remove_addr_entry(msk, entry);
+
+ sock_kfree_s((struct sock *)msk, entry, sizeof(*entry));
+
+ return 0;
+}
+
int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
{
- struct mptcp_pm_addr_entry *match;
struct mptcp_sock *msk;
struct nlattr *id;
int err = -EINVAL;
@@ -323,32 +369,8 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
sk = (struct sock *)msk;
lock_sock(sk);
-
- if (id_val == 0) {
- err = mptcp_userspace_pm_remove_id_zero_address(msk);
- release_sock(sk);
- goto out;
- }
-
- spin_lock_bh(&msk->pm.lock);
- match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
- if (!match) {
- spin_unlock_bh(&msk->pm.lock);
- release_sock(sk);
- goto out;
- }
-
- list_del_rcu(&match->list);
- spin_unlock_bh(&msk->pm.lock);
-
- mptcp_pm_remove_addr_entry(msk, match);
-
+ err = userspace_pm_address_remove(msk, id_val);
release_sock(sk);
-
- sock_kfree_s(sk, match, sizeof(*match));
-
- err = 0;
-out:
if (err)
NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
"address with id %u not found",
@@ -358,12 +380,38 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
return err;
}
+static int userspace_pm_subflow_create(struct mptcp_sock *msk,
+ struct mptcp_pm_addr_entry *entry,
+ struct mptcp_addr_info *remote)
+{
+ struct sock *sk = (struct sock *)msk;
+ struct mptcp_pm_local local;
+ int err;
+
+ err = mptcp_userspace_pm_append_new_local_addr(msk, entry, false);
+ if (err < 0)
+ return err;
+
+ local.addr = entry->addr;
+ local.flags = entry->flags;
+ local.ifindex = entry->ifindex;
+
+ err = __mptcp_subflow_connect(sk, &local, remote);
+ 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);
+
+ return 0;
+}
+
int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
{
struct mptcp_pm_addr_entry entry = { 0 };
struct mptcp_addr_info addr_r;
struct nlattr *raddr, *laddr;
- struct mptcp_pm_local local;
struct mptcp_sock *msk;
int err = -EINVAL;
struct sock *sk;
@@ -401,31 +449,13 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
goto create_err;
}
- err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
- if (err < 0) {
- NL_SET_ERR_MSG_ATTR(info->extack, laddr,
- "did not match address and id");
- 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 = userspace_pm_subflow_create(msk, &entry, &addr_r);
release_sock(sk);
if (err)
GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
- 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);
-
create_err:
sock_put(sk);
return err;
@@ -477,14 +507,34 @@ 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 *ssk, *sk = (struct sock *)msk;
+
+ ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
+ if (!ssk)
+ return -ESRCH;
+
+ 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, mptcp_subflow_ctx(ssk));
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
+
+ return 0;
+}
+
int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
{
struct mptcp_pm_addr_entry addr_l;
struct mptcp_addr_info addr_r;
struct nlattr *raddr, *laddr;
struct mptcp_sock *msk;
- struct sock *sk, *ssk;
int err = -EINVAL;
+ struct sock *sk;
if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
@@ -535,37 +585,47 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
}
lock_sock(sk);
- ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
- if (!ssk) {
- GENL_SET_ERR_MSG(info, "subflow not found");
- err = -ESRCH;
- goto release_sock;
- }
-
- spin_lock_bh(&msk->pm.lock);
- mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
- spin_unlock_bh(&msk->pm.lock);
- mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
- mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
- MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
-release_sock:
+ err = userspace_pm_subflow_destroy(msk, &addr_l, &addr_r);
release_sock(sk);
+ if (err)
+ GENL_SET_ERR_MSG(info, "subflow not found");
destroy_err:
sock_put(sk);
return err;
}
+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;
+ u8 bkup = 0;
+
+ if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+ bkup = 1;
+
+ 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;
+ }
+ 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 *local,
struct genl_info *info)
{
struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
- struct mptcp_pm_addr_entry *entry;
struct nlattr *attr, *attr_rem;
struct mptcp_sock *msk;
int ret = -EINVAL;
struct sock *sk;
- u8 bkup = 0;
if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
return ret;
@@ -596,21 +656,8 @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
goto set_flags_err;
}
- if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
- bkup = 1;
-
- 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;
- }
- spin_unlock_bh(&msk->pm.lock);
-
lock_sock(sk);
- ret = mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, &rem, bkup);
+ ret = userspace_pm_set_flags(msk, local, &rem);
release_sock(sk);
/* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
@@ -687,6 +734,18 @@ 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,
+ .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)
{
@@ -734,7 +793,15 @@ 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);
}
+
+void __init mptcp_userspace_pm_init(void)
+{
+ mptcp_register_path_manager(&mptcp_userspace_pm);
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 64254c57be01..2492354e34dd 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1160,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.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH mptcp-next v2 3/3] mptcp: init and release mptcp_pm_ops
2025-01-15 10:09 [PATCH mptcp-next v2 0/3] BPF path manager, part 4 Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 1/3] mptcp: define struct mptcp_pm_ops Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm Geliang Tang
@ 2025-01-15 10:09 ` Geliang Tang
2025-01-15 11:16 ` [PATCH mptcp-next v2 0/3] BPF path manager, part 4 MPTCP CI
3 siblings, 0 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-15 10:09 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
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 | 7 +++++
net/mptcp/pm_userspace.c | 58 +++++++++++++++++++++++++++++++++++-----
net/mptcp/protocol.c | 1 +
net/mptcp/protocol.h | 3 +++
4 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 3b47c2380a44..4353498f7396 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -600,6 +600,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;
@@ -627,6 +628,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);
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index c03201c95fea..876411f22d99 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -164,7 +164,9 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
new_entry.addr.id = 0;
new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
- return userspace_pm_get_local_id(msk, &new_entry);
+ return msk->pm.ops->get_local_id ?
+ msk->pm.ops->get_local_id(msk, &new_entry) :
+ userspace_pm_get_local_id(msk, &new_entry);
}
static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
@@ -184,7 +186,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 msk->pm.ops->get_flags ?
+ msk->pm.ops->get_flags(msk, skc) :
+ userspace_pm_get_flags(msk, skc);
}
static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
@@ -269,7 +273,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 = msk->pm.ops->address_announce ?
+ msk->pm.ops->address_announce(msk, &addr_val) :
+ userspace_pm_address_announce(msk, &addr_val);
release_sock(sk);
if (err)
NL_SET_ERR_MSG_ATTR(info->extack, addr,
@@ -369,7 +375,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 = msk->pm.ops->address_remove ?
+ msk->pm.ops->address_remove(msk, id_val) :
+ userspace_pm_address_remove(msk, id_val);
release_sock(sk);
if (err)
NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
@@ -450,7 +458,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 = msk->pm.ops->subflow_create ?
+ msk->pm.ops->subflow_create(msk, &entry, &addr_r) :
+ userspace_pm_subflow_create(msk, &entry, &addr_r);
release_sock(sk);
if (err)
@@ -585,7 +595,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, &addr_l, &addr_r);
+ err = msk->pm.ops->subflow_destroy ?
+ msk->pm.ops->subflow_destroy(msk, &addr_l, &addr_r) :
+ userspace_pm_subflow_destroy(msk, &addr_l, &addr_r);
release_sock(sk);
if (err)
GENL_SET_ERR_MSG(info, "subflow not found");
@@ -657,7 +669,9 @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
}
lock_sock(sk);
- ret = userspace_pm_set_flags(msk, local, &rem);
+ ret = msk->pm.ops->set_flags ?
+ msk->pm.ops->set_flags(msk, local, &rem) :
+ userspace_pm_set_flags(msk, local, &rem);
release_sock(sk);
/* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
@@ -801,6 +815,36 @@ void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm)
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 5cda189d29f2..bba22c3f7279 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2940,6 +2940,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 2492354e34dd..94f412b11a6f 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -221,6 +221,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 */
@@ -1052,6 +1053,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);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp-next v2 0/3] BPF path manager, part 4
2025-01-15 10:09 [PATCH mptcp-next v2 0/3] BPF path manager, part 4 Geliang Tang
` (2 preceding siblings ...)
2025-01-15 10:09 ` [PATCH mptcp-next v2 3/3] mptcp: init and release mptcp_pm_ops Geliang Tang
@ 2025-01-15 11:16 ` MPTCP CI
3 siblings, 0 replies; 7+ messages in thread
From: MPTCP CI @ 2025-01-15 11:16 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): Unstable: 1 failed test(s): bpftest_test_progs-cpuv4_mptcp 🔴
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/12786155697
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/70af88472329
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=925640
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] 7+ messages in thread
* Re: [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm
2025-01-15 10:09 ` [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm Geliang Tang
@ 2025-01-16 2:43 ` Geliang Tang
2025-01-16 3:06 ` Geliang Tang
1 sibling, 0 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-16 2:43 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
On Wed, 2025-01-15 at 18:09 +0800, Geliang Tang wrote:
> 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().
>
> Extract address_announce() interface of the userspace PM from the
> handler
> of netlink commond MPTCP_PM_CMD_ANNOUNCE mptcp_pm_nl_announce_doit(),
CI reports some warnings:
WARNING: 'commond' may be misspelled - perhaps 'command'?
Will update them in the next version.
Thanks,
-Geliang
> only
> leave the code for obtaining msk through "info" and parsing address
> entry
> in the handler.
>
> Extract address_remove() interface of the userspace PM 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.
>
> Extract subflow_create() interface of the userspace PM 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 of the userspace PM 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.
>
> Extract set_flags() interface of the userspace PM from function
> mptcp_userspace_pm_set_flags(), only leave the code for obtaining
> msk through "info" in this function.
>
> All fives interfaces are invoked under holding the msk socket lock.
>
> Extract get_local_id() interface of the userspace PM from function
> mptcp_userspace_pm_get_local_id(), only leave the code for setting
> new address entry in this function.
>
> get_flags() interface of the userspace PM is defined as the same as
> the function mptcp_userspace_pm_get_flags(), then this function
> becomes a wrapper.
>
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
> net/mptcp/pm.c | 1 +
> net/mptcp/pm_userspace.c | 275 ++++++++++++++++++++++++-------------
> --
> net/mptcp/protocol.h | 1 +
> 3 files changed, 173 insertions(+), 104 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index e275be73b963..3b47c2380a44 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -646,4 +646,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 2fdee6f22113..c03201c95fea 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -135,32 +135,40 @@ 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_addr_info *skc)
> +static int userspace_pm_get_local_id(struct mptcp_sock *msk,
> + struct mptcp_pm_addr_entry
> *local)
> {
> - struct mptcp_pm_addr_entry *entry = NULL, new_entry;
> __be16 msk_sport = ((struct inet_sock *)
> inet_sk((struct sock *)msk))-
> >inet_sport;
> + struct mptcp_pm_addr_entry *entry;
>
> 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;
>
> + if (local->addr.port == msk_sport)
> + local->addr.port = 0;
> +
> + return mptcp_userspace_pm_append_new_local_addr(msk, local,
> true);
> +}
> +
> +int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
> + struct mptcp_addr_info *skc)
> +{
> + struct mptcp_pm_addr_entry new_entry;
> +
> 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;
> -
> - return mptcp_userspace_pm_append_new_local_addr(msk,
> &new_entry, true);
> + return userspace_pm_get_local_id(msk, &new_entry);
> }
>
> -u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
> - struct mptcp_addr_info *skc)
> +static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
> + struct mptcp_addr_info *skc)
> {
> struct mptcp_pm_addr_entry *entry;
> u8 flags;
> @@ -173,6 +181,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 mptcp_sock *msk;
> @@ -198,6 +212,28 @@ 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;
> +
> + 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 mptcp_pm_addr_entry addr_val;
> @@ -232,26 +268,13 @@ int mptcp_pm_nl_announce_doit(struct sk_buff
> *skb, struct genl_info *info)
> goto announce_err;
> }
>
> - err = mptcp_userspace_pm_append_new_local_addr(msk,
> &addr_val, false);
> - if (err < 0) {
> - NL_SET_ERR_MSG_ATTR(info->extack, addr,
> - "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)
> + NL_SET_ERR_MSG_ATTR(info->extack, addr,
> + "did not match address and id");
>
> - err = 0;
> announce_err:
> sock_put(sk);
> return err;
> @@ -301,9 +324,32 @@ void mptcp_pm_remove_addr_entry(struct
> mptcp_sock *msk,
> spin_unlock_bh(&msk->pm.lock);
> }
>
> +static int userspace_pm_address_remove(struct mptcp_sock *msk, u8
> id)
> +{
> + struct mptcp_pm_addr_entry *entry;
> +
> + if (id == 0)
> + return
> mptcp_userspace_pm_remove_id_zero_address(msk);
> +
> + spin_lock_bh(&msk->pm.lock);
> + entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
> + if (!entry) {
> + spin_unlock_bh(&msk->pm.lock);
> + return -EINVAL;
> + }
> +
> + list_del_rcu(&entry->list);
> + spin_unlock_bh(&msk->pm.lock);
> +
> + mptcp_pm_remove_addr_entry(msk, entry);
> +
> + sock_kfree_s((struct sock *)msk, entry, sizeof(*entry));
> +
> + return 0;
> +}
> +
> int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info
> *info)
> {
> - struct mptcp_pm_addr_entry *match;
> struct mptcp_sock *msk;
> struct nlattr *id;
> int err = -EINVAL;
> @@ -323,32 +369,8 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb,
> struct genl_info *info)
> sk = (struct sock *)msk;
>
> lock_sock(sk);
> -
> - if (id_val == 0) {
> - err =
> mptcp_userspace_pm_remove_id_zero_address(msk);
> - release_sock(sk);
> - goto out;
> - }
> -
> - spin_lock_bh(&msk->pm.lock);
> - match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
> - if (!match) {
> - spin_unlock_bh(&msk->pm.lock);
> - release_sock(sk);
> - goto out;
> - }
> -
> - list_del_rcu(&match->list);
> - spin_unlock_bh(&msk->pm.lock);
> -
> - mptcp_pm_remove_addr_entry(msk, match);
> -
> + err = userspace_pm_address_remove(msk, id_val);
> release_sock(sk);
> -
> - sock_kfree_s(sk, match, sizeof(*match));
> -
> - err = 0;
> -out:
> if (err)
> NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
> "address with id %u not
> found",
> @@ -358,12 +380,38 @@ int mptcp_pm_nl_remove_doit(struct sk_buff
> *skb, struct genl_info *info)
> return err;
> }
>
> +static int userspace_pm_subflow_create(struct mptcp_sock *msk,
> + struct mptcp_pm_addr_entry
> *entry,
> + struct mptcp_addr_info
> *remote)
> +{
> + struct sock *sk = (struct sock *)msk;
> + struct mptcp_pm_local local;
> + int err;
> +
> + err = mptcp_userspace_pm_append_new_local_addr(msk, entry,
> false);
> + if (err < 0)
> + return err;
> +
> + local.addr = entry->addr;
> + local.flags = entry->flags;
> + local.ifindex = entry->ifindex;
> +
> + err = __mptcp_subflow_connect(sk, &local, remote);
> + 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);
> +
> + return 0;
> +}
> +
> int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct
> genl_info *info)
> {
> struct mptcp_pm_addr_entry entry = { 0 };
> struct mptcp_addr_info addr_r;
> struct nlattr *raddr, *laddr;
> - struct mptcp_pm_local local;
> struct mptcp_sock *msk;
> int err = -EINVAL;
> struct sock *sk;
> @@ -401,31 +449,13 @@ int mptcp_pm_nl_subflow_create_doit(struct
> sk_buff *skb, struct genl_info *info)
> goto create_err;
> }
>
> - err = mptcp_userspace_pm_append_new_local_addr(msk, &entry,
> false);
> - if (err < 0) {
> - NL_SET_ERR_MSG_ATTR(info->extack, laddr,
> - "did not match address and id");
> - 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 = userspace_pm_subflow_create(msk, &entry, &addr_r);
> release_sock(sk);
>
> if (err)
> GENL_SET_ERR_MSG_FMT(info, "connect error: %d",
> err);
>
> - 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);
> -
> create_err:
> sock_put(sk);
> return err;
> @@ -477,14 +507,34 @@ 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 *ssk, *sk = (struct sock *)msk;
> +
> + ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
> + if (!ssk)
> + return -ESRCH;
> +
> + 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, mptcp_subflow_ctx(ssk));
> + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
> +
> + return 0;
> +}
> +
> int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct
> genl_info *info)
> {
> struct mptcp_pm_addr_entry addr_l;
> struct mptcp_addr_info addr_r;
> struct nlattr *raddr, *laddr;
> struct mptcp_sock *msk;
> - struct sock *sk, *ssk;
> int err = -EINVAL;
> + struct sock *sk;
>
> if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
> GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
> @@ -535,37 +585,47 @@ int mptcp_pm_nl_subflow_destroy_doit(struct
> sk_buff *skb, struct genl_info *info
> }
>
> lock_sock(sk);
> - ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
> - if (!ssk) {
> - GENL_SET_ERR_MSG(info, "subflow not found");
> - err = -ESRCH;
> - goto release_sock;
> - }
> -
> - spin_lock_bh(&msk->pm.lock);
> - mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
> - spin_unlock_bh(&msk->pm.lock);
> - mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN |
> SEND_SHUTDOWN);
> - mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
> - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
> -release_sock:
> + err = userspace_pm_subflow_destroy(msk, &addr_l, &addr_r);
> release_sock(sk);
> + if (err)
> + GENL_SET_ERR_MSG(info, "subflow not found");
>
> destroy_err:
> sock_put(sk);
> return err;
> }
>
> +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;
> + u8 bkup = 0;
> +
> + if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> + bkup = 1;
> +
> + 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;
> + }
> + 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 *local,
> struct genl_info *info)
> {
> struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
> - struct mptcp_pm_addr_entry *entry;
> struct nlattr *attr, *attr_rem;
> struct mptcp_sock *msk;
> int ret = -EINVAL;
> struct sock *sk;
> - u8 bkup = 0;
>
> if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
> return ret;
> @@ -596,21 +656,8 @@ int mptcp_userspace_pm_set_flags(struct
> mptcp_pm_addr_entry *local,
> goto set_flags_err;
> }
>
> - if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> - bkup = 1;
> -
> - 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;
> - }
> - spin_unlock_bh(&msk->pm.lock);
> -
> lock_sock(sk);
> - ret = mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, &rem,
> bkup);
> + ret = userspace_pm_set_flags(msk, local, &rem);
> release_sock(sk);
>
> /* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
> @@ -687,6 +734,18 @@ 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,
> + .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)
> {
> @@ -734,7 +793,15 @@ 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);
> }
> +
> +void __init mptcp_userspace_pm_init(void)
> +{
> + mptcp_register_path_manager(&mptcp_userspace_pm);
> +}
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 64254c57be01..2492354e34dd 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -1160,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);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm
2025-01-15 10:09 ` [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm Geliang Tang
2025-01-16 2:43 ` Geliang Tang
@ 2025-01-16 3:06 ` Geliang Tang
1 sibling, 0 replies; 7+ messages in thread
From: Geliang Tang @ 2025-01-16 3:06 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
On Wed, 2025-01-15 at 18:09 +0800, Geliang Tang wrote:
> 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().
>
> Extract address_announce() interface of the userspace PM 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 of the userspace PM 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.
>
> Extract subflow_create() interface of the userspace PM 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 of the userspace PM 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.
>
> Extract set_flags() interface of the userspace PM from function
> mptcp_userspace_pm_set_flags(), only leave the code for obtaining
> msk through "info" in this function.
>
> All fives interfaces are invoked under holding the msk socket lock.
>
> Extract get_local_id() interface of the userspace PM from function
> mptcp_userspace_pm_get_local_id(), only leave the code for setting
> new address entry in this function.
>
> get_flags() interface of the userspace PM is defined as the same as
> the function mptcp_userspace_pm_get_flags(), then this function
> becomes a wrapper.
>
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> ---
> net/mptcp/pm.c | 1 +
> net/mptcp/pm_userspace.c | 275 ++++++++++++++++++++++++-------------
> --
> net/mptcp/protocol.h | 1 +
> 3 files changed, 173 insertions(+), 104 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index e275be73b963..3b47c2380a44 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -646,4 +646,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 2fdee6f22113..c03201c95fea 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -135,32 +135,40 @@ 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_addr_info *skc)
> +static int userspace_pm_get_local_id(struct mptcp_sock *msk,
> + struct mptcp_pm_addr_entry
> *local)
> {
> - struct mptcp_pm_addr_entry *entry = NULL, new_entry;
> __be16 msk_sport = ((struct inet_sock *)
> inet_sk((struct sock *)msk))-
> >inet_sport;
> + struct mptcp_pm_addr_entry *entry;
>
> 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;
>
> + if (local->addr.port == msk_sport)
> + local->addr.port = 0;
> +
> + return mptcp_userspace_pm_append_new_local_addr(msk, local,
> true);
> +}
> +
> +int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
> + struct mptcp_addr_info *skc)
> +{
> + struct mptcp_pm_addr_entry new_entry;
> +
> 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;
> -
> - return mptcp_userspace_pm_append_new_local_addr(msk,
> &new_entry, true);
> + return userspace_pm_get_local_id(msk, &new_entry);
> }
>
> -u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk,
> - struct mptcp_addr_info *skc)
> +static u8 userspace_pm_get_flags(struct mptcp_sock *msk,
> + struct mptcp_addr_info *skc)
> {
> struct mptcp_pm_addr_entry *entry;
> u8 flags;
> @@ -173,6 +181,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 mptcp_sock *msk;
> @@ -198,6 +212,28 @@ 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;
> +
> + 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 mptcp_pm_addr_entry addr_val;
> @@ -232,26 +268,13 @@ int mptcp_pm_nl_announce_doit(struct sk_buff
> *skb, struct genl_info *info)
> goto announce_err;
> }
>
> - err = mptcp_userspace_pm_append_new_local_addr(msk,
> &addr_val, false);
> - if (err < 0) {
> - NL_SET_ERR_MSG_ATTR(info->extack, addr,
> - "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)
> + NL_SET_ERR_MSG_ATTR(info->extack, addr,
> + "did not match address and id");
>
> - err = 0;
> announce_err:
> sock_put(sk);
> return err;
> @@ -301,9 +324,32 @@ void mptcp_pm_remove_addr_entry(struct
> mptcp_sock *msk,
> spin_unlock_bh(&msk->pm.lock);
> }
>
> +static int userspace_pm_address_remove(struct mptcp_sock *msk, u8
> id)
> +{
> + struct mptcp_pm_addr_entry *entry;
> +
> + if (id == 0)
> + return
> mptcp_userspace_pm_remove_id_zero_address(msk);
> +
> + spin_lock_bh(&msk->pm.lock);
> + entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
> + if (!entry) {
> + spin_unlock_bh(&msk->pm.lock);
> + return -EINVAL;
> + }
> +
> + list_del_rcu(&entry->list);
> + spin_unlock_bh(&msk->pm.lock);
> +
> + mptcp_pm_remove_addr_entry(msk, entry);
> +
> + sock_kfree_s((struct sock *)msk, entry, sizeof(*entry));
> +
> + return 0;
> +}
> +
> int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info
> *info)
> {
> - struct mptcp_pm_addr_entry *match;
> struct mptcp_sock *msk;
> struct nlattr *id;
> int err = -EINVAL;
> @@ -323,32 +369,8 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb,
> struct genl_info *info)
> sk = (struct sock *)msk;
>
> lock_sock(sk);
> -
> - if (id_val == 0) {
> - err =
> mptcp_userspace_pm_remove_id_zero_address(msk);
> - release_sock(sk);
> - goto out;
> - }
> -
> - spin_lock_bh(&msk->pm.lock);
> - match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
> - if (!match) {
> - spin_unlock_bh(&msk->pm.lock);
> - release_sock(sk);
> - goto out;
> - }
> -
> - list_del_rcu(&match->list);
> - spin_unlock_bh(&msk->pm.lock);
> -
> - mptcp_pm_remove_addr_entry(msk, match);
> -
> + err = userspace_pm_address_remove(msk, id_val);
> release_sock(sk);
> -
> - sock_kfree_s(sk, match, sizeof(*match));
> -
> - err = 0;
> -out:
> if (err)
> NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
> "address with id %u not
> found",
> @@ -358,12 +380,38 @@ int mptcp_pm_nl_remove_doit(struct sk_buff
> *skb, struct genl_info *info)
> return err;
> }
>
> +static int userspace_pm_subflow_create(struct mptcp_sock *msk,
> + struct mptcp_pm_addr_entry
> *entry,
> + struct mptcp_addr_info
> *remote)
> +{
> + struct sock *sk = (struct sock *)msk;
> + struct mptcp_pm_local local;
> + int err;
> +
> + err = mptcp_userspace_pm_append_new_local_addr(msk, entry,
> false);
> + if (err < 0)
> + return err;
> +
> + local.addr = entry->addr;
> + local.flags = entry->flags;
> + local.ifindex = entry->ifindex;
> +
> + err = __mptcp_subflow_connect(sk, &local, remote);
> + 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);
> +
> + return 0;
Should be 'return err;' here.
Will update it in the next version.
Thanks,
-Geliang
> +}
> +
> int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct
> genl_info *info)
> {
> struct mptcp_pm_addr_entry entry = { 0 };
> struct mptcp_addr_info addr_r;
> struct nlattr *raddr, *laddr;
> - struct mptcp_pm_local local;
> struct mptcp_sock *msk;
> int err = -EINVAL;
> struct sock *sk;
> @@ -401,31 +449,13 @@ int mptcp_pm_nl_subflow_create_doit(struct
> sk_buff *skb, struct genl_info *info)
> goto create_err;
> }
>
> - err = mptcp_userspace_pm_append_new_local_addr(msk, &entry,
> false);
> - if (err < 0) {
> - NL_SET_ERR_MSG_ATTR(info->extack, laddr,
> - "did not match address and id");
> - 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 = userspace_pm_subflow_create(msk, &entry, &addr_r);
> release_sock(sk);
>
> if (err)
> GENL_SET_ERR_MSG_FMT(info, "connect error: %d",
> err);
>
> - 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);
> -
> create_err:
> sock_put(sk);
> return err;
> @@ -477,14 +507,34 @@ 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 *ssk, *sk = (struct sock *)msk;
> +
> + ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
> + if (!ssk)
> + return -ESRCH;
> +
> + 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, mptcp_subflow_ctx(ssk));
> + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
> +
> + return 0;
> +}
> +
> int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct
> genl_info *info)
> {
> struct mptcp_pm_addr_entry addr_l;
> struct mptcp_addr_info addr_r;
> struct nlattr *raddr, *laddr;
> struct mptcp_sock *msk;
> - struct sock *sk, *ssk;
> int err = -EINVAL;
> + struct sock *sk;
>
> if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
> GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
> @@ -535,37 +585,47 @@ int mptcp_pm_nl_subflow_destroy_doit(struct
> sk_buff *skb, struct genl_info *info
> }
>
> lock_sock(sk);
> - ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
> - if (!ssk) {
> - GENL_SET_ERR_MSG(info, "subflow not found");
> - err = -ESRCH;
> - goto release_sock;
> - }
> -
> - spin_lock_bh(&msk->pm.lock);
> - mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
> - spin_unlock_bh(&msk->pm.lock);
> - mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN |
> SEND_SHUTDOWN);
> - mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
> - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
> -release_sock:
> + err = userspace_pm_subflow_destroy(msk, &addr_l, &addr_r);
> release_sock(sk);
> + if (err)
> + GENL_SET_ERR_MSG(info, "subflow not found");
>
> destroy_err:
> sock_put(sk);
> return err;
> }
>
> +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;
> + u8 bkup = 0;
> +
> + if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> + bkup = 1;
> +
> + 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;
> + }
> + 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 *local,
> struct genl_info *info)
> {
> struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
> - struct mptcp_pm_addr_entry *entry;
> struct nlattr *attr, *attr_rem;
> struct mptcp_sock *msk;
> int ret = -EINVAL;
> struct sock *sk;
> - u8 bkup = 0;
>
> if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
> return ret;
> @@ -596,21 +656,8 @@ int mptcp_userspace_pm_set_flags(struct
> mptcp_pm_addr_entry *local,
> goto set_flags_err;
> }
>
> - if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> - bkup = 1;
> -
> - 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;
> - }
> - spin_unlock_bh(&msk->pm.lock);
> -
> lock_sock(sk);
> - ret = mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, &rem,
> bkup);
> + ret = userspace_pm_set_flags(msk, local, &rem);
> release_sock(sk);
>
> /* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
> @@ -687,6 +734,18 @@ 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,
> + .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)
> {
> @@ -734,7 +793,15 @@ 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);
> }
> +
> +void __init mptcp_userspace_pm_init(void)
> +{
> + mptcp_register_path_manager(&mptcp_userspace_pm);
> +}
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 64254c57be01..2492354e34dd 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -1160,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);
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-01-16 3:06 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-15 10:09 [PATCH mptcp-next v2 0/3] BPF path manager, part 4 Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 1/3] mptcp: define struct mptcp_pm_ops Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 2/3] mptcp: register default userspace pm Geliang Tang
2025-01-16 2:43 ` Geliang Tang
2025-01-16 3:06 ` Geliang Tang
2025-01-15 10:09 ` [PATCH mptcp-next v2 3/3] mptcp: init and release mptcp_pm_ops Geliang Tang
2025-01-15 11:16 ` [PATCH mptcp-next v2 0/3] BPF path manager, part 4 MPTCP CI
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox