Here are a few cleanups, preparation work for the new PM ops, and sysctl knobs.
- Patch 1: reorg: move generic NL code used by all PMs to pm_netlink.c.
- Patch 2: use kmemdup() instead of kmalloc + copy.
- Patch 3: small cleanup to use pm var instead of msk->pm.
- Patch 4: reorg: id_avail_bitmap is only used by the in-kernel PM.
- Patch 5: use struct_group to easily reset a subset of PM data vars.
- Patch 6: introduce the minimal skeleton for the new PM ops.
- Patch 7: register in-kernel and userspace PM ops.
- Patch 8: new net.mptcp.path_manager sysctl knob, deprecating pm_type.
- Patch 9: map the new path_manager sysctl knob with pm_type.
- Patch 10: map the old pm_type sysctl knob with path_manager.
- Patch 11: new net.mptcp.available_path_managers sysctl knob.
- Patch 12: new test to validate path_manager and pm_type mapping.
Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- Geliang Tang (11): mptcp: pm: in-kernel: use kmemdup helper mptcp: pm: use pm variable instead of msk->pm mptcp: pm: only fill id_avail_bitmap for in-kernel pm mptcp: pm: add struct_group in mptcp_pm_data mptcp: pm: define struct mptcp_pm_ops mptcp: pm: register in-kernel and userspace PM mptcp: sysctl: set path manager by name mptcp: sysctl: map path_manager to pm_type mptcp: sysctl: map pm_type to path_manager mptcp: sysctl: add available_path_managers selftests: mptcp: add pm sysctl mapping tests
Matthieu Baerts (NGI0) (1): mptcp: pm: split netlink and in-kernel init
Documentation/networking/mptcp-sysctl.rst | 23 +++++ include/net/mptcp.h | 14 +++ net/mptcp/ctrl.c | 113 +++++++++++++++++++++- net/mptcp/pm.c | 97 ++++++++++++++++--- net/mptcp/pm_kernel.c | 16 +-- net/mptcp/pm_netlink.c | 6 ++ net/mptcp/pm_userspace.c | 10 ++ net/mptcp/protocol.h | 17 ++++ tools/testing/selftests/net/mptcp/userspace_pm.sh | 30 +++++- 9 files changed, 301 insertions(+), 25 deletions(-) --- base-commit: e016cf5f39e9c53e274a7b7122a949d8839b8782 change-id: 20250312-net-next-mptcp-pm-ops-intro-01510135cd5e
Best regards,
The registration of mptcp_genl_family is useful for both the in-kernel and the userspace PM. It should then be done in pm_netlink.c.
On the other hand, the registration of the in-kernel pernet subsystem is specific to the in-kernel PM, and should stay there in pm_kernel.c.
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm.c | 1 + net/mptcp/pm_kernel.c | 5 +---- net/mptcp/pm_netlink.c | 6 ++++++ net/mptcp/protocol.h | 1 + 4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 833839d7286e717599579356af3117f70e39de0a..8e6a325a389803196c35175cd5ea7637624d0ee2 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -1022,5 +1022,6 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
void __init mptcp_pm_init(void) { + mptcp_pm_kernel_register(); mptcp_pm_nl_init(); } diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index daf8f98a316439a67c12f63f2388ef497dae08dd..62ae68abb2cb0066a30a3fab88ae5f082c523413 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -1400,11 +1400,8 @@ static struct pernet_operations mptcp_pm_pernet_ops = { .size = sizeof(struct pm_nl_pernet), };
-void __init mptcp_pm_nl_init(void) +void __init mptcp_pm_kernel_register(void) { if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0) panic("Failed to register MPTCP PM pernet subsystem.\n"); - - if (genl_register_family(&mptcp_genl_family)) - panic("Failed to register MPTCP PM netlink family\n"); } diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index b2e5bbdcd5df920887ffbd9b6d652f422b32d49e..50aaf259959aeaf36e7ab954c6f7957eaf2bc390 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -625,3 +625,9 @@ struct genl_family mptcp_genl_family __ro_after_init = { .mcgrps = mptcp_pm_mcgrps, .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps), }; + +void __init mptcp_pm_nl_init(void) +{ + if (genl_register_family(&mptcp_genl_family)) + panic("Failed to register MPTCP PM netlink family\n"); +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index c51b6a22d5e099c4486cc76fc4abc9a91c574c4a..ffb70fe08181815c23629354f78e3bdbe599e703 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1147,6 +1147,7 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo return local_id; }
+void __init mptcp_pm_kernel_register(void); void __init mptcp_pm_nl_init(void); void mptcp_pm_worker(struct mptcp_sock *msk); void __mptcp_pm_kernel_worker(struct mptcp_sock *msk);
On Thu, Mar 13, 2025 at 11:20:50AM +0100, Matthieu Baerts (NGI0) wrote:
The registration of mptcp_genl_family is useful for both the in-kernel and the userspace PM. It should then be done in pm_netlink.c.
On the other hand, the registration of the in-kernel pernet subsystem is specific to the in-kernel PM, and should stay there in pm_kernel.c.
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
Instead of using kmalloc() or kzalloc() to allocate an entry and then immediately duplicate another entry to the newly allocated one, kmemdup() helper can be used to simplify the code.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm_kernel.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index 62ae68abb2cb0066a30a3fab88ae5f082c523413..806a9b5b3c07a350c20ec7085183c26af9f50d44 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -710,11 +710,10 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, return ret;
/* address not found, add to local list */ - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmemdup(skc, sizeof(*skc), GFP_ATOMIC); if (!entry) return -ENOMEM;
- *entry = *skc; entry->addr.port = 0; ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true, false); if (ret < 0) @@ -817,13 +816,12 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info) return -EINVAL; }
- entry = kzalloc(sizeof(*entry), GFP_KERNEL_ACCOUNT); + entry = kmemdup(&addr, sizeof(addr), GFP_KERNEL_ACCOUNT); if (!entry) { GENL_SET_ERR_MSG(info, "can't allocate addr"); return -ENOMEM; }
- *entry = addr; if (entry->addr.port) { ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry); if (ret) {
On Thu, Mar 13, 2025 at 11:20:51AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
Instead of using kmalloc() or kzalloc() to allocate an entry and then immediately duplicate another entry to the newly allocated one, kmemdup() helper can be used to simplify the code.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
The variable "pm" has been defined in mptcp_pm_fully_established() and mptcp_pm_data_reset() as "msk->pm", so use "pm" directly instead of using "msk->pm".
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 8e6a325a389803196c35175cd5ea7637624d0ee2..04a156395aaddf50e67d10479086591a37063fa3 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -511,13 +511,13 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk) * be sure to serve this event only once. */ if (READ_ONCE(pm->work_pending) && - !(msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED))) + !(pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED))) mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED);
- if ((msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0) + if ((pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0) announce = true;
- msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED); + pm->status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED); spin_unlock_bh(&pm->lock);
if (announce) @@ -1009,7 +1009,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(pm->id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); }
void mptcp_pm_data_init(struct mptcp_sock *msk)
On Thu, Mar 13, 2025 at 11:20:52AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
The variable "pm" has been defined in mptcp_pm_fully_established() and mptcp_pm_data_reset() as "msk->pm", so use "pm" directly instead of using "msk->pm".
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
id_avail_bitmap of struct mptcp_pm_data is currently only used by the in-kernel PM, so this patch moves its initialization operation under the "if (pm_type == MPTCP_PM_TYPE_KERNEL)" condition.
Suggested-by: Matthieu Baerts matttbe@kernel.org Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 04a156395aaddf50e67d10479086591a37063fa3..af009661477b1743b11221c0d59b53cd89e6e791 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -1000,6 +1000,8 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk) !!mptcp_pm_get_add_addr_accept_max(msk) && subflows_allowed); WRITE_ONCE(pm->accept_subflow, subflows_allowed); + + bitmap_fill(pm->id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); } else { WRITE_ONCE(pm->work_pending, 0); WRITE_ONCE(pm->accept_addr, 0); @@ -1009,7 +1011,6 @@ 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(pm->id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); }
void mptcp_pm_data_init(struct mptcp_sock *msk)
On Thu, Mar 13, 2025 at 11:20:53AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
id_avail_bitmap of struct mptcp_pm_data is currently only used by the in-kernel PM, so this patch moves its initialization operation under the "if (pm_type == MPTCP_PM_TYPE_KERNEL)" condition.
Suggested-by: Matthieu Baerts matttbe@kernel.org Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a "struct_group(reset, ...)" in struct mptcp_pm_data to simplify the reset, and make sure we don't miss any.
Suggested-by: Matthieu Baerts matttbe@kernel.org Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm.c | 13 +------------ net/mptcp/protocol.h | 5 +++++ 2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index af009661477b1743b11221c0d59b53cd89e6e791..85ee999729a1c37f42bb21490d7f68d186e6734f 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -978,10 +978,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;
- pm->add_addr_signaled = 0; - pm->add_addr_accepted = 0; - pm->local_addr_used = 0; - pm->subflows = 0; + memset(&pm->reset, 0, sizeof(pm->reset)); pm->rm_list_tx.nr = 0; pm->rm_list_rx.nr = 0; WRITE_ONCE(pm->pm_type, pm_type); @@ -1002,15 +999,7 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk) WRITE_ONCE(pm->accept_subflow, subflows_allowed);
bitmap_fill(pm->id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); - } else { - WRITE_ONCE(pm->work_pending, 0); - WRITE_ONCE(pm->accept_addr, 0); - WRITE_ONCE(pm->accept_subflow, 0); } - - WRITE_ONCE(pm->addr_signal, 0); - WRITE_ONCE(pm->remote_deny_join_id0, false); - pm->status = 0; }
void mptcp_pm_data_init(struct mptcp_sock *msk) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index ffb70fe08181815c23629354f78e3bdbe599e703..15e2a03025ecb4cae44ccb700fcbbdd06ab806d1 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -223,6 +223,8 @@ struct mptcp_pm_data {
spinlock_t lock; /*protects the whole PM data */
+ struct_group(reset, + u8 addr_signal; bool server_side; bool work_pending; @@ -235,6 +237,9 @@ struct mptcp_pm_data { u8 pm_type; u8 subflows; u8 status; + + ); + DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); struct mptcp_rm_list rm_list_tx; struct mptcp_rm_list rm_list_rx;
On Thu, Mar 13, 2025 at 11:20:54AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a "struct_group(reset, ...)" in struct mptcp_pm_data to simplify the reset, and make sure we don't miss any.
Suggested-by: Matthieu Baerts matttbe@kernel.org Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
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 an MPTCP path manager, which contains a set of interfaces. Currently only init() and release() interfaces are included, subsequent patches will add others step by step.
Add a set of functions to register, unregister, find and validate a given path manager struct ops.
"list" is used to add this path manager to mptcp_pm_list list when it is registered. "name" is used to identify this path manager. mptcp_pm_find() uses "name" to find a path manager on the list.
mptcp_pm_unregister is not used in this set, but will be invoked in .unreg of struct bpf_struct_ops. mptcp_pm_validate() will be invoked in .validate of struct bpf_struct_ops. That's why they are exported.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- include/net/mptcp.h | 12 ++++++++++++ net/mptcp/pm.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 5 +++++ 3 files changed, 67 insertions(+)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 2c85ca92bb1c39989ae08a74ff4ef9b42099e60d..645d15695e3f5ec4b945bb543630f3dcc54453f2 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 */ @@ -121,6 +122,17 @@ struct mptcp_sched_ops { void (*release)(struct mptcp_sock *msk); } ____cacheline_aligned_in_smp;
+#define MPTCP_PM_NAME_MAX 16 + +struct mptcp_pm_ops { + char name[MPTCP_PM_NAME_MAX]; + 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.c b/net/mptcp/pm.c index 85ee999729a1c37f42bb21490d7f68d186e6734f..f4948a2cf9be078043bd237f56a57c27804ef4db 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -5,6 +5,8 @@ */ #define pr_fmt(fmt) "MPTCP: " fmt
+#include <linux/rculist.h> +#include <linux/spinlock.h> #include "protocol.h" #include "mib.h"
@@ -18,6 +20,9 @@ struct mptcp_pm_add_entry { struct mptcp_sock *sock; };
+static DEFINE_SPINLOCK(mptcp_pm_list_lock); +static LIST_HEAD(mptcp_pm_list); + /* path manager helpers */
/* if sk is ipv4 or ipv6_only allows only same-family local and remote addresses, @@ -1015,3 +1020,48 @@ void __init mptcp_pm_init(void) mptcp_pm_kernel_register(); mptcp_pm_nl_init(); } + +/* Must be called with rcu read lock held */ +struct mptcp_pm_ops *mptcp_pm_find(const char *name) +{ + struct mptcp_pm_ops *pm_ops; + + list_for_each_entry_rcu(pm_ops, &mptcp_pm_list, list) { + if (!strcmp(pm_ops->name, name)) + return pm_ops; + } + + return NULL; +} + +int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) +{ + return 0; +} + +int mptcp_pm_register(struct mptcp_pm_ops *pm_ops) +{ + int ret; + + ret = mptcp_pm_validate(pm_ops); + if (ret) + return ret; + + spin_lock(&mptcp_pm_list_lock); + if (mptcp_pm_find(pm_ops->name)) { + spin_unlock(&mptcp_pm_list_lock); + return -EEXIST; + } + list_add_tail_rcu(&pm_ops->list, &mptcp_pm_list); + spin_unlock(&mptcp_pm_list_lock); + + pr_debug("%s registered\n", pm_ops->name); + return 0; +} + +void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops) +{ + spin_lock(&mptcp_pm_list_lock); + list_del_rcu(&pm_ops->list); + spin_unlock(&mptcp_pm_list_lock); +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 15e2a03025ecb4cae44ccb700fcbbdd06ab806d1..ac8a178426e4ef495d7c5b5b9bd4c8b8835d71e4 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1050,6 +1050,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(const char *name); +int mptcp_pm_register(struct mptcp_pm_ops *pm_ops); +void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops); +int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops); + void mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock *msk);
void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
On Thu, Mar 13, 2025 at 11:20:55AM +0100, Matthieu Baerts (NGI0) wrote:
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 an MPTCP path manager, which contains a set of interfaces. Currently only init() and release() interfaces are included, subsequent patches will add others step by step.
Add a set of functions to register, unregister, find and validate a given path manager struct ops.
"list" is used to add this path manager to mptcp_pm_list list when it is registered. "name" is used to identify this path manager. mptcp_pm_find() uses "name" to find a path manager on the list.
mptcp_pm_unregister is not used in this set, but will be invoked in .unreg of struct bpf_struct_ops. mptcp_pm_validate() will be invoked in .validate of struct bpf_struct_ops. That's why they are exported.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
This patch defines the original in-kernel netlink path manager as a new struct mptcp_pm_ops named "mptcp_pm_kernel", and register it in mptcp_pm_kernel_register(). And define the userspace path manager as a new struct mptcp_pm_ops named "mptcp_pm_userspace", and register it in mptcp_pm_init().
To ensure that there's always a valid path manager available, the default path manager "mptcp_pm_kernel" will be skipped in mptcp_pm_unregister().
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/pm.c | 5 +++++ net/mptcp/pm_kernel.c | 7 +++++++ net/mptcp/pm_userspace.c | 10 ++++++++++ net/mptcp/protocol.h | 4 ++++ 4 files changed, 26 insertions(+)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index f4948a2cf9be078043bd237f56a57c27804ef4db..3896f21a46bd7f6912d2ffe22a3984ba97923021 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -1018,6 +1018,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk) void __init mptcp_pm_init(void) { mptcp_pm_kernel_register(); + mptcp_pm_userspace_register(); mptcp_pm_nl_init(); }
@@ -1061,6 +1062,10 @@ int mptcp_pm_register(struct mptcp_pm_ops *pm_ops)
void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops) { + /* skip unregistering the default path manager */ + if (WARN_ON_ONCE(pm_ops == &mptcp_pm_kernel)) + return; + spin_lock(&mptcp_pm_list_lock); list_del_rcu(&pm_ops->list); spin_unlock(&mptcp_pm_list_lock); diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index 806a9b5b3c07a350c20ec7085183c26af9f50d44..d39e7c1784608db290b8a2c1bc4fc24ed800cbb4 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -1398,8 +1398,15 @@ static struct pernet_operations mptcp_pm_pernet_ops = { .size = sizeof(struct pm_nl_pernet), };
+struct mptcp_pm_ops mptcp_pm_kernel = { + .name = "kernel", + .owner = THIS_MODULE, +}; + void __init mptcp_pm_kernel_register(void) { if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0) panic("Failed to register MPTCP PM pernet subsystem.\n"); + + mptcp_pm_register(&mptcp_pm_kernel); } diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 13856df226736727783a27fc0932a0003aadd8ee..2cb62f026b1f4420c549ab8ee6f54ffe3880d453 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -682,3 +682,13 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, sock_put(sk); return ret; } + +static struct mptcp_pm_ops mptcp_pm_userspace = { + .name = "userspace", + .owner = THIS_MODULE, +}; + +void __init mptcp_pm_userspace_register(void) +{ + mptcp_pm_register(&mptcp_pm_userspace); +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index ac8a178426e4ef495d7c5b5b9bd4c8b8835d71e4..c9e435a1fd7c7ab22a279c6de7c1573fe45cee98 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1050,6 +1050,9 @@ 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);
+/* the default path manager, used in mptcp_pm_unregister */ +extern struct mptcp_pm_ops mptcp_pm_kernel; + struct mptcp_pm_ops *mptcp_pm_find(const char *name); int mptcp_pm_register(struct mptcp_pm_ops *pm_ops); void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops); @@ -1158,6 +1161,7 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo }
void __init mptcp_pm_kernel_register(void); +void __init mptcp_pm_userspace_register(void); void __init mptcp_pm_nl_init(void); void mptcp_pm_worker(struct mptcp_sock *msk); void __mptcp_pm_kernel_worker(struct mptcp_sock *msk);
On Thu, Mar 13, 2025 at 11:20:56AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This patch defines the original in-kernel netlink path manager as a new struct mptcp_pm_ops named "mptcp_pm_kernel", and register it in mptcp_pm_kernel_register(). And define the userspace path manager as a new struct mptcp_pm_ops named "mptcp_pm_userspace", and register it in mptcp_pm_init().
To ensure that there's always a valid path manager available, the default path manager "mptcp_pm_kernel" will be skipped in mptcp_pm_unregister().
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
Similar to net.mptcp.scheduler, a new net.mptcp.path_manager sysctl knob is added to determine which path manager will be used by each newly created MPTCP socket by setting the name of it.
Dealing with an explicit name is easier than with a number, especially when more PMs will be introduced.
This sysctl knob makes the old one "pm_type" deprecated.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- Documentation/networking/mptcp-sysctl.rst | 19 ++++++++++++ net/mptcp/ctrl.c | 50 +++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 1 + 3 files changed, 70 insertions(+)
diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index 03e1d3610333e29423b0f40591c9e914dc2d0366..b78a2254d4523e0c0fa09338d4b676da18f82d97 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -72,6 +72,23 @@ enabled - BOOLEAN
Default: 1 (enabled)
+path_manager - STRING + Set the default path manager name to use for each new MPTCP + socket. In-kernel path management will control subflow + connections and address advertisements according to + per-namespace values configured over the MPTCP netlink + API. Userspace path management puts per-MPTCP-connection subflow + connection decisions and address advertisements under control of + a privileged userspace program, at the cost of more netlink + traffic to propagate all of the related events and commands. + + This is a per-namespace sysctl. + + * "kernel" - In-kernel path manager + * "userspace" - Userspace path manager + + Default: "kernel" + pm_type - INTEGER Set the default path manager type to use for each new MPTCP socket. In-kernel path management will control subflow @@ -84,6 +101,8 @@ pm_type - INTEGER
This is a per-namespace sysctl.
+ Deprecated since v6.15, use path_manager instead. + * 0 - In-kernel path manager * 1 - Userspace path manager
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index be6c0237e10bfd7520edd3c57ec43ce4377b97d5..4209dc7f97048d27deea1923742dfd5ebd710694 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -39,6 +39,7 @@ struct mptcp_pernet { u8 allow_join_initial_addr_port; u8 pm_type; char scheduler[MPTCP_SCHED_NAME_MAX]; + char path_manager[MPTCP_PM_NAME_MAX]; };
static struct mptcp_pernet *mptcp_get_pernet(const struct net *net) @@ -83,6 +84,11 @@ int mptcp_get_pm_type(const struct net *net) return mptcp_get_pernet(net)->pm_type; }
+const char *mptcp_get_path_manager(const struct net *net) +{ + return mptcp_get_pernet(net)->path_manager; +} + const char *mptcp_get_scheduler(const struct net *net) { return mptcp_get_pernet(net)->scheduler; @@ -101,6 +107,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) pernet->stale_loss_cnt = 4; pernet->pm_type = MPTCP_PM_TYPE_KERNEL; strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler)); + strscpy(pernet->path_manager, "kernel", sizeof(pernet->path_manager)); }
#ifdef CONFIG_SYSCTL @@ -174,6 +181,42 @@ static int proc_blackhole_detect_timeout(const struct ctl_table *table, return ret; }
+static int mptcp_set_path_manager(char *path_manager, const char *name) +{ + struct mptcp_pm_ops *pm_ops; + int ret = 0; + + rcu_read_lock(); + pm_ops = mptcp_pm_find(name); + if (pm_ops) + strscpy(path_manager, name, MPTCP_PM_NAME_MAX); + else + ret = -ENOENT; + rcu_read_unlock(); + + return ret; +} + +static int proc_path_manager(const struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + char (*path_manager)[MPTCP_PM_NAME_MAX] = ctl->data; + char pm_name[MPTCP_PM_NAME_MAX]; + const struct ctl_table tbl = { + .data = pm_name, + .maxlen = MPTCP_PM_NAME_MAX, + }; + int ret; + + strscpy(pm_name, *path_manager, MPTCP_PM_NAME_MAX); + + ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + if (write && ret == 0) + ret = mptcp_set_path_manager(*path_manager, pm_name); + + return ret; +} + static struct ctl_table mptcp_sysctl_table[] = { { .procname = "enabled", @@ -253,6 +296,12 @@ static struct ctl_table mptcp_sysctl_table[] = { .mode = 0644, .proc_handler = proc_dou8vec_minmax, }, + { + .procname = "path_manager", + .maxlen = MPTCP_PM_NAME_MAX, + .mode = 0644, + .proc_handler = proc_path_manager, + }, };
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) @@ -278,6 +327,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[8].data = &pernet->close_timeout; table[9].data = &pernet->blackhole_timeout; table[10].data = &pernet->syn_retrans_before_tcp_fallback; + table[11].data = &pernet->path_manager;
hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table, ARRAY_SIZE(mptcp_sysctl_table)); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index c9e435a1fd7c7ab22a279c6de7c1573fe45cee98..818c2c648677c255a00d668ab9b7406f0731fcf8 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -699,6 +699,7 @@ int mptcp_allow_join_id0(const struct net *net); unsigned int mptcp_stale_loss_cnt(const struct net *net); unsigned int mptcp_close_timeout(const struct sock *sk); int mptcp_get_pm_type(const struct net *net); +const char *mptcp_get_path_manager(const struct net *net); const char *mptcp_get_scheduler(const struct net *net);
void mptcp_active_disable(struct sock *sk);
On Thu, Mar 13, 2025 at 11:20:57AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
Similar to net.mptcp.scheduler, a new net.mptcp.path_manager sysctl knob is added to determine which path manager will be used by each newly created MPTCP socket by setting the name of it.
Dealing with an explicit name is easier than with a number, especially when more PMs will be introduced.
This sysctl knob makes the old one "pm_type" deprecated.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
This patch maps the newly added path manager sysctl "path_manager" to the old one "pm_type".
path_manager pm_type
"kernel" -> MPTCP_PM_TYPE_KERNEL "userspace" -> MPTCP_PM_TYPE_USERSPACE others -> __MPTCP_PM_TYPE_NR
It is important to add this to keep a compatibility with the now deprecated pm_type sysctl knob.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/ctrl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index 4209dc7f97048d27deea1923742dfd5ebd710694..cb0811e636ff2f4bb981d2688eb8d07946fc1744 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -200,6 +200,9 @@ static int mptcp_set_path_manager(char *path_manager, const char *name) static int proc_path_manager(const struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos) { + struct mptcp_pernet *pernet = container_of(ctl->data, + struct mptcp_pernet, + path_manager); char (*path_manager)[MPTCP_PM_NAME_MAX] = ctl->data; char pm_name[MPTCP_PM_NAME_MAX]; const struct ctl_table tbl = { @@ -211,8 +214,18 @@ static int proc_path_manager(const struct ctl_table *ctl, int write, strscpy(pm_name, *path_manager, MPTCP_PM_NAME_MAX);
ret = proc_dostring(&tbl, write, buffer, lenp, ppos); - if (write && ret == 0) + if (write && ret == 0) { ret = mptcp_set_path_manager(*path_manager, pm_name); + if (ret == 0) { + u8 pm_type = __MPTCP_PM_TYPE_NR; + + if (strncmp(pm_name, "kernel", MPTCP_PM_NAME_MAX) == 0) + pm_type = MPTCP_PM_TYPE_KERNEL; + else if (strncmp(pm_name, "userspace", MPTCP_PM_NAME_MAX) == 0) + pm_type = MPTCP_PM_TYPE_USERSPACE; + pernet->pm_type = pm_type; + } + }
return ret; }
On Thu, Mar 13, 2025 at 11:20:58AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This patch maps the newly added path manager sysctl "path_manager" to the old one "pm_type".
path_manager pm_type
"kernel" -> MPTCP_PM_TYPE_KERNEL "userspace" -> MPTCP_PM_TYPE_USERSPACE others -> __MPTCP_PM_TYPE_NR
It is important to add this to keep a compatibility with the now deprecated pm_type sysctl knob.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a new proc_handler "proc_pm_type" for "pm_type" to map old path manager sysctl "pm_type" to the newly added "path_manager".
path_manager pm_type
MPTCP_PM_TYPE_KERNEL -> "kernel" MPTCP_PM_TYPE_USERSPACE -> "userspace"
It is important to add this to keep a compatibility with the now deprecated pm_type sysctl knob.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/ctrl.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index cb0811e636ff2f4bb981d2688eb8d07946fc1744..4d8b31f32eb50347d10db792f084e43c93f687c6 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -230,6 +230,29 @@ static int proc_path_manager(const struct ctl_table *ctl, int write, return ret; }
+static int proc_pm_type(const struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + struct mptcp_pernet *pernet = container_of(ctl->data, + struct mptcp_pernet, + pm_type); + int ret; + + ret = proc_dou8vec_minmax(ctl, write, buffer, lenp, ppos); + if (write && ret == 0) { + u8 pm_type = READ_ONCE(*(u8 *)ctl->data); + char *pm_name = ""; + + if (pm_type == MPTCP_PM_TYPE_KERNEL) + pm_name = "kernel"; + else if (pm_type == MPTCP_PM_TYPE_USERSPACE) + pm_name = "userspace"; + mptcp_set_path_manager(pernet->path_manager, pm_name); + } + + return ret; +} + static struct ctl_table mptcp_sysctl_table[] = { { .procname = "enabled", @@ -274,7 +297,7 @@ static struct ctl_table mptcp_sysctl_table[] = { .procname = "pm_type", .maxlen = sizeof(u8), .mode = 0644, - .proc_handler = proc_dou8vec_minmax, + .proc_handler = proc_pm_type, .extra1 = SYSCTL_ZERO, .extra2 = &mptcp_pm_type_max },
On Thu, Mar 13, 2025 at 11:20:59AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This patch adds a new proc_handler "proc_pm_type" for "pm_type" to map old path manager sysctl "pm_type" to the newly added "path_manager".
path_manager pm_type
MPTCP_PM_TYPE_KERNEL -> "kernel" MPTCP_PM_TYPE_USERSPACE -> "userspace"
It is important to add this to keep a compatibility with the now deprecated pm_type sysctl knob.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
Similarly to net.mptcp.available_schedulers, this patch adds a new one net.mptcp.available_path_managers to list the available path managers.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- Documentation/networking/mptcp-sysctl.rst | 4 ++++ include/net/mptcp.h | 2 ++ net/mptcp/ctrl.c | 25 +++++++++++++++++++++++++ net/mptcp/pm.c | 19 +++++++++++++++++++ net/mptcp/protocol.h | 1 + 5 files changed, 51 insertions(+)
diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index b78a2254d4523e0c0fa09338d4b676da18f82d97..5bfab01eff5a9db89e1484787953241c16e147cf 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -30,6 +30,10 @@ allow_join_initial_addr_port - BOOLEAN
Default: 1
+available_path_managers - STRING + Shows the available path managers choices that are registered. More + path managers may be available, but not loaded. + available_schedulers - STRING Shows the available schedulers choices that are registered. More packet schedulers may be available, but not loaded. diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 645d15695e3f5ec4b945bb543630f3dcc54453f2..bfbad695951cf664af4d05390104883268b6bcd2 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -123,6 +123,8 @@ struct mptcp_sched_ops { } ____cacheline_aligned_in_smp;
#define MPTCP_PM_NAME_MAX 16 +#define MPTCP_PM_MAX 128 +#define MPTCP_PM_BUF_MAX (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX)
struct mptcp_pm_ops { char name[MPTCP_PM_NAME_MAX]; diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index 4d8b31f32eb50347d10db792f084e43c93f687c6..d9290c5bb6c7956ca98319259f92b812680f74f7 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -253,6 +253,24 @@ static int proc_pm_type(const struct ctl_table *ctl, int write, return ret; }
+static int proc_available_path_managers(const struct ctl_table *ctl, + int write, void *buffer, + size_t *lenp, loff_t *ppos) +{ + struct ctl_table tbl = { .maxlen = MPTCP_PM_BUF_MAX, }; + int ret; + + tbl.data = kmalloc(tbl.maxlen, GFP_USER); + if (!tbl.data) + return -ENOMEM; + + mptcp_pm_get_available(tbl.data, MPTCP_PM_BUF_MAX); + ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + kfree(tbl.data); + + return ret; +} + static struct ctl_table mptcp_sysctl_table[] = { { .procname = "enabled", @@ -338,6 +356,12 @@ static struct ctl_table mptcp_sysctl_table[] = { .mode = 0644, .proc_handler = proc_path_manager, }, + { + .procname = "available_path_managers", + .maxlen = MPTCP_PM_BUF_MAX, + .mode = 0444, + .proc_handler = proc_available_path_managers, + }, };
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) @@ -364,6 +388,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[9].data = &pernet->blackhole_timeout; table[10].data = &pernet->syn_retrans_before_tcp_fallback; table[11].data = &pernet->path_manager; + /* table[12] is for available_path_managers which is read-only info */
hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table, ARRAY_SIZE(mptcp_sysctl_table)); diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 3896f21a46bd7f6912d2ffe22a3984ba97923021..18b19dbccbba72916b2f666600a2bc8993ebd1df 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -1070,3 +1070,22 @@ void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops) list_del_rcu(&pm_ops->list); spin_unlock(&mptcp_pm_list_lock); } + +/* Build string with list of available path manager values. + * Similar to tcp_get_available_congestion_control() + */ +void mptcp_pm_get_available(char *buf, size_t maxlen) +{ + struct mptcp_pm_ops *pm_ops; + size_t offs = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(pm_ops, &mptcp_pm_list, list) { + offs += snprintf(buf + offs, maxlen - offs, "%s%s", + offs == 0 ? "" : " ", pm_ops->name); + + if (WARN_ON_ONCE(offs >= maxlen)) + break; + } + rcu_read_unlock(); +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 818c2c648677c255a00d668ab9b7406f0731fcf8..d409586b5977f93bff14fffd83b1d3020d57353b 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1058,6 +1058,7 @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name); int mptcp_pm_register(struct mptcp_pm_ops *pm_ops); void mptcp_pm_unregister(struct mptcp_pm_ops *pm_ops); int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops); +void mptcp_pm_get_available(char *buf, size_t maxlen);
void mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock *msk);
On Thu, Mar 13, 2025 at 11:21:00AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
Similarly to net.mptcp.available_schedulers, this patch adds a new one net.mptcp.available_path_managers to list the available path managers.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
From: Geliang Tang tanggeliang@kylinos.cn
This patch checks if the newly added net.mptcp.path_manager is mapped successfully from or to the old net.mptcp.pm_type in userspace_pm.sh.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/userspace_pm.sh | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh index 3651f73451cf8b07d4492c60da45e88aabc44b7a..333064b0b5ac03ae003417d2070f3c08f94743ed 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -117,7 +117,36 @@ cleanup() trap cleanup EXIT
# Create and configure network namespaces for testing +print_title "Init" mptcp_lib_ns_init ns1 ns2 + +# check path_manager and pm_type sysctl mapping +if [ -f /proc/sys/net/mptcp/path_manager ]; then + ip netns exec "$ns1" sysctl -q net.mptcp.path_manager=userspace + pm_type="$(ip netns exec "$ns1" sysctl -n net.mptcp.pm_type)" + if [ "${pm_type}" != "1" ]; then + test_fail "unexpected pm_type: ${pm_type}" + mptcp_lib_result_print_all_tap + exit ${KSFT_FAIL} + fi + + ip netns exec "$ns1" sysctl -q net.mptcp.path_manager=error 2>/dev/null + pm_type="$(ip netns exec "$ns1" sysctl -n net.mptcp.pm_type)" + if [ "${pm_type}" != "1" ]; then + test_fail "unexpected pm_type after error: ${pm_type}" + mptcp_lib_result_print_all_tap + exit ${KSFT_FAIL} + fi + + ip netns exec "$ns1" sysctl -q net.mptcp.pm_type=0 + pm_name="$(ip netns exec "$ns1" sysctl -n net.mptcp.path_manager)" + if [ "${pm_name}" != "kernel" ]; then + test_fail "unexpected path-manager: ${pm_name}" + mptcp_lib_result_print_all_tap + exit ${KSFT_FAIL} + fi +fi + for i in "$ns1" "$ns2" ;do ip netns exec "$i" sysctl -q net.mptcp.pm_type=1 done @@ -152,7 +181,6 @@ mptcp_lib_events "${ns1}" "${server_evts}" server_evts_pid sleep 0.5 mptcp_lib_subtests_last_ts_reset
-print_title "Init" print_test "Created network namespaces ns1, ns2" test_pass
On Thu, Mar 13, 2025 at 11:21:01AM +0100, Matthieu Baerts (NGI0) wrote:
From: Geliang Tang tanggeliang@kylinos.cn
This patch checks if the newly added net.mptcp.path_manager is mapped successfully from or to the old net.mptcp.pm_type in userspace_pm.sh.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org
Reviewed-by: Simon Horman horms@kernel.org
Hello:
This series was applied to netdev/net-next.git (main) by Paolo Abeni pabeni@redhat.com:
On Thu, 13 Mar 2025 11:20:49 +0100 you wrote:
Here are a few cleanups, preparation work for the new PM ops, and sysctl knobs.
Patch 1: reorg: move generic NL code used by all PMs to pm_netlink.c.
Patch 2: use kmemdup() instead of kmalloc + copy.
[...]
Here is the summary with links: - [net-next,01/12] mptcp: pm: split netlink and in-kernel init https://git.kernel.org/netdev/net-next/c/b97d6b682027 - [net-next,02/12] mptcp: pm: in-kernel: use kmemdup helper https://git.kernel.org/netdev/net-next/c/fa123489e7ef - [net-next,03/12] mptcp: pm: use pm variable instead of msk->pm https://git.kernel.org/netdev/net-next/c/5fff36b69cd4 - [net-next,04/12] mptcp: pm: only fill id_avail_bitmap for in-kernel pm https://git.kernel.org/netdev/net-next/c/98a0a99e81b6 - [net-next,05/12] mptcp: pm: add struct_group in mptcp_pm_data https://git.kernel.org/netdev/net-next/c/eff5b1578e99 - [net-next,06/12] mptcp: pm: define struct mptcp_pm_ops https://git.kernel.org/netdev/net-next/c/1305b0c22eca - [net-next,07/12] mptcp: pm: register in-kernel and userspace PM https://git.kernel.org/netdev/net-next/c/770170b41810 - [net-next,08/12] mptcp: sysctl: set path manager by name https://git.kernel.org/netdev/net-next/c/595c26d122d1 - [net-next,09/12] mptcp: sysctl: map path_manager to pm_type https://git.kernel.org/netdev/net-next/c/573b653401a8 - [net-next,10/12] mptcp: sysctl: map pm_type to path_manager https://git.kernel.org/netdev/net-next/c/7982ed0edda3 - [net-next,11/12] mptcp: sysctl: add available_path_managers https://git.kernel.org/netdev/net-next/c/fa3ee9dd8067 - [net-next,12/12] selftests: mptcp: add pm sysctl mapping tests https://git.kernel.org/netdev/net-next/c/9cf0128e64ab
You are awesome, thank you!
linux-kselftest-mirror@lists.linaro.org