:p
atchew
Login
From: Geliang Tang <tanggeliang@kylinos.cn> Some path manager related refactoring and cleanups. Geliang Tang (6): mptcp: pm: in-kernel: avoid access entry without lock mptcp: pm: in-kernel: reduce parameters of set_flags mptcp: pm: use addr entry for get_local_id mptcp: pm: in-kernel: use kmemdup helper sock: add sock_kmemdup helper mptcp: pm: userspace: use sock_kmemdup helper include/net/sock.h | 1 + net/core/sock.c | 23 +++++++++++++++++++++++ net/mptcp/pm.c | 9 ++++++--- net/mptcp/pm_netlink.c | 30 +++++++++++++----------------- net/mptcp/pm_userspace.c | 20 +++++++------------- net/mptcp/protocol.h | 6 ++++-- 6 files changed, 54 insertions(+), 35 deletions(-) -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> In mptcp_pm_nl_set_flags(), "entry" is copied to "local" when pernet->lock is held to avoid direct access to entry without pernet->lock. Therefore, "local->flags" should be passed to mptcp_nl_set_flags instead of "entry->flags" when pernet->lock is not held, so as to avoid access to entry. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local, *local = *entry; spin_unlock_bh(&pernet->lock); - mptcp_nl_set_flags(net, &local->addr, entry->flags, changed); + mptcp_nl_set_flags(net, &local->addr, local->flags, changed); return 0; } -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> The number of parameters in mptcp_nl_set_flags() can be reduced. Only need to pass a "local" parameter to it instead of "local->addr" and "local->flags". Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm_netlink.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk, spin_unlock_bh(&msk->pm.lock); } -static void mptcp_nl_set_flags(struct net *net, struct mptcp_addr_info *addr, - u8 flags, u8 changed) +static void mptcp_nl_set_flags(struct net *net, + struct mptcp_pm_addr_entry *local, + u8 changed) { - u8 is_subflow = !!(flags & MPTCP_PM_ADDR_FLAG_SUBFLOW); - u8 bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP); + u8 is_subflow = !!(local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW); + u8 bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP); long s_slot = 0, s_num = 0; struct mptcp_sock *msk; @@ -XXX,XX +XXX,XX @@ static void mptcp_nl_set_flags(struct net *net, struct mptcp_addr_info *addr, lock_sock(sk); if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) - mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup); + mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, NULL, bkup); /* Subflows will only be recreated if the SUBFLOW flag is set */ if (is_subflow && (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)) - mptcp_pm_nl_fullmesh(msk, addr); + mptcp_pm_nl_fullmesh(msk, &local->addr); release_sock(sk); next: @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local, *local = *entry; spin_unlock_bh(&pernet->lock); - mptcp_nl_set_flags(net, &local->addr, local->flags, changed); + mptcp_nl_set_flags(net, local, changed); return 0; } -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> The following code in mptcp_userspace_pm_get_local_id() that assigns "skc" to "new_entry" is not allowed in BPF if we use the same code to implement the get_local_id() interface of a BFP path manager: memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); new_entry.addr = *skc; new_entry.addr.id = 0; new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; To solve the issue, this patch moves this assignment to "new_entry" forward to mptcp_pm_get_local_id(), and then passing "new_entry" as a parameter to both mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id(). Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 9 ++++++--- net/mptcp/pm_netlink.c | 11 ++++------- net/mptcp/pm_userspace.c | 17 ++++++----------- net/mptcp/protocol.h | 6 ++++-- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) { - struct mptcp_addr_info skc_local; + struct mptcp_pm_addr_entry skc_local = { 0 }; struct mptcp_addr_info msk_local; if (WARN_ON_ONCE(!msk)) @@ -XXX,XX +XXX,XX @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) * addr */ mptcp_local_address((struct sock_common *)msk, &msk_local); - mptcp_local_address((struct sock_common *)skc, &skc_local); - if (mptcp_addresses_equal(&msk_local, &skc_local, false)) + mptcp_local_address((struct sock_common *)skc, &skc_local.addr); + if (mptcp_addresses_equal(&msk_local, &skc_local.addr, false)) return 0; + skc_local.addr.id = 0; + skc_local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; + if (mptcp_pm_is_userspace(msk)) return mptcp_userspace_pm_get_local_id(msk, &skc_local); return mptcp_pm_nl_get_local_id(msk, &skc_local); diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk, return err; } -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc) +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc) { struct mptcp_pm_addr_entry *entry; struct pm_nl_pernet *pernet; @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc pernet = pm_nl_get_pernet_from_msk(msk); rcu_read_lock(); - entry = __lookup_addr(pernet, skc); + entry = __lookup_addr(pernet, &skc->addr); ret = entry ? entry->addr.id : -1; rcu_read_unlock(); if (ret >= 0) @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc if (!entry) return -ENOMEM; - entry->addr = *skc; - entry->addr.id = 0; + *entry = *skc; entry->addr.port = 0; - entry->ifindex = 0; - entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - entry->lsk = NULL; ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true); if (ret < 0) kfree(entry); diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id) } int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) + struct mptcp_pm_addr_entry *skc) { - 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, &skc->addr); spin_unlock_bh(&msk->pm.lock); if (entry) return entry->addr.id; - memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); - new_entry.addr = *skc; - new_entry.addr.id = 0; - new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - - if (new_entry.addr.port == msk_sport) - new_entry.addr.port = 0; + if (skc->addr.port == msk_sport) + skc->addr.port = 0; - return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); + return mptcp_userspace_pm_append_new_local_addr(msk, skc, true); } bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb, bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, struct mptcp_rm_list *rm_list); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc); +int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc); bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -- 2.43.0
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> --- net/mptcp/pm_netlink.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ 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); if (ret < 0) @@ -XXX,XX +XXX,XX @@ 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) { -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> This patch adds the sock version of kmemdup() helper, named sock_kmemdup(), to duplicate a memory block using the socket's option memory buffer. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- include/net/sock.h | 1 + net/core/sock.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/net/sock.h b/include/net/sock.h index XXXXXXX..XXXXXXX 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -XXX,XX +XXX,XX @@ static inline struct sk_buff *sock_alloc_send_skb(struct sock *sk, } void *sock_kmalloc(struct sock *sk, int size, gfp_t priority); +void *sock_kmemdup(struct sock *sk, const void *src, int size, gfp_t priority); void sock_kfree_s(struct sock *sk, void *mem, int size); void sock_kzfree_s(struct sock *sk, void *mem, int size); void sk_send_sigurg(struct sock *sk); diff --git a/net/core/sock.c b/net/core/sock.c index XXXXXXX..XXXXXXX 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -XXX,XX +XXX,XX @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) } EXPORT_SYMBOL(sock_kmalloc); +/* + * Duplicate a memory block using the socket's option memory buffer. + */ +void *sock_kmemdup(struct sock *sk, const void *src, int size, gfp_t priority) +{ + int optmem_max = READ_ONCE(sock_net(sk)->core.sysctl_optmem_max); + + if ((unsigned int)size <= optmem_max && + atomic_read(&sk->sk_omem_alloc) + size < optmem_max) { + void *mem; + /* First do the add, to avoid the race if kmalloc + * might sleep. + */ + atomic_add(size, &sk->sk_omem_alloc); + mem = kmemdup(src, size, priority); + if (mem) + return mem; + atomic_sub(size, &sk->sk_omem_alloc); + } + return NULL; +} +EXPORT_SYMBOL(sock_kmemdup); + /* Free an option memory block. Note, we actually want the inline * here as this allows gcc to detect the nullify and fold away the * condition entirely. -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> Instead of using sock_kmalloc() to allocate an entry and then immediately duplicate another entry to the newly allocated one, sock_kmemdup() helper can be used to simplify the code. More importantly, the code "*e = *entry;" that assigns "entry" to "e" is not easy to implemented in BPF if we use the same code to implement an append_new_local_addr() helper of a BFP path manager. This patch avoids this type of memory assignment operation. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm_userspace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, /* Memory for the entry is allocated from the * sock option buffer. */ - e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC); + e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC); if (!e) { ret = -ENOMEM; goto append_err; } - *e = *entry; if (!e->addr.id && needs_id) e->addr.id = find_next_zero_bit(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1, -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> v6: - add "name" in struct mptcp_pm_ops. - add some "sysctl" patches. - drop "struct mptcp_pm_param". - drop "pm_type" in mptcp_pm_data. v5: - use "struct mptcp_pm_param *param" as unified parameters for all interfaces. - register in-kernel mptcp_pm_ops too. - only implement two interfaces "get_local_id" and "get_priority" in this set. v4: - include a new patch "define BPF path manager type". - add new interfaces: created established closed listerner_created listener_closed - rename interfaces as: address_announced address_removed subflow_established subflow_closed get_priority set_priority - rename functions as: mptcp_pm_validate mptcp_pm_register mptcp_pm_unregister mptcp_pm_initialize mptcp_pm_release v3: - rename the 2nd parameter of get_local_id() from 'local' to 'skc'. - keep the 'msk_sport' check in mptcp_userspace_pm_get_local_id(). - return 'err' instead of '0' in userspace_pm_subflow_create(). - drop 'ret' variable inmptcp_pm_data_reset(). - fix typos in commit log. v2: - update get_local_id interface in patch 2. get_addr() and dump_addr() interfaces of BPF userspace pm are dropped as Matt suggested. In order to implement BPF path manager, it's 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 path manager. Geliang Tang (13): mptcp: sysctl: use index for sysctl table mptcp: sysctl: add path_manager to set pm name mptcp: pm: use addr entry for get_local_id mptcp: pm: define struct mptcp_pm_ops mptcp: pm: in-kernel: register mptcp_in_kernel_pm mptcp: pm: userspace: register mptcp_userspace_pm mptcp: pm: initialize and release mptcp_pm_ops mptcp: pm: drop pm_type in mptcp_pm_data mptcp: sysctl: drop old pm_type sysctl mptcp: sysctl: add available_path_managers mptcp: pm: drop get_local_id helpers mptcp: pm: drop is_backup helpers selftests/mptcp: use path_manager instead of pm_type Documentation/networking/mptcp-sysctl.rst | 14 +- include/net/mptcp.h | 39 +++++ net/mptcp/ctrl.c | 104 ++++++++++--- net/mptcp/pm.c | 141 ++++++++++++++++-- net/mptcp/pm_netlink.c | 24 ++- net/mptcp/pm_userspace.c | 36 +++-- net/mptcp/protocol.c | 1 + net/mptcp/protocol.h | 23 ++- .../testing/selftests/net/mptcp/mptcp_join.sh | 26 ++-- .../selftests/net/mptcp/userspace_pm.sh | 4 +- 10 files changed, 324 insertions(+), 88 deletions(-) -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> The sysctl table needs to be updated when a new sysctl is added or an old sysctl is deleted. It's inconvenient to use fixed index numbers, since the index number that needs to be changed and all subsequent index numbers need to be updated accordingly. This patch adds an "i" variable to access each sysctl in the sysctl table incrementally. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/ctrl.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) { struct ctl_table_header *hdr; struct ctl_table *table; + int i = 0; table = mptcp_sysctl_table; if (!net_eq(net, &init_net)) { @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) goto err_alloc; } - table[0].data = &pernet->mptcp_enabled; - table[1].data = &pernet->add_addr_timeout; - table[2].data = &pernet->checksum_enabled; - table[3].data = &pernet->allow_join_initial_addr_port; - table[4].data = &pernet->stale_loss_cnt; - table[5].data = &pernet->pm_type; - table[6].data = &pernet->scheduler; - /* table[7] is for available_schedulers which is read-only info */ - table[8].data = &pernet->close_timeout; - table[9].data = &pernet->blackhole_timeout; - table[10].data = &pernet->syn_retrans_before_tcp_fallback; + table[i++].data = &pernet->mptcp_enabled; + table[i++].data = &pernet->add_addr_timeout; + table[i++].data = &pernet->checksum_enabled; + table[i++].data = &pernet->allow_join_initial_addr_port; + table[i++].data = &pernet->stale_loss_cnt; + table[i++].data = &pernet->pm_type; + table[i++].data = &pernet->scheduler; + i++; /* table[i] is for available_schedulers which is read-only info */ + table[i++].data = &pernet->close_timeout; + table[i++].data = &pernet->blackhole_timeout; + table[i++].data = &pernet->syn_retrans_before_tcp_fallback; hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table, ARRAY_SIZE(mptcp_sysctl_table)); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> A new net.mptcp.path_manager sysctl is added to determine which path manager will be used by each newly-created MPTCP socket by setting the name of it. This sysctl will replace the old one pm_type. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Documentation/networking/mptcp-sysctl.rst | 17 ++++++++ net/mptcp/ctrl.c | 50 +++++++++++++++++++++++ net/mptcp/protocol.h | 1 + 3 files changed, 68 insertions(+) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -XXX,XX +XXX,XX @@ pm_type - INTEGER Default: 0 +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. + + * "in-kernel" - In-kernel path manager + * "userspace" - Userspace path manager + + Default: "in-kernel" + scheduler - STRING Select the scheduler of your choice. diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -XXX,XX +XXX,XX @@ struct mptcp_pernet { u8 checksum_enabled; u8 allow_join_initial_addr_port; u8 pm_type; + char path_manager[MPTCP_PM_NAME_MAX]; char scheduler[MPTCP_SCHED_NAME_MAX]; }; @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) pernet->allow_join_initial_addr_port = 1; pernet->stale_loss_cnt = 4; pernet->pm_type = MPTCP_PM_TYPE_KERNEL; + strscpy(pernet->path_manager, "in-kernel", sizeof(pernet->path_manager)); strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler)); } #ifdef CONFIG_SYSCTL +static int mptcp_set_path_manager(char *path_manager, const char *name) +{ + struct mptcp_pm_ops *pm; + int ret = 0; + + rcu_read_lock(); + pm = mptcp_pm_find(name); + if (pm) + 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 val[MPTCP_PM_NAME_MAX]; + const struct ctl_table tbl = { + .data = val, + .maxlen = MPTCP_PM_NAME_MAX, + }; + int ret; + + strscpy(val, *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, val); + + return ret; +} + static int mptcp_set_scheduler(char *scheduler, const char *name) { struct mptcp_sched_ops *sched; @@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = &mptcp_pm_type_max }, + { + .procname = "path_manager", + .maxlen = MPTCP_PM_NAME_MAX, + .mode = 0644, + .proc_handler = proc_path_manager, + }, { .procname = "scheduler", .maxlen = MPTCP_SCHED_NAME_MAX, @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[i++].data = &pernet->allow_join_initial_addr_port; table[i++].data = &pernet->stale_loss_cnt; table[i++].data = &pernet->pm_type; + table[i++].data = &pernet->path_manager; table[i++].data = &pernet->scheduler; i++; /* table[i] is for available_schedulers which is read-only info */ table[i++].data = &pernet->close_timeout; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ 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); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> The following code in mptcp_userspace_pm_get_local_id() that assigns "skc" to "new_entry" is not allowed in BPF if we use the same code to implement the get_local_id() interface of a BFP path manager: memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); new_entry.addr = *skc; new_entry.addr.id = 0; new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; To solve the issue, this patch moves this assignment to "new_entry" forward to mptcp_pm_get_local_id(), and then passing "new_entry" as a parameter to both mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id(). Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 9 ++++++--- net/mptcp/pm_netlink.c | 11 ++++------- net/mptcp/pm_userspace.c | 17 ++++++----------- net/mptcp/protocol.h | 6 ++++-- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) { - struct mptcp_addr_info skc_local; + struct mptcp_pm_addr_entry skc_local = { 0 }; struct mptcp_addr_info msk_local; if (WARN_ON_ONCE(!msk)) @@ -XXX,XX +XXX,XX @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) * addr */ mptcp_local_address((struct sock_common *)msk, &msk_local); - mptcp_local_address((struct sock_common *)skc, &skc_local); - if (mptcp_addresses_equal(&msk_local, &skc_local, false)) + mptcp_local_address((struct sock_common *)skc, &skc_local.addr); + if (mptcp_addresses_equal(&msk_local, &skc_local.addr, false)) return 0; + skc_local.addr.id = 0; + skc_local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; + if (mptcp_pm_is_userspace(msk)) return mptcp_userspace_pm_get_local_id(msk, &skc_local); return mptcp_pm_nl_get_local_id(msk, &skc_local); diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk, return err; } -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc) +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc) { struct mptcp_pm_addr_entry *entry; struct pm_nl_pernet *pernet; @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc pernet = pm_nl_get_pernet_from_msk(msk); rcu_read_lock(); - entry = __lookup_addr(pernet, skc); + entry = __lookup_addr(pernet, &skc->addr); ret = entry ? entry->addr.id : -1; rcu_read_unlock(); if (ret >= 0) @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc if (!entry) return -ENOMEM; - entry->addr = *skc; - entry->addr.id = 0; + *entry = *skc; entry->addr.port = 0; - entry->ifindex = 0; - entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - entry->lsk = NULL; ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true); if (ret < 0) kfree(entry); diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id) } int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) + struct mptcp_pm_addr_entry *skc) { - 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, &skc->addr); spin_unlock_bh(&msk->pm.lock); if (entry) return entry->addr.id; - memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); - new_entry.addr = *skc; - new_entry.addr.id = 0; - new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - - if (new_entry.addr.port == msk_sport) - new_entry.addr.port = 0; + if (skc->addr.port == msk_sport) + skc->addr.port = 0; - return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); + return mptcp_userspace_pm_append_new_local_addr(msk, skc, true); } bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb, bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, struct mptcp_rm_list *rm_list); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc); +int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc); bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -- 2.43.0
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 | 37 +++++++++++++++++++++++++++++ net/mptcp/pm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 5 ++++ 3 files changed, 97 insertions(+) diff --git a/include/net/mptcp.h b/include/net/mptcp.h index XXXXXXX..XXXXXXX 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -XXX,XX +XXX,XX @@ struct mptcp_info; struct mptcp_sock; +struct mptcp_pm_addr_entry; struct seq_file; /* MPTCP sk_buff extension data */ @@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops { void (*release)(struct mptcp_sock *msk); } ____cacheline_aligned_in_smp; +#define MPTCP_PM_NAME_MAX 16 + +struct mptcp_pm_ops { + int (*created)(struct mptcp_sock *msk); + int (*established)(struct mptcp_sock *msk); + int (*closed)(struct mptcp_sock *msk); + int (*get_local_id)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc); + bool (*get_priority)(struct mptcp_sock *msk, + struct mptcp_addr_info *skc); + int (*address_announced)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *local); + int (*address_removed)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *local); + int (*subflow_established)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *local, + struct mptcp_addr_info *remote); + int (*subflow_closed)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *local, + struct mptcp_addr_info *remote); + int (*set_priority)(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *local, + struct mptcp_addr_info *remote, + u8 changed); + int (*listener_created)(struct mptcp_sock *msk); + int (*listener_closed)(struct mptcp_sock *msk); + + u8 type; + 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 XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ #define pr_fmt(fmt) "MPTCP: " fmt #include <linux/kernel.h> +#include <linux/rculist.h> +#include <linux/spinlock.h> #include <net/mptcp.h> #include "protocol.h" #include "mib.h" #include "mptcp_pm_gen.h" +static DEFINE_SPINLOCK(mptcp_pm_list_lock); +static LIST_HEAD(mptcp_pm_list); + /* path manager command handlers */ int mptcp_pm_announce_addr(struct mptcp_sock *msk, @@ -XXX,XX +XXX,XX @@ void __init mptcp_pm_init(void) { 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; + + list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { + if (!strcmp(pm->name, name)) + return pm; + } + + return NULL; +} + +int mptcp_pm_validate(struct mptcp_pm_ops *pm) +{ + if (!pm->get_local_id || !pm->get_priority) { + pr_err("%u does not implement required ops\n", pm->type); + return -EINVAL; + } + + return 0; +} + +int mptcp_pm_register(struct mptcp_pm_ops *pm) +{ + int ret; + + ret = mptcp_pm_validate(pm); + if (ret) + return ret; + + spin_lock(&mptcp_pm_list_lock); + if (mptcp_pm_find(pm->name)) { + 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("%s registered\n", pm->name); + return 0; +} + +void mptcp_pm_unregister(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 XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ 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_validate(struct mptcp_pm_ops *pm); +int mptcp_pm_register(struct mptcp_pm_ops *pm); +void mptcp_pm_unregister(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
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_in_kernel_pm", and register it in mptcp_pm_nl_init(). This mptcp_pm_ops will be skipped in mptcp_pm_unregister(). Only get_local_id() and get_priority() interfaces are implemented here. mptcp_pm_nl_is_backup() becomes a wrapper of get_priority(). Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 3 +++ net/mptcp/pm_netlink.c | 18 +++++++++++++++++- net/mptcp/protocol.h | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_register(struct mptcp_pm_ops *pm) void mptcp_pm_unregister(struct mptcp_pm_ops *pm) { + if (pm == &mptcp_in_kernel_pm) + return; + spin_lock(&mptcp_pm_list_lock); list_del_rcu(&pm->list); spin_unlock(&mptcp_pm_list_lock); diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, return ret; } -bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) +static bool mptcp_pm_nl_get_priority(struct mptcp_sock *msk, + struct mptcp_addr_info *skc) { struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); struct mptcp_pm_addr_entry *entry; @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) return backup; } +bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) +{ + return mptcp_pm_nl_get_priority(msk, skc); +} + #define MPTCP_PM_CMD_GRP_OFFSET 0 #define MPTCP_PM_EV_GRP_OFFSET 1 @@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = { .size = sizeof(struct pm_nl_pernet), }; +struct mptcp_pm_ops mptcp_in_kernel_pm = { + .get_local_id = mptcp_pm_nl_get_local_id, + .get_priority = mptcp_pm_nl_get_priority, + .type = MPTCP_PM_TYPE_KERNEL, + .name = "in-kernel", + .owner = THIS_MODULE, +}; + void __init mptcp_pm_nl_init(void) { if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0) @@ -XXX,XX +XXX,XX @@ void __init mptcp_pm_nl_init(void) if (genl_register_family(&mptcp_genl_family)) panic("Failed to register MPTCP PM netlink family\n"); + + mptcp_pm_register(&mptcp_in_kernel_pm); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ 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); +extern struct mptcp_pm_ops mptcp_in_kernel_pm; + struct mptcp_pm_ops *mptcp_pm_find(const char *name); int mptcp_pm_validate(struct mptcp_pm_ops *pm); int mptcp_pm_register(struct mptcp_pm_ops *pm); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> This patch defines the original userspace path manager as a new struct mptcp_pm_ops named "mptcp_userspace_pm", and register it in mptcp_pm_data_init(). Only get_local_id() and get_priority() interfaces are implemented here. mptcp_userspace_pm_is_backup() becomes a wrapper of get_priority(). Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 1 + net/mptcp/pm_userspace.c | 23 +++++++++++++++++++++-- net/mptcp/protocol.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_init(struct mptcp_sock *msk) void __init mptcp_pm_init(void) { mptcp_pm_nl_init(); + mptcp_userspace_pm_init(); } /* Must be called with rcu read lock held */ diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, return mptcp_userspace_pm_append_new_local_addr(msk, skc, true); } -bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) +static bool mptcp_userspace_pm_get_priority(struct mptcp_sock *msk, + struct mptcp_addr_info *skc) { struct mptcp_pm_addr_entry *entry; bool backup; @@ -XXX,XX +XXX,XX @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, return backup; } +bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, + struct mptcp_addr_info *skc) +{ + return mptcp_userspace_pm_get_priority(msk, skc); +} + static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info) { struct mptcp_sock *msk; @@ -XXX,XX +XXX,XX @@ 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_userspace_pm = { + .get_local_id = mptcp_userspace_pm_get_local_id, + .get_priority = mptcp_userspace_pm_get_priority, + .type = MPTCP_PM_TYPE_USERSPACE, + .name = "userspace", + .owner = THIS_MODULE, +}; + +void __init mptcp_userspace_pm_init(void) +{ + mptcp_pm_register(&mptcp_userspace_pm); +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ 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
From: Geliang Tang <tanggeliang@kylinos.cn> Add a struct mptcp_pm_ops pointer "ops" in struct mptcp_pm_data, and two functions mptcp_pm_initialize() and mptcp_pm_release(), to set and release this pointer. mptcp_pm_initialize() is invoked in mptcp_pm_data_reset(), while mptcp_pm_release() is invoked in mptcp_destroy_common(). Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 38 ++++++++++++++++++++++++++++++++++++++ net/mptcp/protocol.c | 1 + net/mptcp/protocol.h | 3 +++ 3 files changed, 42 insertions(+) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_addr_families_match(const struct sock *sk, void mptcp_pm_data_reset(struct mptcp_sock *msk) { + const char *path_manager = mptcp_get_path_manager(sock_net((struct 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; @@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_reset(struct mptcp_sock *msk) pm->rm_list_rx.nr = 0; WRITE_ONCE(pm->pm_type, pm_type); + rcu_read_lock(); + ret = mptcp_pm_initialize(msk, mptcp_pm_find(path_manager)); + rcu_read_unlock(); + if (ret) + return; + if (pm_type == MPTCP_PM_TYPE_KERNEL) { bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); @@ -XXX,XX +XXX,XX @@ void mptcp_pm_unregister(struct mptcp_pm_ops *pm) list_del_rcu(&pm->list); spin_unlock(&mptcp_pm_list_lock); } + +int mptcp_pm_initialize(struct mptcp_sock *msk, struct mptcp_pm_ops *pm) +{ + if (!pm) + pm = &mptcp_in_kernel_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("pm %s initialized\n", pm->name); + return 0; +} + +void mptcp_pm_release(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); +} diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -XXX,XX +XXX,XX @@ void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) mptcp_token_destroy(msk); mptcp_pm_free_anno_list(msk); mptcp_free_local_addr_list(msk); + mptcp_pm_release(msk); } static void mptcp_destroy(struct sock *sk) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name); int mptcp_pm_validate(struct mptcp_pm_ops *pm); int mptcp_pm_register(struct mptcp_pm_ops *pm); void mptcp_pm_unregister(struct mptcp_pm_ops *pm); +int mptcp_pm_initialize(struct mptcp_sock *msk, struct mptcp_pm_ops *pm); +void mptcp_pm_release(struct mptcp_sock *msk); void mptcp_free_local_addr_list(struct mptcp_sock *msk); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> Now pm->pm_type can be replaced by pm->ops->type, then "pm_type" filed of struct mptcp_pm_data can be dropped. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 6 ++---- net/mptcp/protocol.h | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_addr_families_match(const struct sock *sk, void mptcp_pm_data_reset(struct mptcp_sock *msk) { const char *path_manager = mptcp_get_path_manager(sock_net((struct sock *)msk)); - u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk)); struct mptcp_pm_data *pm = &msk->pm; int ret; @@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_reset(struct mptcp_sock *msk) pm->subflows = 0; pm->rm_list_tx.nr = 0; pm->rm_list_rx.nr = 0; - WRITE_ONCE(pm->pm_type, pm_type); rcu_read_lock(); ret = mptcp_pm_initialize(msk, mptcp_pm_find(path_manager)); @@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_reset(struct mptcp_sock *msk) if (ret) return; - if (pm_type == MPTCP_PM_TYPE_KERNEL) { + if (pm->ops->type == MPTCP_PM_TYPE_KERNEL) { bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); /* pm->work_pending must be only be set to 'true' when - * pm->pm_type is set to MPTCP_PM_TYPE_KERNEL + * pm->ops->type is set to MPTCP_PM_TYPE_KERNEL */ WRITE_ONCE(pm->work_pending, (!!mptcp_pm_get_local_addr_max(msk) && diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_data { u8 add_addr_signaled; u8 add_addr_accepted; u8 local_addr_used; - u8 pm_type; u8 subflows; u8 status; DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); @@ -XXX,XX +XXX,XX @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk) static inline bool mptcp_pm_is_userspace(const struct mptcp_sock *msk) { - return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_USERSPACE; + return msk->pm.ops->type == MPTCP_PM_TYPE_USERSPACE; } static inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk) { - return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_KERNEL; + return msk->pm.ops->type == MPTCP_PM_TYPE_KERNEL; } static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port) -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> Old path manager sysctl "pm_type" can be replaced by the newly added "path_manager". Drop it together with mptcp_get_pm_type() helper. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Documentation/networking/mptcp-sysctl.rst | 17 ----------------- net/mptcp/ctrl.c | 20 -------------------- net/mptcp/protocol.h | 1 - 3 files changed, 38 deletions(-) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -XXX,XX +XXX,XX @@ enabled - BOOLEAN Default: 1 (enabled) -pm_type - INTEGER - Set the default path manager type 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. - - * 0 - In-kernel path manager - * 1 - Userspace path manager - - Default: 0 - path_manager - STRING Set the default path manager name to use for each new MPTCP socket. In-kernel path management will control subflow diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_id; -#ifdef CONFIG_SYSCTL -static int mptcp_pm_type_max = __MPTCP_PM_TYPE_MAX; -#endif - struct mptcp_pernet { #ifdef CONFIG_SYSCTL struct ctl_table_header *ctl_table_hdr; @@ -XXX,XX +XXX,XX @@ struct mptcp_pernet { u8 mptcp_enabled; u8 checksum_enabled; u8 allow_join_initial_addr_port; - u8 pm_type; char path_manager[MPTCP_PM_NAME_MAX]; char scheduler[MPTCP_SCHED_NAME_MAX]; }; @@ -XXX,XX +XXX,XX @@ unsigned int mptcp_close_timeout(const struct sock *sk) return mptcp_get_pernet(sock_net(sk))->close_timeout; } -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; @@ -XXX,XX +XXX,XX @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) pernet->checksum_enabled = 0; pernet->allow_join_initial_addr_port = 1; pernet->stale_loss_cnt = 4; - pernet->pm_type = MPTCP_PM_TYPE_KERNEL; strscpy(pernet->path_manager, "in-kernel", sizeof(pernet->path_manager)); strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler)); } @@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = { .mode = 0644, .proc_handler = proc_douintvec_minmax, }, - { - .procname = "pm_type", - .maxlen = sizeof(u8), - .mode = 0644, - .proc_handler = proc_dou8vec_minmax, - .extra1 = SYSCTL_ZERO, - .extra2 = &mptcp_pm_type_max - }, { .procname = "path_manager", .maxlen = MPTCP_PM_NAME_MAX, @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[i++].data = &pernet->checksum_enabled; table[i++].data = &pernet->allow_join_initial_addr_port; table[i++].data = &pernet->stale_loss_cnt; - table[i++].data = &pernet->pm_type; table[i++].data = &pernet->path_manager; table[i++].data = &pernet->scheduler; i++; /* table[i] is for available_schedulers which is read-only info */ diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ int mptcp_is_checksum_enabled(const struct net *net); 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); -- 2.43.0
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 mangers. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Documentation/networking/mptcp-sysctl.rst | 4 ++++ include/net/mptcp.h | 2 ++ net/mptcp/ctrl.c | 25 +++++++++++++++++++++++ net/mptcp/pm.c | 20 ++++++++++++++++++ net/mptcp/protocol.h | 1 + 5 files changed, 52 insertions(+) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -XXX,XX +XXX,XX @@ path_manager - STRING Default: "in-kernel" +available_path_managers - STRING + Shows the available path managers choices that are registered. More + path managers may be available, but not loaded. + scheduler - STRING Select the scheduler of your choice. diff --git a/include/net/mptcp.h b/include/net/mptcp.h index XXXXXXX..XXXXXXX 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -XXX,XX +XXX,XX @@ 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 { int (*created)(struct mptcp_sock *msk); diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -XXX,XX +XXX,XX @@ static int proc_path_manager(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 int mptcp_set_scheduler(char *scheduler, const char *name) { struct mptcp_sched_ops *sched; @@ -XXX,XX +XXX,XX @@ 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, + }, { .procname = "scheduler", .maxlen = MPTCP_SCHED_NAME_MAX, @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[i++].data = &pernet->allow_join_initial_addr_port; table[i++].data = &pernet->stale_loss_cnt; table[i++].data = &pernet->path_manager; + i++; /* table[i] is for available_path_managers which is read-only info */ table[i++].data = &pernet->scheduler; i++; /* table[i] is for available_schedulers which is read-only info */ table[i++].data = &pernet->close_timeout; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) return NULL; } +/* 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; + size_t offs = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { + offs += snprintf(buf + offs, maxlen - offs, + "%s%s", + offs == 0 ? "" : " ", pm->name); + + if (WARN_ON_ONCE(offs >= maxlen)) + break; + } + rcu_read_unlock(); +} + int mptcp_pm_validate(struct mptcp_pm_ops *pm) { if (!pm->get_local_id || !pm->get_priority) { diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk, extern struct mptcp_pm_ops mptcp_in_kernel_pm; struct mptcp_pm_ops *mptcp_pm_find(const char *name); +void mptcp_pm_get_available(char *buf, size_t maxlen); int mptcp_pm_validate(struct mptcp_pm_ops *pm); int mptcp_pm_register(struct mptcp_pm_ops *pm); void mptcp_pm_unregister(struct mptcp_pm_ops *pm); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> Now mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id() helpers can be dropped, and mptcp_pm_get_local_id() can directly invoke get_local_id() interface through "ops" of "msk->pm". Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 4 +--- net/mptcp/pm_netlink.c | 4 ++-- net/mptcp/pm_userspace.c | 4 ++-- net/mptcp/protocol.h | 4 ---- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) skc_local.addr.id = 0; skc_local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - if (mptcp_pm_is_userspace(msk)) - return mptcp_userspace_pm_get_local_id(msk, &skc_local); - return mptcp_pm_nl_get_local_id(msk, &skc_local); + return msk->pm.ops->get_local_id(msk, &skc_local); } bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk, return err; } -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *skc) +static int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc) { struct mptcp_pm_addr_entry *entry; struct pm_nl_pernet *pernet; diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id) return NULL; } -int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *skc) +static int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *skc) { __be16 msk_sport = ((struct inet_sock *) inet_sk((struct sock *)msk))->inet_sport; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb, bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, struct mptcp_rm_list *rm_list); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *skc); -int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *skc); bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> Now mptcp_pm_nl_is_backup() and mptcp_userspace_pm_is_backup() helpers can be dropped, and mptcp_pm_is_backup() can directly invoke get_priority() interface through "ops" of "msk->pm". Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 5 +---- net/mptcp/pm_netlink.c | 5 ----- net/mptcp/pm_userspace.c | 6 ------ net/mptcp/protocol.h | 2 -- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc) mptcp_local_address((struct sock_common *)skc, &skc_local); - if (mptcp_pm_is_userspace(msk)) - return mptcp_userspace_pm_is_backup(msk, &skc_local); - - return mptcp_pm_nl_is_backup(msk, &skc_local); + return msk->pm.ops->get_priority(msk, &skc_local); } static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_nl_get_priority(struct mptcp_sock *msk, return backup; } -bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) -{ - return mptcp_pm_nl_get_priority(msk, skc); -} - #define MPTCP_PM_CMD_GRP_OFFSET 0 #define MPTCP_PM_EV_GRP_OFFSET 1 diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -XXX,XX +XXX,XX @@ static bool mptcp_userspace_pm_get_priority(struct mptcp_sock *msk, return backup; } -bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) -{ - return mptcp_userspace_pm_get_priority(msk, skc); -} - static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info) { struct mptcp_sock *msk; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, struct mptcp_rm_list *rm_list); int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); -bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); int mptcp_pm_nl_dump_addr(struct sk_buff *msg, struct netlink_callback *cb); int mptcp_userspace_pm_dump_addr(struct sk_buff *msg, -- 2.43.0
From: Geliang Tang <tanggeliang@kylinos.cn> This patch uses the newly added net.mptcp.path_manager instead of the old net.mptcp.pm_type for all path manager selftests in mptcp_join.sh and userspace_pm.sh. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- .../testing/selftests/net/mptcp/mptcp_join.sh | 26 +++++++++---------- .../selftests/net/mptcp/userspace_pm.sh | 4 +-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ init_partial() local netns for netns in "$ns1" "$ns2"; do - ip netns exec $netns sysctl -q net.mptcp.pm_type=0 2>/dev/null || true + ip netns exec $netns sysctl -q net.mptcp.path_manager="in-kernel" 2>/dev/null || true if $checksum; then ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1 fi @@ -XXX,XX +XXX,XX @@ set_userspace_pm() { local ns=$1 - ip netns exec $ns sysctl -q net.mptcp.pm_type=1 + ip netns exec $ns sysctl -q net.mptcp.path_manager="userspace" } subflows_tests() @@ -XXX,XX +XXX,XX @@ userspace_tests() { # userspace pm type prevents add_addr if reset "userspace pm type prevents add_addr" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm type does not echo add_addr without daemon if reset "userspace pm no echo w/o daemon" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm type rejects join if reset "userspace pm type rejects join" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 pm_nl_set_limits $ns1 1 1 pm_nl_set_limits $ns2 1 1 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm type does not send join if reset "userspace pm type does not send join" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 1 1 pm_nl_set_limits $ns2 1 1 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm type prevents mp_prio if reset "userspace pm type prevents mp_prio" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 pm_nl_set_limits $ns1 1 1 pm_nl_set_limits $ns2 1 1 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm type prevents rm_addr if reset "userspace pm type prevents rm_addr" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm add & remove address if reset_with_events "userspace pm add & remove address" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 2 2 { speed=5 \ @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm create destroy subflow if reset_with_events "userspace pm create destroy subflow" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 { speed=5 \ @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm create id 0 subflow if reset_with_events "userspace pm create id 0 subflow" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 { speed=5 \ @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm remove initial subflow if reset_with_events "userspace pm remove initial subflow" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 { speed=5 \ @@ -XXX,XX +XXX,XX @@ userspace_tests() # userspace pm send RM_ADDR for ID 0 if reset_with_events "userspace pm send RM_ADDR for ID 0" && - continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 1 1 { speed=5 \ diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -XXX,XX +XXX,XX @@ mptcp_lib_check_mptcp mptcp_lib_check_kallsyms -if ! mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then +if ! mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then echo "userspace pm tests are not supported by the kernel: SKIP" exit ${KSFT_SKIP} fi @@ -XXX,XX +XXX,XX @@ trap cleanup EXIT # Create and configure network namespaces for testing mptcp_lib_ns_init ns1 ns2 for i in "$ns1" "$ns2" ;do - ip netns exec "$i" sysctl -q net.mptcp.pm_type=1 + ip netns exec "$i" sysctl -q net.mptcp.path_manager="userspace" done # "$ns1" ns2 -- 2.43.0