From 9cdd8dda76eee1be73a56fbba5912ef444529815 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 16 Oct 2024 17:12:37 +0800 Subject: [PATCH] mptcp: register default userspace pm This patch defines the original userspace pm as the default path manager, named mptcp_userspace_pm, and register it in mptcp_pm_data_init(). Add a struct mptcp_pm_ops pointer "ops" in struct mptcp_pm_data, and two functions mptcp_init_pm() and mptcp_release_pm(), to set and release this pointer. mptcp_init_pm() is invoked in mptcp_pm_data_reset(), while mptcp_release_pm() is invoked in __mptcp_destroy_sock(). In this way, different userspace path managers can be initialized through the pm_type sysctl, and then called into their respective interfaces through "ops" of "msk->pm". Signed-off-by: Geliang Tang --- net/mptcp/pm.c | 4 ++ net/mptcp/pm_userspace.c | 88 ++++++++++++++++++++++++++++++++++++---- net/mptcp/protocol.c | 1 + net/mptcp/protocol.h | 4 ++ 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index c2229e46de1a4e..3b9249c34d5a75 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -516,6 +516,9 @@ 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); + + if (mptcp_init_pm(msk, mptcp_pm_find(pm_type))) + return; } WRITE_ONCE(pm->addr_signal, 0); @@ -535,4 +538,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 f07c77dca84b8d..a3d4a11daf6505 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -157,7 +157,9 @@ static int userspace_pm_get_local_id(struct mptcp_sock *msk, int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_pm_addr_entry *local) { - return userspace_pm_get_local_id(msk, local); + return INDIRECT_CALL_1(msk->pm.ops->get_local_id, + userspace_pm_get_local_id, + msk, local); } static u8 userspace_pm_get_flags(struct mptcp_sock *msk, @@ -178,7 +180,9 @@ static u8 userspace_pm_get_flags(struct mptcp_sock *msk, u8 mptcp_userspace_pm_get_flags(struct mptcp_sock *msk, struct mptcp_addr_info *skc) { - return userspace_pm_get_flags(msk, skc); + return INDIRECT_CALL_1(msk->pm.ops->get_flags, + userspace_pm_get_flags, + msk, skc); } static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info) @@ -258,7 +262,9 @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info) } lock_sock(sk); - err = userspace_pm_address_announce(msk, &addr_val); + err = INDIRECT_CALL_1(msk->pm.ops->address_announce, + userspace_pm_address_announce, + msk, &addr_val); release_sock(sk); if (err) GENL_SET_ERR_MSG(info, "address_announce failed"); @@ -344,7 +350,9 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info) sk = (struct sock *)msk; lock_sock(sk); - err = userspace_pm_address_remove(msk, id_val); + err = INDIRECT_CALL_1(msk->pm.ops->address_remove, + userspace_pm_address_remove, + msk, id_val); release_sock(sk); if (err) GENL_SET_ERR_MSG(info, "address_remove failed"); @@ -416,7 +424,9 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info) } lock_sock(sk); - err = userspace_pm_subflow_create(msk, &entry, &addr_r); + err = INDIRECT_CALL_1(msk->pm.ops->subflow_create, + userspace_pm_subflow_create, + msk, &entry, &addr_r); release_sock(sk); if (err) GENL_SET_ERR_MSG(info, "subflow_create failed"); @@ -548,7 +558,9 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info } lock_sock(sk); - err = userspace_pm_subflow_destroy(msk, &local, &addr_r); + err = INDIRECT_CALL_1(msk->pm.ops->subflow_destroy, + userspace_pm_subflow_destroy, + msk, &local, &addr_r); release_sock(sk); if (err) GENL_SET_ERR_MSG(info, "subflow_destroy failed"); @@ -602,7 +614,9 @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *loc, sk = (struct sock *)msk; lock_sock(sk); - ret = userspace_pm_set_flags(msk, loc, rem); + ret = INDIRECT_CALL_1(msk->pm.ops->set_flags, + userspace_pm_set_flags, + msk, loc, rem); release_sock(sk); if (ret) GENL_SET_ERR_MSG(info, "set_flags failed"); @@ -647,7 +661,9 @@ int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap, lock_sock(sk); spin_lock_bh(&msk->pm.lock); - ret = userspace_pm_dump_addr(msk, bitmap); + ret = INDIRECT_CALL_1(msk->pm.ops->dump_addr, + userspace_pm_dump_addr, + msk, bitmap); spin_unlock_bh(&msk->pm.lock); release_sock(sk); @@ -677,7 +693,9 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, lock_sock(sk); spin_lock_bh(&msk->pm.lock); - entry = userspace_pm_get_addr(msk, id); + entry = INDIRECT_CALL_1(msk->pm.ops->get_addr, + userspace_pm_get_addr, + msk, id); if (entry) { *addr = *entry; ret = 0; @@ -689,6 +707,20 @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, return ret; } +static struct mptcp_pm_ops mptcp_userspace_pm = { + .address_announce = userspace_pm_address_announce, + .address_remove = userspace_pm_address_remove, + .subflow_create = userspace_pm_subflow_create, + .subflow_destroy = userspace_pm_subflow_destroy, + .get_local_id = userspace_pm_get_local_id, + .get_flags = userspace_pm_get_flags, + .get_addr = userspace_pm_get_addr, + .dump_addr = userspace_pm_dump_addr, + .set_flags = userspace_pm_set_flags, + .type = MPTCP_PM_TYPE_USERSPACE, + .owner = THIS_MODULE, +}; + /* Must be called with rcu read lock held */ struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type) { @@ -724,7 +756,45 @@ int mptcp_register_path_manager(struct mptcp_pm_ops *pm) void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) { + if (pm == &mptcp_userspace_pm) + return; + spin_lock(&mptcp_pm_list_lock); list_del_rcu(&pm->list); spin_unlock(&mptcp_pm_list_lock); } + +int mptcp_init_pm(struct mptcp_sock *msk, struct mptcp_pm_ops *pm) +{ + if (!pm) + pm = &mptcp_userspace_pm; + + if (!bpf_try_module_get(pm, pm->owner)) + return -EBUSY; + + msk->pm.ops = pm; + if (msk->pm.ops->init) + msk->pm.ops->init(msk); + + pr_debug("userspace_pm type %u initialized\n", msk->pm.ops->type); + return 0; +} + +void mptcp_release_pm(struct mptcp_sock *msk) +{ + struct mptcp_pm_ops *pm = msk->pm.ops; + + if (!pm) + return; + + msk->pm.ops = NULL; + if (pm->release) + pm->release(msk); + + bpf_module_put(pm, pm->owner); +} + +void __init mptcp_userspace_pm_init(void) +{ + mptcp_register_path_manager(&mptcp_userspace_pm); +} diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index e420ce9bbfb6e0..0f4305379e58e0 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3038,6 +3038,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 722b28a8fdfa2d..16316fc0c1eb51 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -220,6 +220,7 @@ struct mptcp_pm_data { struct mptcp_addr_info remote; struct list_head anno_list; struct list_head userspace_pm_local_addr_list; + struct mptcp_pm_ops *ops; spinlock_t lock; /*protects the whole PM data */ @@ -1058,6 +1059,8 @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk, struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type); int mptcp_register_path_manager(struct mptcp_pm_ops *pm); void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); +int mptcp_init_pm(struct mptcp_sock *msk, struct mptcp_pm_ops *pm); +void mptcp_release_pm(struct mptcp_sock *msk); void mptcp_free_local_addr_list(struct mptcp_sock *msk); @@ -1157,6 +1160,7 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo } void __init mptcp_pm_nl_init(void); +void __init mptcp_userspace_pm_init(void); void mptcp_pm_nl_work(struct mptcp_sock *msk); unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk); unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);