1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Implement address_announced/address_removed/subflow_established/
3
v8:
4
subflow_closed interfaces.
4
- address Matt's comments in v7.
5
6
v7:
7
- addresss Matt's comments in v6 [1].
8
- drop "type" from struct mptcp_pm_ops as Matt suggested.
9
- map "pm_type" to new sysctl as Matt suggested.
5
10
6
Depends on:
11
Depends on:
7
- BPF path manager, part 4, v5
12
- mptcp: pm: code reorganisation, v2
8
Based-on: <cover.1740019794.git.tanggeliang@kylinos.cn>
9
13
10
Geliang Tang (9):
14
Based-on: <20250228-mptcp-pm-reorg-code-v2-0-fa8b2542b7a5@kernel.org>
11
mptcp: pm: in-kernel: add address_removed/subflow_closed
12
mptcp: pm: in-kernel: address_announced interface
13
mptcp: pm: in-kernel: address_removed interface
14
mptcp: pm: in-kernel: subflow_established interface
15
mptcp: pm: in-kernel: subflow_closed interface
16
mptcp: pm: userspace: address_announced interface
17
mptcp: pm: userspace: address_removed interface
18
mptcp: pm: userspace: subflow_established interface
19
mptcp: pm: userspace: subflow_closed interface
20
15
21
net/mptcp/pm_netlink.c | 115 ++++++++++++++------
16
[1]
22
net/mptcp/pm_userspace.c | 220 +++++++++++++++++++++++----------------
17
https://patchwork.kernel.org/project/mptcp/cover/cover.1740320007.git.tanggeliang@kylinos.cn/
23
2 files changed, 215 insertions(+), 120 deletions(-)
18
19
v6:
20
- add "name" in struct mptcp_pm_ops.
21
- add some "sysctl" patches.
22
- drop "struct mptcp_pm_param".
23
- drop "pm_type" in mptcp_pm_data.
24
25
v5:
26
- use "struct mptcp_pm_param *param" as unified parameters for all
27
interfaces.
28
- register in-kernel mptcp_pm_ops too.
29
- only implement two interfaces "get_local_id" and "get_priority" in
30
this set.
31
32
v4:
33
- include a new patch "define BPF path manager type".
34
35
- add new interfaces:
36
    created established closed
37
    listerner_created listener_closed
38
39
- rename interfaces as:
40
    address_announced address_removed
41
    subflow_established subflow_closed
42
    get_priority set_priority
43
44
- rename functions as:
45
    mptcp_pm_validate
46
    mptcp_pm_register
47
    mptcp_pm_unregister
48
    mptcp_pm_initialize
49
    mptcp_pm_release
50
51
v3:
52
- rename the 2nd parameter of get_local_id() from 'local' to 'skc'.
53
- keep the 'msk_sport' check in mptcp_userspace_pm_get_local_id().
54
- return 'err' instead of '0' in userspace_pm_subflow_create().
55
- drop 'ret' variable inmptcp_pm_data_reset().
56
- fix typos in commit log.
57
58
v2:
59
- update get_local_id interface in patch 2.
60
61
get_addr() and dump_addr() interfaces of BPF userspace pm are dropped
62
as Matt suggested.
63
64
In order to implement BPF path manager, it's necessary to unify the
65
interfaces of the path manager. This set contains some cleanups and
66
refactoring to unify the interfaces in kernel space. Finally, define
67
a struct mptcp_pm_ops for a path manager.
68
69
Geliang Tang (12):
70
mptcp: pm: define struct mptcp_pm_ops
71
mptcp: sysctl: new sysctl to set path manager by name
72
mptcp: sysctl: map pm_type to path_manager
73
mptcp: sysctl: map path_manager to pm_type
74
mptcp: sysctl: add available_path_managers
75
mptcp: pm: in-kernel: register mptcp_pm_kernel
76
mptcp: pm: userspace: register mptcp_pm_userspace
77
mptcp: pm: initialize and release mptcp_pm_ops
78
mptcp: pm: add get_local_id() interface
79
mptcp: pm: add get_priority() interface
80
selftests: mptcp: add pm_type mapping tests
81
selftests: mptcp: add path_manager sysctl test
82
83
Documentation/networking/mptcp-sysctl.rst | 23 +++
84
include/net/mptcp.h | 19 +++
85
net/mptcp/ctrl.c | 112 +++++++++++++-
86
net/mptcp/pm.c | 145 ++++++++++++++----
87
net/mptcp/pm_kernel.c | 35 ++++-
88
net/mptcp/pm_userspace.c | 36 ++++-
89
net/mptcp/protocol.h | 18 ++-
90
.../testing/selftests/net/mptcp/mptcp_join.sh | 49 +++++-
91
8 files changed, 393 insertions(+), 44 deletions(-)
24
92
25
--
93
--
26
2.43.0
94
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
This patch defines the code in the loop of traversing all msks in
3
In order to allow users to develop their own BPF-based path manager,
4
mptcp_nl_remove_subflow_and_signal_addr() as two new helpers,
4
this patch defines a struct ops "mptcp_pm_ops" for a userspace path
5
mptcp_pm_nl_address_removed() and mptcp_pm_nl_subflow_closed(),
5
manager, which contains a set of interfaces.
6
used for signaling a RM_ADDR and closing a subflow respectively.
6
7
Add a set of functions to register, unregister, find and validate a
8
given struct ops.
7
9
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
9
---
11
---
10
net/mptcp/pm_netlink.c | 60 +++++++++++++++++++++++++++---------------
12
include/net/mptcp.h | 12 ++++++++++
11
1 file changed, 39 insertions(+), 21 deletions(-)
13
net/mptcp/pm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
14
net/mptcp/protocol.h | 5 ++++
15
3 files changed, 72 insertions(+)
12
16
13
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
17
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/net/mptcp/pm_netlink.c
19
--- a/include/net/mptcp.h
16
+++ b/net/mptcp/pm_netlink.c
20
+++ b/include/net/mptcp.h
17
@@ -XXX,XX +XXX,XX @@ static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
21
@@ -XXX,XX +XXX,XX @@
18
        msk->pm.local_addr_used--;
22
23
struct mptcp_info;
24
struct mptcp_sock;
25
+struct mptcp_pm_addr_entry;
26
struct seq_file;
27
28
/* MPTCP sk_buff extension data */
29
@@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops {
30
    void (*release)(struct mptcp_sock *msk);
31
} ____cacheline_aligned_in_smp;
32
33
+#define MPTCP_PM_NAME_MAX    16
34
+
35
+struct mptcp_pm_ops {
36
+    char            name[MPTCP_PM_NAME_MAX];
37
+    struct module        *owner;
38
+    struct list_head    list;
39
+
40
+    void (*init)(struct mptcp_sock *msk);
41
+    void (*release)(struct mptcp_sock *msk);
42
+} ____cacheline_aligned_in_smp;
43
+
44
#ifdef CONFIG_MPTCP
45
void mptcp_init(void);
46
47
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/net/mptcp/pm.c
50
+++ b/net/mptcp/pm.c
51
@@ -XXX,XX +XXX,XX @@
52
*/
53
#define pr_fmt(fmt) "MPTCP: " fmt
54
55
+#include <linux/rculist.h>
56
+#include <linux/spinlock.h>
57
#include "protocol.h"
58
#include "mib.h"
59
60
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_add_entry {
61
    struct mptcp_sock    *sock;
62
};
63
64
+static DEFINE_SPINLOCK(mptcp_pm_list_lock);
65
+static LIST_HEAD(mptcp_pm_list);
66
+
67
/* path manager helpers */
68
69
/* if sk is ipv4 or ipv6_only allows only same-family local and remote addresses,
70
@@ -XXX,XX +XXX,XX @@ void __init mptcp_pm_init(void)
71
    mptcp_pm_kernel_register();
72
    mptcp_pm_nl_init();
19
}
73
}
20
74
+
21
+static int mptcp_pm_nl_address_removed(struct mptcp_sock *msk,
75
+/* Must be called with rcu read lock held */
22
+                 const struct mptcp_pm_addr_entry *local)
76
+struct mptcp_pm_ops *mptcp_pm_find(const char *name)
23
+{
77
+{
24
+    bool remove_subflow;
78
+    struct mptcp_pm_ops *pm;
25
+
79
+
26
+    remove_subflow = mptcp_lookup_subflow_by_saddr(&msk->conn_list, &local->addr);
80
+    list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
27
+    mptcp_pm_remove_anno_addr(msk, &local->addr, remove_subflow &&
81
+        if (!strcmp(pm->name, name))
28
+                 !(local->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
82
+            return pm;
29
+    return 0;
83
+    }
84
+
85
+    return NULL;
30
+}
86
+}
31
+
87
+
32
+static int mptcp_pm_nl_subflow_closed(struct mptcp_sock *msk,
88
+int mptcp_pm_validate(struct mptcp_pm_ops *pm)
33
+                 const struct mptcp_pm_addr_entry *local)
34
+{
89
+{
35
+    struct mptcp_rm_list list = { .nr = 1 };
90
+    if (!pm->init) {
36
+    bool remove_subflow;
91
+        pr_err("%s does not implement required ops\n", pm->name);
37
+
92
+        return -EINVAL;
38
+    list.ids[0] = mptcp_endp_get_local_id(msk, &local->addr);
39
+    remove_subflow = mptcp_lookup_subflow_by_saddr(&msk->conn_list, &local->addr);
40
+    if (remove_subflow) {
41
+        spin_lock_bh(&msk->pm.lock);
42
+        mptcp_pm_nl_rm_subflow_received(msk, &list);
43
+        spin_unlock_bh(&msk->pm.lock);
44
+    }
93
+    }
45
+
46
+    if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
47
+        spin_lock_bh(&msk->pm.lock);
48
+        __mark_subflow_endp_available(msk, list.ids[0]);
49
+        spin_unlock_bh(&msk->pm.lock);
50
+    }
51
+
52
+    if (msk->mpc_endpoint_id == local->addr.id)
53
+        msk->mpc_endpoint_id = 0;
54
+
94
+
55
+    return 0;
95
+    return 0;
56
+}
96
+}
57
+
97
+
58
static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
98
+int mptcp_pm_register(struct mptcp_pm_ops *pm)
59
                         const struct mptcp_pm_addr_entry *entry)
99
+{
60
{
100
+    int ret;
61
    const struct mptcp_addr_info *addr = &entry->addr;
101
+
62
-    struct mptcp_rm_list list = { .nr = 1 };
102
+    ret = mptcp_pm_validate(pm);
63
    long s_slot = 0, s_num = 0;
103
+    if (ret)
64
    struct mptcp_sock *msk;
104
+        return ret;
65
105
+
66
@@ -XXX,XX +XXX,XX @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
106
+    spin_lock(&mptcp_pm_list_lock);
67
107
+    if (mptcp_pm_find(pm->name)) {
68
    while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
108
+        spin_unlock(&mptcp_pm_list_lock);
69
        struct sock *sk = (struct sock *)msk;
109
+        return -EEXIST;
70
-        bool remove_subflow;
110
+    }
71
111
+    list_add_tail_rcu(&pm->list, &mptcp_pm_list);
72
        if (mptcp_pm_is_userspace(msk))
112
+    spin_unlock(&mptcp_pm_list_lock);
73
            goto next;
113
+
74
114
+    pr_debug("%s registered\n", pm->name);
75
        lock_sock(sk);
115
+    return 0;
76
-        remove_subflow = mptcp_lookup_subflow_by_saddr(&msk->conn_list, addr);
116
+}
77
-        mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
117
+
78
-                     !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
118
+void mptcp_pm_unregister(struct mptcp_pm_ops *pm)
79
-
119
+{
80
-        list.ids[0] = mptcp_endp_get_local_id(msk, addr);
120
+    spin_lock(&mptcp_pm_list_lock);
81
-        if (remove_subflow) {
121
+    list_del_rcu(&pm->list);
82
-            spin_lock_bh(&msk->pm.lock);
122
+    spin_unlock(&mptcp_pm_list_lock);
83
-            mptcp_pm_nl_rm_subflow_received(msk, &list);
123
+}
84
-            spin_unlock_bh(&msk->pm.lock);
124
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
85
-        }
125
index XXXXXXX..XXXXXXX 100644
86
-
126
--- a/net/mptcp/protocol.h
87
-        if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
127
+++ b/net/mptcp/protocol.h
88
-            spin_lock_bh(&msk->pm.lock);
128
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
89
-            __mark_subflow_endp_available(msk, list.ids[0]);
129
void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
90
-            spin_unlock_bh(&msk->pm.lock);
130
                struct mptcp_pm_addr_entry *entry);
91
-        }
131
92
-
132
+struct mptcp_pm_ops *mptcp_pm_find(const char *name);
93
-        if (msk->mpc_endpoint_id == entry->addr.id)
133
+int mptcp_pm_validate(struct mptcp_pm_ops *pm);
94
-            msk->mpc_endpoint_id = 0;
134
+int mptcp_pm_register(struct mptcp_pm_ops *pm);
95
+        mptcp_pm_nl_address_removed(msk, entry);
135
+void mptcp_pm_unregister(struct mptcp_pm_ops *pm);
96
+        mptcp_pm_nl_subflow_closed(msk, entry);
136
+
97
        release_sock(sk);
137
void mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock *msk);
98
138
99
next:
139
void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
100
--
140
--
101
2.43.0
141
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Update mptcp_pm_nl_subflow_established() to match the parameters and
3
A new net.mptcp.path_manager sysctl is added to determine which path
4
return value of subflow_established() interface and define it as the
4
manager will be used by each newly-created MPTCP socket by setting the
5
interface of the in-kernel netlink PM.
5
name of it.
6
6
7
This interface is invoked under holding the msk socket lock.
7
This sysctl makes the old one "pm_type" deprecated.
8
8
9
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
9
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
---
10
---
11
net/mptcp/pm_netlink.c | 11 +++++++++--
11
Documentation/networking/mptcp-sysctl.rst | 19 +++++++++
12
1 file changed, 9 insertions(+), 2 deletions(-)
12
net/mptcp/ctrl.c | 50 +++++++++++++++++++++++
13
net/mptcp/protocol.h | 1 +
14
3 files changed, 70 insertions(+)
13
15
14
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
16
diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/net/mptcp/pm_netlink.c
18
--- a/Documentation/networking/mptcp-sysctl.rst
17
+++ b/net/mptcp/pm_netlink.c
19
+++ b/Documentation/networking/mptcp-sysctl.rst
18
@@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
20
@@ -XXX,XX +XXX,XX @@ enabled - BOOLEAN
19
    mptcp_pm_create_subflow_or_signal_addr(msk);
21
22
    Default: 1 (enabled)
23
24
+path_manager - STRING
25
+    Set the default path manager name to use for each new MPTCP
26
+    socket. In-kernel path management will control subflow
27
+    connections and address advertisements according to
28
+    per-namespace values configured over the MPTCP netlink
29
+    API. Userspace path management puts per-MPTCP-connection subflow
30
+    connection decisions and address advertisements under control of
31
+    a privileged userspace program, at the cost of more netlink
32
+    traffic to propagate all of the related events and commands.
33
+
34
+    This is a per-namespace sysctl.
35
+
36
+    * "kernel" - In-kernel path manager
37
+    * "userspace" - Userspace path manager
38
+
39
+    Default: "kernel"
40
+
41
pm_type - INTEGER
42
    Set the default path manager type to use for each new MPTCP
43
    socket. In-kernel path management will control subflow
44
@@ -XXX,XX +XXX,XX @@ pm_type - INTEGER
45
46
    This is a per-namespace sysctl.
47
48
+    Deprecated since v6.15, use path_manager instead.
49
+
50
    * 0 - In-kernel path manager
51
    * 1 - Userspace path manager
52
53
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/net/mptcp/ctrl.c
56
+++ b/net/mptcp/ctrl.c
57
@@ -XXX,XX +XXX,XX @@ struct mptcp_pernet {
58
    u8 allow_join_initial_addr_port;
59
    u8 pm_type;
60
    char scheduler[MPTCP_SCHED_NAME_MAX];
61
+    char path_manager[MPTCP_PM_NAME_MAX];
62
};
63
64
static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
65
@@ -XXX,XX +XXX,XX @@ int mptcp_get_pm_type(const struct net *net)
66
    return mptcp_get_pernet(net)->pm_type;
20
}
67
}
21
68
22
-static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
69
+const char *mptcp_get_path_manager(const struct net *net)
23
+static int mptcp_pm_nl_subflow_established(struct mptcp_sock *msk,
70
+{
24
+                     struct mptcp_pm_param *param)
71
+    return mptcp_get_pernet(net)->path_manager;
72
+}
73
+
74
const char *mptcp_get_scheduler(const struct net *net)
25
{
75
{
26
    mptcp_pm_create_subflow_or_signal_addr(msk);
76
    return mptcp_get_pernet(net)->scheduler;
77
@@ -XXX,XX +XXX,XX @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
78
    pernet->stale_loss_cnt = 4;
79
    pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
80
    strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler));
81
+    strscpy(pernet->path_manager, "kernel", sizeof(pernet->path_manager));
82
}
83
84
#ifdef CONFIG_SYSCTL
85
@@ -XXX,XX +XXX,XX @@ static int proc_blackhole_detect_timeout(const struct ctl_table *table,
86
    return ret;
87
}
88
89
+static int mptcp_set_path_manager(char *path_manager, const char *name)
90
+{
91
+    struct mptcp_pm_ops *pm;
92
+    int ret = 0;
27
+
93
+
28
+    return 0;
94
+    rcu_read_lock();
29
}
95
+    pm = mptcp_pm_find(name);
30
96
+    if (pm)
31
/* Fill all the local addresses into the array addrs[],
97
+        strscpy(path_manager, name, MPTCP_PM_NAME_MAX);
32
@@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
98
+    else
33
void mptcp_pm_nl_work(struct mptcp_sock *msk)
99
+        ret = -ENOENT;
34
{
100
+    rcu_read_unlock();
35
    struct mptcp_pm_data *pm = &msk->pm;
101
+
36
+    struct mptcp_pm_param param;
102
+    return ret;
37
103
+}
38
    msk_owned_by_me(msk);
104
+
39
105
+static int proc_path_manager(const struct ctl_table *ctl, int write,
40
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_nl_work(struct mptcp_sock *msk)
106
+             void *buffer, size_t *lenp, loff_t *ppos)
41
    }
107
+{
42
    if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
108
+    char (*path_manager)[MPTCP_PM_NAME_MAX] = ctl->data;
43
        pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
109
+    char val[MPTCP_PM_NAME_MAX];
44
-        mptcp_pm_nl_subflow_established(msk);
110
+    const struct ctl_table tbl = {
45
+        msk->pm.ops && msk->pm.ops->subflow_established ?
111
+        .data = val,
46
+            msk->pm.ops->subflow_established(msk, &param) :
112
+        .maxlen = MPTCP_PM_NAME_MAX,
47
+            mptcp_pm_nl_subflow_established(msk, &param);
113
+    };
48
    }
114
+    int ret;
49
115
+
50
    spin_unlock_bh(&msk->pm.lock);
116
+    strscpy(val, *path_manager, MPTCP_PM_NAME_MAX);
51
@@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = {
117
+
52
static struct mptcp_pm_ops mptcp_netlink_pm = {
118
+    ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
53
    .address_announced    = mptcp_pm_nl_address_announced,
119
+    if (write && ret == 0)
54
    .address_removed    = mptcp_pm_nl_address_removed,
120
+        ret = mptcp_set_path_manager(*path_manager, val);
55
+    .subflow_established    = mptcp_pm_nl_subflow_established,
121
+
56
    .get_local_id        = mptcp_pm_nl_get_local_id,
122
+    return ret;
57
    .get_priority        = mptcp_pm_nl_get_priority,
123
+}
58
    .type            = MPTCP_PM_TYPE_KERNEL,
124
+
125
static struct ctl_table mptcp_sysctl_table[] = {
126
    {
127
        .procname = "enabled",
128
@@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = {
129
        .mode = 0644,
130
        .proc_handler = proc_dou8vec_minmax,
131
    },
132
+    {
133
+        .procname = "path_manager",
134
+        .maxlen    = MPTCP_PM_NAME_MAX,
135
+        .mode = 0644,
136
+        .proc_handler = proc_path_manager,
137
+    },
138
};
139
140
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
141
@@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
142
    table[8].data = &pernet->close_timeout;
143
    table[9].data = &pernet->blackhole_timeout;
144
    table[10].data = &pernet->syn_retrans_before_tcp_fallback;
145
+    table[11].data = &pernet->path_manager;
146
147
    hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
148
                 ARRAY_SIZE(mptcp_sysctl_table));
149
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
150
index XXXXXXX..XXXXXXX 100644
151
--- a/net/mptcp/protocol.h
152
+++ b/net/mptcp/protocol.h
153
@@ -XXX,XX +XXX,XX @@ int mptcp_allow_join_id0(const struct net *net);
154
unsigned int mptcp_stale_loss_cnt(const struct net *net);
155
unsigned int mptcp_close_timeout(const struct sock *sk);
156
int mptcp_get_pm_type(const struct net *net);
157
+const char *mptcp_get_path_manager(const struct net *net);
158
const char *mptcp_get_scheduler(const struct net *net);
159
160
void mptcp_active_disable(struct sock *sk);
59
--
161
--
60
2.43.0
162
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Update the 2nd parameter of mptcp_pm_nl_subflow_closed(), and define it
3
This patch adds a new proc_handler "proc_pm_type" for "pm_type" to
4
as the subflow_closed() interface of the in-kernel netlink PM.
4
map old path manager sysctl "pm_type" to the newly added "path_manager".
5
6
This interface is invoked under holding the msk socket lock.
7
5
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
9
---
7
---
10
net/mptcp/pm_netlink.c | 8 ++++++--
8
net/mptcp/ctrl.c | 28 +++++++++++++++++++++++++++-
11
1 file changed, 6 insertions(+), 2 deletions(-)
9
1 file changed, 27 insertions(+), 1 deletion(-)
12
10
13
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
11
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/net/mptcp/pm_netlink.c
13
--- a/net/mptcp/ctrl.c
16
+++ b/net/mptcp/pm_netlink.c
14
+++ b/net/mptcp/ctrl.c
17
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_address_removed(struct mptcp_sock *msk,
15
@@ -XXX,XX +XXX,XX @@ static int proc_path_manager(const struct ctl_table *ctl, int write,
16
    return ret;
18
}
17
}
19
18
20
static int mptcp_pm_nl_subflow_closed(struct mptcp_sock *msk,
19
+static int proc_pm_type(const struct ctl_table *ctl, int write,
21
-                 const struct mptcp_pm_addr_entry *local)
20
+            void *buffer, size_t *lenp, loff_t *ppos)
22
+                 struct mptcp_pm_param *param)
21
+{
23
{
22
+    struct mptcp_pernet *pernet = container_of(ctl->data,
24
+    struct mptcp_pm_addr_entry *local = &param->entry;
23
+                         struct mptcp_pernet,
25
    struct mptcp_rm_list list = { .nr = 1 };
24
+                         pm_type);
26
    bool remove_subflow;
25
+    u8 pm_type = READ_ONCE(*(u8 *)ctl->data);
27
26
+    const struct ctl_table tbl = {
28
@@ -XXX,XX +XXX,XX @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
27
+        .maxlen = sizeof(pm_type),
29
        msk->pm.ops && msk->pm.ops->address_removed ?
28
+        .data = &pm_type,
30
            msk->pm.ops->address_removed(msk, &param) :
29
+    };
31
            mptcp_pm_nl_address_removed(msk, &param);
30
+    int ret;
32
-        mptcp_pm_nl_subflow_closed(msk, entry);
31
+
33
+        msk->pm.ops && msk->pm.ops->subflow_closed ?
32
+    ret = proc_dou8vec_minmax(&tbl, write, buffer, lenp, ppos);
34
+            msk->pm.ops->subflow_closed(msk, &param) :
33
+    if (write && ret == 0) {
35
+            mptcp_pm_nl_subflow_closed(msk, &param);
34
+        char *path_manager = "kernel";
36
        release_sock(sk);
35
+
37
36
+        if (pm_type == MPTCP_PM_TYPE_USERSPACE)
38
next:
37
+            path_manager = "userspace";
39
@@ -XXX,XX +XXX,XX @@ static struct mptcp_pm_ops mptcp_netlink_pm = {
38
+        mptcp_set_path_manager(pernet->path_manager, path_manager);
40
    .address_announced    = mptcp_pm_nl_address_announced,
39
+        WRITE_ONCE(*(u8 *)ctl->data, pm_type);
41
    .address_removed    = mptcp_pm_nl_address_removed,
40
+    }
42
    .subflow_established    = mptcp_pm_nl_subflow_established,
41
+
43
+    .subflow_closed        = mptcp_pm_nl_subflow_closed,
42
+    return ret;
44
    .get_local_id        = mptcp_pm_nl_get_local_id,
43
+}
45
    .get_priority        = mptcp_pm_nl_get_priority,
44
+
46
    .type            = MPTCP_PM_TYPE_KERNEL,
45
static struct ctl_table mptcp_sysctl_table[] = {
46
    {
47
        .procname = "enabled",
48
@@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = {
49
        .procname = "pm_type",
50
        .maxlen = sizeof(u8),
51
        .mode = 0644,
52
-        .proc_handler = proc_dou8vec_minmax,
53
+        .proc_handler = proc_pm_type,
54
        .extra1 = SYSCTL_ZERO,
55
        .extra2 = &mptcp_pm_type_max
56
    },
47
--
57
--
48
2.43.0
58
2.43.0
diff view generated by jsdifflib
New patch
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
2
3
This patch maps the newly added path manager sysctl "path_manager"
4
to the old one "pm_type".
5
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
7
---
8
net/mptcp/ctrl.c | 11 ++++++++++-
9
1 file changed, 10 insertions(+), 1 deletion(-)
10
11
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/mptcp/ctrl.c
14
+++ b/net/mptcp/ctrl.c
15
@@ -XXX,XX +XXX,XX @@ static int mptcp_set_path_manager(char *path_manager, const char *name)
16
static int proc_path_manager(const struct ctl_table *ctl, int write,
17
             void *buffer, size_t *lenp, loff_t *ppos)
18
{
19
+    struct mptcp_pernet *pernet = container_of(ctl->data,
20
+                         struct mptcp_pernet,
21
+                         path_manager);
22
    char (*path_manager)[MPTCP_PM_NAME_MAX] = ctl->data;
23
    char val[MPTCP_PM_NAME_MAX];
24
    const struct ctl_table tbl = {
25
@@ -XXX,XX +XXX,XX @@ static int proc_path_manager(const struct ctl_table *ctl, int write,
26
    strscpy(val, *path_manager, MPTCP_PM_NAME_MAX);
27
28
    ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
29
-    if (write && ret == 0)
30
+    if (write && ret == 0) {
31
+        u8 pm_type = MPTCP_PM_TYPE_KERNEL;
32
+
33
+        if (!strncmp(val, "userspace", MPTCP_PM_NAME_MAX))
34
+            pm_type = MPTCP_PM_TYPE_USERSPACE;
35
+        pernet->pm_type = pm_type;
36
        ret = mptcp_set_path_manager(*path_manager, val);
37
+    }
38
39
    return ret;
40
}
41
--
42
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Extract address_announced() interface of the in-kernel netlink PM from
3
Similarly to net.mptcp.available_schedulers, this patch adds a new one
4
the helper mptcp_nl_add_subflow_or_signal_addr(), only leave the code
4
net.mptcp.available_path_managers to list the available path managers.
5
for traversing all msk in the helper.
6
7
This interface is invoked under holding the msk socket lock.
8
5
9
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
---
7
---
11
net/mptcp/pm_netlink.c | 34 +++++++++++++++++++++++++---------
8
Documentation/networking/mptcp-sysctl.rst | 4 ++++
12
1 file changed, 25 insertions(+), 9 deletions(-)
9
include/net/mptcp.h | 2 ++
10
net/mptcp/ctrl.c | 25 +++++++++++++++++++++++
11
net/mptcp/pm.c | 19 +++++++++++++++++
12
net/mptcp/protocol.h | 1 +
13
5 files changed, 51 insertions(+)
13
14
14
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
15
diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/net/mptcp/pm_netlink.c
17
--- a/Documentation/networking/mptcp-sysctl.rst
17
+++ b/net/mptcp/pm_netlink.c
18
+++ b/Documentation/networking/mptcp-sysctl.rst
18
@@ -XXX,XX +XXX,XX @@ static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
19
@@ -XXX,XX +XXX,XX @@ allow_join_initial_addr_port - BOOLEAN
19
    return pm_nl_get_pernet(genl_info_net(info));
20
21
    Default: 1
22
23
+available_path_managers - STRING
24
+    Shows the available path managers choices that are registered. More
25
+    path managers may be available, but not loaded.
26
+
27
available_schedulers - STRING
28
    Shows the available schedulers choices that are registered. More packet
29
    schedulers may be available, but not loaded.
30
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/net/mptcp.h
33
+++ b/include/net/mptcp.h
34
@@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops {
35
} ____cacheline_aligned_in_smp;
36
37
#define MPTCP_PM_NAME_MAX    16
38
+#define MPTCP_PM_MAX        128
39
+#define MPTCP_PM_BUF_MAX    (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX)
40
41
struct mptcp_pm_ops {
42
    char            name[MPTCP_PM_NAME_MAX];
43
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/net/mptcp/ctrl.c
46
+++ b/net/mptcp/ctrl.c
47
@@ -XXX,XX +XXX,XX @@ static int proc_pm_type(const struct ctl_table *ctl, int write,
48
    return ret;
20
}
49
}
21
50
22
+static int mptcp_pm_nl_address_announced(struct mptcp_sock *msk,
51
+static int proc_available_path_managers(const struct ctl_table *ctl,
23
+                     struct mptcp_pm_param *param)
52
+                    int write, void *buffer,
53
+                    size_t *lenp, loff_t *ppos)
24
+{
54
+{
25
+    struct mptcp_addr_info *addr = &param->addr;
55
+    struct ctl_table tbl = { .maxlen = MPTCP_PM_BUF_MAX, };
26
+    struct mptcp_addr_info mpc_addr;
56
+    int ret;
27
+
57
+
28
+    /* if the endp linked to the init sf is re-added with a != ID */
58
+    tbl.data = kmalloc(tbl.maxlen, GFP_USER);
29
+    mptcp_local_address((struct sock_common *)msk, &mpc_addr);
59
+    if (!tbl.data)
60
+        return -ENOMEM;
30
+
61
+
31
+    spin_lock_bh(&msk->pm.lock);
62
+    mptcp_pm_get_available(tbl.data, MPTCP_PM_BUF_MAX);
32
+    if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
63
+    ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
33
+        msk->mpc_endpoint_id = addr->id;
64
+    kfree(tbl.data);
34
+
65
+
35
+    mptcp_pm_create_subflow_or_signal_addr(msk);
66
+    return ret;
36
+    spin_unlock_bh(&msk->pm.lock);
37
+
38
+    return 0;
39
+}
67
+}
40
+
68
+
41
static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
69
static struct ctl_table mptcp_sysctl_table[] = {
42
                     struct mptcp_addr_info *addr)
70
    {
43
{
71
        .procname = "enabled",
44
@@ -XXX,XX +XXX,XX @@ static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
72
@@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = {
45
73
        .mode = 0644,
46
    while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
74
        .proc_handler = proc_path_manager,
47
        struct sock *sk = (struct sock *)msk;
75
    },
48
-        struct mptcp_addr_info mpc_addr;
76
+    {
49
+        struct mptcp_pm_param param;
77
+        .procname = "available_path_managers",
50
78
+        .maxlen    = MPTCP_PM_BUF_MAX,
51
        if (!READ_ONCE(msk->fully_established) ||
79
+        .mode = 0444,
52
         mptcp_pm_is_userspace(msk))
80
+        .proc_handler = proc_available_path_managers,
53
            goto next;
81
+    },
54
55
-        /* if the endp linked to the init sf is re-added with a != ID */
56
-        mptcp_local_address((struct sock_common *)msk, &mpc_addr);
57
-
58
        lock_sock(sk);
59
-        spin_lock_bh(&msk->pm.lock);
60
-        if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
61
-            msk->mpc_endpoint_id = addr->id;
62
-        mptcp_pm_create_subflow_or_signal_addr(msk);
63
-        spin_unlock_bh(&msk->pm.lock);
64
+        mptcp_pm_param_set_contexts(&param, NULL, addr);
65
+        msk->pm.ops && msk->pm.ops->address_announced ?
66
+            msk->pm.ops->address_announced(msk, &param) :
67
+            mptcp_pm_nl_address_announced(msk, &param);
68
        release_sock(sk);
69
70
next:
71
@@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = {
72
};
82
};
73
83
74
static struct mptcp_pm_ops mptcp_netlink_pm = {
84
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
75
+    .address_announced    = mptcp_pm_nl_address_announced,
85
@@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
76
    .get_local_id        = mptcp_pm_nl_get_local_id,
86
    table[9].data = &pernet->blackhole_timeout;
77
    .get_priority        = mptcp_pm_nl_get_priority,
87
    table[10].data = &pernet->syn_retrans_before_tcp_fallback;
78
    .type            = MPTCP_PM_TYPE_KERNEL,
88
    table[11].data = &pernet->path_manager;
89
+    /* table[12] is for available_path_managers which is read-only info */
90
91
    hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
92
                 ARRAY_SIZE(mptcp_sysctl_table));
93
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/net/mptcp/pm.c
96
+++ b/net/mptcp/pm.c
97
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_unregister(struct mptcp_pm_ops *pm)
98
    list_del_rcu(&pm->list);
99
    spin_unlock(&mptcp_pm_list_lock);
100
}
101
+
102
+/* Build string with list of available path manager values.
103
+ * Similar to tcp_get_available_congestion_control()
104
+ */
105
+void mptcp_pm_get_available(char *buf, size_t maxlen)
106
+{
107
+    struct mptcp_pm_ops *pm;
108
+    size_t offs = 0;
109
+
110
+    rcu_read_lock();
111
+    list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
112
+        offs += snprintf(buf + offs, maxlen - offs, "%s%s",
113
+                 offs == 0 ? "" : " ", pm->name);
114
+
115
+        if (WARN_ON_ONCE(offs >= maxlen))
116
+            break;
117
+    }
118
+    rcu_read_unlock();
119
+}
120
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/net/mptcp/protocol.h
123
+++ b/net/mptcp/protocol.h
124
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name);
125
int mptcp_pm_validate(struct mptcp_pm_ops *pm);
126
int mptcp_pm_register(struct mptcp_pm_ops *pm);
127
void mptcp_pm_unregister(struct mptcp_pm_ops *pm);
128
+void mptcp_pm_get_available(char *buf, size_t maxlen);
129
130
void mptcp_userspace_pm_free_local_addr_list(struct mptcp_sock *msk);
131
79
--
132
--
80
2.43.0
133
2.43.0
diff view generated by jsdifflib
New patch
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
2
3
This patch defines the original in-kernel netlink path manager as a
4
new struct mptcp_pm_ops named "mptcp_pm_kernel", and register it in
5
mptcp_pm_kernel_register().
6
7
This mptcp_pm_ops will be skipped in mptcp_pm_unregister().
8
9
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
---
11
net/mptcp/pm.c | 4 ++++
12
net/mptcp/pm_kernel.c | 26 ++++++++++++++++++++++++++
13
net/mptcp/protocol.h | 3 +++
14
3 files changed, 33 insertions(+)
15
16
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/net/mptcp/pm.c
19
+++ b/net/mptcp/pm.c
20
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_register(struct mptcp_pm_ops *pm)
21
22
void mptcp_pm_unregister(struct mptcp_pm_ops *pm)
23
{
24
+    /* skip unregistering the default path manager */
25
+    if (pm == &mptcp_pm_kernel)
26
+        return;
27
+
28
    spin_lock(&mptcp_pm_list_lock);
29
    list_del_rcu(&pm->list);
30
    spin_unlock(&mptcp_pm_list_lock);
31
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/net/mptcp/pm_kernel.c
34
+++ b/net/mptcp/pm_kernel.c
35
@@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = {
36
    .size = sizeof(struct pm_nl_pernet),
37
};
38
39
+static void mptcp_pm_nl_initialize(struct mptcp_sock *msk)
40
+{
41
+    bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk);
42
+    struct mptcp_pm_data *pm = &msk->pm;
43
+
44
+    /* pm->work_pending must be only be set to 'true' when
45
+     * pm is the default path manager
46
+     */
47
+    WRITE_ONCE(pm->work_pending,
48
+         (!!mptcp_pm_get_local_addr_max(msk) &&
49
+         subflows_allowed) ||
50
+         !!mptcp_pm_get_add_addr_signal_max(msk));
51
+    WRITE_ONCE(pm->accept_addr,
52
+         !!mptcp_pm_get_add_addr_accept_max(msk) &&
53
+         subflows_allowed);
54
+    WRITE_ONCE(pm->accept_subflow, subflows_allowed);
55
+}
56
+
57
+struct mptcp_pm_ops mptcp_pm_kernel = {
58
+    .init            = mptcp_pm_nl_initialize,
59
+    .name            = "kernel",
60
+    .owner            = THIS_MODULE,
61
+};
62
+
63
void __init mptcp_pm_kernel_register(void)
64
{
65
    if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
66
        panic("Failed to register MPTCP PM pernet subsystem.\n");
67
+
68
+    mptcp_pm_register(&mptcp_pm_kernel);
69
}
70
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/net/mptcp/protocol.h
73
+++ b/net/mptcp/protocol.h
74
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
75
void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
76
                struct mptcp_pm_addr_entry *entry);
77
78
+/* the default path manager, used in mptcp_pm_unregister */
79
+extern struct mptcp_pm_ops mptcp_pm_kernel;
80
+
81
struct mptcp_pm_ops *mptcp_pm_find(const char *name);
82
int mptcp_pm_validate(struct mptcp_pm_ops *pm);
83
int mptcp_pm_register(struct mptcp_pm_ops *pm);
84
--
85
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Extract address_announced() interface of the userspace PM from the handler
3
This patch defines the original userspace path manager as a new
4
of netlink command MPTCP_PM_CMD_ANNOUNCE mptcp_pm_nl_announce_doit(), only
4
struct mptcp_pm_ops named "mptcp_userspace_pm", and register it
5
leave the code for obtaining msk through "info" and parsing address entry
5
in mptcp_pm_init(). mptcp_userspace_pm_is_release() is a wrapper
6
in the handler.
6
of mptcp_userspace_pm_free_local_addr_list().
7
8
This interface is invoked under holding the msk socket lock.
9
7
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
11
---
9
---
12
net/mptcp/pm_userspace.c | 49 ++++++++++++++++++++++++++--------------
10
net/mptcp/pm.c | 1 +
13
1 file changed, 32 insertions(+), 17 deletions(-)
11
net/mptcp/pm_userspace.c | 26 ++++++++++++++++++++++++++
12
net/mptcp/protocol.h | 1 +
13
3 files changed, 28 insertions(+)
14
14
15
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/mptcp/pm.c
18
+++ b/net/mptcp/pm.c
19
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
20
void __init mptcp_pm_init(void)
21
{
22
    mptcp_pm_kernel_register();
23
+    mptcp_pm_userspace_register();
24
    mptcp_pm_nl_init();
25
}
26
15
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
27
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/net/mptcp/pm_userspace.c
29
--- a/net/mptcp/pm_userspace.c
18
+++ b/net/mptcp/pm_userspace.c
30
+++ b/net/mptcp/pm_userspace.c
19
@@ -XXX,XX +XXX,XX @@ static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *in
31
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
20
    return msk;
32
    sock_put(sk);
33
    return ret;
21
}
34
}
22
35
+
23
+static int mptcp_userspace_pm_address_announced(struct mptcp_sock *msk,
36
+static void mptcp_userspace_pm_init(struct mptcp_sock *msk)
24
+                        struct mptcp_pm_param *param)
25
+{
37
+{
26
+    struct mptcp_pm_addr_entry *local = &param->entry;
38
+    struct mptcp_pm_data *pm = &msk->pm;
27
+    int err;
28
+
39
+
29
+    err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
40
+    WRITE_ONCE(pm->work_pending, 0);
30
+    if (err < 0)
41
+    WRITE_ONCE(pm->accept_addr, 0);
31
+        return err;
42
+    WRITE_ONCE(pm->accept_subflow, 0);
32
+
33
+    spin_lock_bh(&msk->pm.lock);
34
+
35
+    if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
36
+        msk->pm.add_addr_signaled++;
37
+        mptcp_pm_announce_addr(msk, &local->addr, false);
38
+        mptcp_pm_nl_addr_send_ack(msk);
39
+    }
40
+
41
+    spin_unlock_bh(&msk->pm.lock);
42
+
43
+    return 0;
44
+}
43
+}
45
+
44
+
46
int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
45
+static void mptcp_userspace_pm_release(struct mptcp_sock *msk)
47
{
46
+{
48
    struct mptcp_pm_addr_entry addr_val;
47
+    mptcp_userspace_pm_free_local_addr_list(msk);
49
+    struct mptcp_pm_param param;
48
+}
50
    struct mptcp_sock *msk;
49
+
51
    struct nlattr *addr;
50
+static struct mptcp_pm_ops mptcp_pm_userspace = {
52
    int err = -EINVAL;
51
+    .init            = mptcp_userspace_pm_init,
53
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
52
+    .release        = mptcp_userspace_pm_release,
54
        goto announce_err;
53
+    .name            = "userspace",
55
    }
54
+    .owner            = THIS_MODULE,
56
55
+};
57
-    err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
56
+
58
-    if (err < 0) {
57
+void __init mptcp_pm_userspace_register(void)
59
-        NL_SET_ERR_MSG_ATTR(info->extack, addr,
58
+{
60
-                 "did not match address and id");
59
+    mptcp_pm_register(&mptcp_pm_userspace);
61
-        goto announce_err;
60
+}
62
-    }
61
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
63
-
62
index XXXXXXX..XXXXXXX 100644
64
    lock_sock(sk);
63
--- a/net/mptcp/protocol.h
65
-    spin_lock_bh(&msk->pm.lock);
64
+++ b/net/mptcp/protocol.h
66
-
65
@@ -XXX,XX +XXX,XX @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
67
-    if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) {
68
-        msk->pm.add_addr_signaled++;
69
-        mptcp_pm_announce_addr(msk, &addr_val.addr, false);
70
-        mptcp_pm_nl_addr_send_ack(msk);
71
-    }
72
-
73
-    spin_unlock_bh(&msk->pm.lock);
74
+    mptcp_pm_param_set_contexts(&param, &addr_val, NULL);
75
+    err = msk->pm.ops && msk->pm.ops->address_announced ?
76
+     msk->pm.ops->address_announced(msk, &param) :
77
+     mptcp_userspace_pm_address_announced(msk, &param);
78
    release_sock(sk);
79
+    if (err)
80
+        NL_SET_ERR_MSG_ATTR(info->extack, addr,
81
+                 "did not match address and id");
82
83
-    err = 0;
84
announce_err:
85
    sock_put(sk);
86
    return err;
87
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
88
}
66
}
89
67
90
static struct mptcp_pm_ops mptcp_userspace_pm = {
68
void __init mptcp_pm_kernel_register(void);
91
+    .address_announced    = mptcp_userspace_pm_address_announced,
69
+void __init mptcp_pm_userspace_register(void);
92
    .get_local_id        = mptcp_userspace_pm_get_local_id,
70
void __init mptcp_pm_nl_init(void);
93
    .get_priority        = mptcp_userspace_pm_get_priority,
71
void mptcp_pm_worker(struct mptcp_sock *msk);
94
    .type            = MPTCP_PM_TYPE_USERSPACE,
72
void __mptcp_pm_kernel_worker(struct mptcp_sock *msk);
95
--
73
--
96
2.43.0
74
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Extract address_removed() interface of the userspace PM from the handler
3
Add a struct mptcp_pm_ops pointer "ops" in struct mptcp_pm_data, and two
4
of netlink command MPTCP_PM_CMD_REMOVE mptcp_pm_nl_remove_doit(), only
4
functions mptcp_pm_initialize() and mptcp_pm_release(), to set and release
5
leave the code for parsing address id and obtaining msk through "info"
5
this pointer. mptcp_pm_initialize() is invoked in mptcp_pm_data_reset(),
6
in the handler.
6
while mptcp_pm_release() is invoked in mptcp_pm_destroy().
7
8
This interface is invoked under holding the msk socket lock.
9
7
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
11
---
9
---
12
net/mptcp/pm_userspace.c | 74 ++++++++++++++++++++--------------------
10
net/mptcp/pm.c | 57 +++++++++++++++++++++++++++-----------------
13
1 file changed, 37 insertions(+), 37 deletions(-)
11
net/mptcp/protocol.h | 1 +
12
2 files changed, 36 insertions(+), 22 deletions(-)
14
13
15
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
14
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/net/mptcp/pm_userspace.c
16
--- a/net/mptcp/pm.c
18
+++ b/net/mptcp/pm_userspace.c
17
+++ b/net/mptcp/pm.c
19
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
18
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk)
20
{
21
    struct mptcp_rm_list list = { .nr = 0 };
22
    struct mptcp_subflow_context *subflow;
23
-    struct sock *sk = (struct sock *)msk;
24
    bool has_id_0 = false;
25
-    int err = -EINVAL;
26
27
-    lock_sock(sk);
28
    mptcp_for_each_subflow(msk, subflow) {
29
        if (READ_ONCE(subflow->local_id) == 0) {
30
            has_id_0 = true;
31
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
32
        }
33
    }
34
    if (!has_id_0)
35
-        goto remove_err;
36
+        return -EINVAL;
37
38
    list.ids[list.nr++] = 0;
39
40
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
41
    mptcp_pm_remove_addr(msk, &list);
42
    spin_unlock_bh(&msk->pm.lock);
43
44
-    err = 0;
45
-
46
-remove_err:
47
-    release_sock(sk);
48
-    return err;
49
+    return 0;
50
}
51
52
void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
53
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
54
    spin_unlock_bh(&msk->pm.lock);
19
    spin_unlock_bh(&msk->pm.lock);
55
}
20
}
56
21
57
+static int mptcp_userspace_pm_address_removed(struct mptcp_sock *msk,
22
+static void mptcp_pm_initialize(struct mptcp_sock *msk,
58
+                     struct mptcp_pm_param *param)
23
+                struct mptcp_pm_ops *pm)
59
+{
24
+{
60
+    struct mptcp_pm_addr_entry *entry;
25
+    if (!pm || !bpf_try_module_get(pm, pm->owner)) {
61
+    u8 id = param->addr.id;
26
+        pr_warn_once("pm %s fails, fallback to default pm",
62
+
27
+             pm->name);
63
+    if (id == 0)
28
+        pm = &mptcp_pm_kernel;
64
+        return mptcp_userspace_pm_remove_id_zero_address(msk);
65
+
66
+    spin_lock_bh(&msk->pm.lock);
67
+    entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
68
+    if (!entry) {
69
+        spin_unlock_bh(&msk->pm.lock);
70
+        return -EINVAL;
71
+    }
29
+    }
72
+
30
+
73
+    list_del_rcu(&entry->list);
31
+    msk->pm.ops = pm;
74
+    spin_unlock_bh(&msk->pm.lock);
32
+    if (msk->pm.ops->init)
33
+        msk->pm.ops->init(msk);
75
+
34
+
76
+    mptcp_pm_remove_addr_entry(msk, entry);
35
+    pr_debug("pm %s initialized\n", pm->name);
77
+
78
+    sock_kfree_s((struct sock *)msk, entry, sizeof(*entry));
79
+
80
+    return 0;
81
+}
36
+}
82
+
37
+
83
int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
38
+static void mptcp_pm_release(struct mptcp_sock *msk)
39
+{
40
+    struct mptcp_pm_ops *pm = msk->pm.ops;
41
+
42
+    if (!pm)
43
+        return;
44
+
45
+    msk->pm.ops = NULL;
46
+    if (pm->release)
47
+        pm->release(msk);
48
+
49
+    bpf_module_put(pm, pm->owner);
50
+}
51
+
52
void mptcp_pm_destroy(struct mptcp_sock *msk)
84
{
53
{
85
-    struct mptcp_pm_addr_entry *match;
54
    mptcp_pm_free_anno_list(msk);
86
+    struct mptcp_addr_info addr;
55
-
87
+    struct mptcp_pm_param param;
56
-    if (mptcp_pm_is_userspace(msk))
88
    struct mptcp_sock *msk;
57
-        mptcp_userspace_pm_free_local_addr_list(msk);
89
    struct nlattr *id;
58
+    mptcp_pm_release(msk);
90
    int err = -EINVAL;
59
}
91
    struct sock *sk;
60
92
-    u8 id_val;
61
void mptcp_pm_data_reset(struct mptcp_sock *msk)
93
62
{
94
    if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_LOC_ID))
63
+    const char *path_manager = mptcp_get_path_manager(sock_net((struct sock *)msk));
95
        return err;
64
    u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk));
96
65
    struct mptcp_pm_data *pm = &msk->pm;
97
    id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
66
98
-    id_val = nla_get_u8(id);
67
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
99
+    addr.id = nla_get_u8(id);
68
    pm->rm_list_rx.nr = 0;
100
69
    WRITE_ONCE(pm->pm_type, pm_type);
101
    msk = mptcp_userspace_pm_get_sock(info);
70
102
    if (!msk)
71
-    if (pm_type == MPTCP_PM_TYPE_KERNEL) {
103
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
72
-        bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk);
104
73
-
105
    sk = (struct sock *)msk;
74
-        /* pm->work_pending must be only be set to 'true' when
106
75
-         * pm->pm_type is set to MPTCP_PM_TYPE_KERNEL
107
-    if (id_val == 0) {
76
-         */
108
-        err = mptcp_userspace_pm_remove_id_zero_address(msk);
77
-        WRITE_ONCE(pm->work_pending,
109
-        goto out;
78
-             (!!mptcp_pm_get_local_addr_max(msk) &&
79
-             subflows_allowed) ||
80
-             !!mptcp_pm_get_add_addr_signal_max(msk));
81
-        WRITE_ONCE(pm->accept_addr,
82
-             !!mptcp_pm_get_add_addr_accept_max(msk) &&
83
-             subflows_allowed);
84
-        WRITE_ONCE(pm->accept_subflow, subflows_allowed);
85
-    } else {
86
-        WRITE_ONCE(pm->work_pending, 0);
87
-        WRITE_ONCE(pm->accept_addr, 0);
88
-        WRITE_ONCE(pm->accept_subflow, 0);
110
-    }
89
-    }
111
-
90
+    rcu_read_lock();
112
    lock_sock(sk);
91
+    mptcp_pm_initialize(msk, mptcp_pm_find(path_manager));
113
-
92
+    rcu_read_unlock();
114
-    spin_lock_bh(&msk->pm.lock);
93
115
-    match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
94
    WRITE_ONCE(pm->addr_signal, 0);
116
-    if (!match) {
95
    WRITE_ONCE(pm->remote_deny_join_id0, false);
117
-        spin_unlock_bh(&msk->pm.lock);
96
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
118
-        release_sock(sk);
97
index XXXXXXX..XXXXXXX 100644
119
-        goto out;
98
--- a/net/mptcp/protocol.h
120
-    }
99
+++ b/net/mptcp/protocol.h
121
-
100
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_data {
122
-    list_del_rcu(&match->list);
101
    struct mptcp_addr_info remote;
123
-    spin_unlock_bh(&msk->pm.lock);
102
    struct list_head anno_list;
124
-
103
    struct list_head userspace_pm_local_addr_list;
125
-    mptcp_pm_remove_addr_entry(msk, match);
104
+    struct mptcp_pm_ops *ops;
126
-
105
127
+    mptcp_pm_param_set_contexts(&param, NULL, &addr);
106
    spinlock_t    lock;        /*protects the whole PM data */
128
+    err = msk->pm.ops && msk->pm.ops->address_removed ?
107
129
+     msk->pm.ops->address_removed(msk, &param) :
130
+     mptcp_userspace_pm_address_removed(msk, &param);
131
    release_sock(sk);
132
-
133
-    sock_kfree_s(sk, match, sizeof(*match));
134
-
135
-    err = 0;
136
-out:
137
    if (err)
138
        NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
139
                    "address with id %u not found",
140
-                    id_val);
141
+                    addr.id);
142
143
    sock_put(sk);
144
    return err;
145
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
146
147
static struct mptcp_pm_ops mptcp_userspace_pm = {
148
    .address_announced    = mptcp_userspace_pm_address_announced,
149
+    .address_removed    = mptcp_userspace_pm_address_removed,
150
    .get_local_id        = mptcp_userspace_pm_get_local_id,
151
    .get_priority        = mptcp_userspace_pm_get_priority,
152
    .type            = MPTCP_PM_TYPE_USERSPACE,
153
--
108
--
154
2.43.0
109
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Extract subflow_closed() interface of the userspace PM from the handler of
3
Now mptcp_pm_get_local_id() can directly invoke get_local_id() interface
4
netlink command MPTCP_PM_CMD_SUBFLOW_DESTROY
4
through "ops" of "msk->pm". Instead of using mptcp_pm_is_userspace() to
5
check which get_local_id() helper to invoke.
5
6
6
    mptcp_pm_nl_subflow_destroy_doit(),
7
Then mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id()
7
8
helpers can be static.
8
only leave the code for obtaining msk through "info", parsing local address
9
entry and parsing remote address info in the handler.
10
11
This interface is invoked under holding the msk socket lock.
12
9
13
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
14
---
11
---
15
net/mptcp/pm_userspace.c | 45 ++++++++++++++++++++++++++--------------
12
include/net/mptcp.h | 3 +++
16
1 file changed, 30 insertions(+), 15 deletions(-)
13
net/mptcp/pm.c | 6 ++----
14
net/mptcp/pm_kernel.c | 5 +++--
15
net/mptcp/pm_userspace.c | 5 +++--
16
net/mptcp/protocol.h | 4 ----
17
5 files changed, 11 insertions(+), 12 deletions(-)
17
18
19
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/net/mptcp.h
22
+++ b/include/net/mptcp.h
23
@@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops {
24
#define MPTCP_PM_BUF_MAX    (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX)
25
26
struct mptcp_pm_ops {
27
+    int (*get_local_id)(struct mptcp_sock *msk,
28
+             struct mptcp_pm_addr_entry *skc);
29
+
30
    char            name[MPTCP_PM_NAME_MAX];
31
    struct module        *owner;
32
    struct list_head    list;
33
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/net/mptcp/pm.c
36
+++ b/net/mptcp/pm.c
37
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
38
    skc_local.addr.id = 0;
39
    skc_local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
40
41
-    if (mptcp_pm_is_userspace(msk))
42
-        return mptcp_userspace_pm_get_local_id(msk, &skc_local);
43
-    return mptcp_pm_nl_get_local_id(msk, &skc_local);
44
+    return msk->pm.ops->get_local_id(msk, &skc_local);
45
}
46
47
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
48
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name)
49
50
int mptcp_pm_validate(struct mptcp_pm_ops *pm)
51
{
52
-    if (!pm->init) {
53
+    if (!pm->init || !pm->get_local_id) {
54
        pr_err("%s does not implement required ops\n", pm->name);
55
        return -EINVAL;
56
    }
57
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/net/mptcp/pm_kernel.c
60
+++ b/net/mptcp/pm_kernel.c
61
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
62
    return err;
63
}
64
65
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
66
-             struct mptcp_pm_addr_entry *skc)
67
+static int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
68
+                 struct mptcp_pm_addr_entry *skc)
69
{
70
    struct mptcp_pm_addr_entry *entry;
71
    struct pm_nl_pernet *pernet;
72
@@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_initialize(struct mptcp_sock *msk)
73
}
74
75
struct mptcp_pm_ops mptcp_pm_kernel = {
76
+    .get_local_id        = mptcp_pm_nl_get_local_id,
77
    .init            = mptcp_pm_nl_initialize,
78
    .name            = "kernel",
79
    .owner            = THIS_MODULE,
18
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
80
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
19
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
20
--- a/net/mptcp/pm_userspace.c
82
--- a/net/mptcp/pm_userspace.c
21
+++ b/net/mptcp/pm_userspace.c
83
+++ b/net/mptcp/pm_userspace.c
22
@@ -XXX,XX +XXX,XX @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
84
@@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
23
    return NULL;
85
    return NULL;
24
}
86
}
25
87
26
+static int mptcp_userspace_pm_subflow_closed(struct mptcp_sock *msk,
88
-int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
27
+                     struct mptcp_pm_param *param)
89
-                 struct mptcp_pm_addr_entry *skc)
28
+{
90
+static int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
29
+    struct mptcp_pm_addr_entry *local = &param->entry;
91
+                     struct mptcp_pm_addr_entry *skc)
30
+    struct mptcp_addr_info *remote = &param->addr;
31
+    struct sock *ssk, *sk = (struct sock *)msk;
32
+
33
+    ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
34
+    if (!ssk)
35
+        return -ESRCH;
36
+
37
+    spin_lock_bh(&msk->pm.lock);
38
+    mptcp_userspace_pm_delete_local_addr(msk, local);
39
+    spin_unlock_bh(&msk->pm.lock);
40
+    mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
41
+    mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
42
+    MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
43
+
44
+    return 0;
45
+}
46
+
47
int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
48
{
92
{
49
    struct mptcp_pm_addr_entry addr_l;
93
    __be16 msk_sport = ((struct inet_sock *)
50
    struct mptcp_addr_info addr_r;
94
             inet_sk((struct sock *)msk))->inet_sport;
51
    struct nlattr *raddr, *laddr;
95
@@ -XXX,XX +XXX,XX @@ static void mptcp_userspace_pm_release(struct mptcp_sock *msk)
52
+    struct mptcp_pm_param param;
96
}
53
    struct mptcp_sock *msk;
97
54
-    struct sock *sk, *ssk;
98
static struct mptcp_pm_ops mptcp_pm_userspace = {
55
    int err = -EINVAL;
99
+    .get_local_id        = mptcp_userspace_pm_get_local_id,
56
+    struct sock *sk;
100
    .init            = mptcp_userspace_pm_init,
57
101
    .release        = mptcp_userspace_pm_release,
58
    if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
102
    .name            = "userspace",
59
     GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
103
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
60
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
104
index XXXXXXX..XXXXXXX 100644
61
    }
105
--- a/net/mptcp/protocol.h
62
106
+++ b/net/mptcp/protocol.h
63
    lock_sock(sk);
107
@@ -XXX,XX +XXX,XX @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
64
-    ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
108
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
65
-    if (!ssk) {
109
             struct mptcp_rm_list *rm_list);
66
-        GENL_SET_ERR_MSG(info, "subflow not found");
110
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
67
-        err = -ESRCH;
111
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
68
-        goto release_sock;
112
-             struct mptcp_pm_addr_entry *skc);
69
-    }
113
-int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
70
-
114
-                 struct mptcp_pm_addr_entry *skc);
71
-    spin_lock_bh(&msk->pm.lock);
115
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
72
-    mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
116
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
73
-    spin_unlock_bh(&msk->pm.lock);
117
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
74
-    mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
75
-    mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
76
-    MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
77
-release_sock:
78
+    mptcp_pm_param_set_contexts(&param, &addr_l, &addr_r);
79
+    err = msk->pm.ops && msk->pm.ops->subflow_closed ?
80
+     msk->pm.ops->subflow_closed(msk, &param) :
81
+     mptcp_userspace_pm_subflow_closed(msk, &param);
82
    release_sock(sk);
83
+    if (err)
84
+        GENL_SET_ERR_MSG(info, "subflow not found");
85
86
destroy_err:
87
    sock_put(sk);
88
@@ -XXX,XX +XXX,XX @@ static struct mptcp_pm_ops mptcp_userspace_pm = {
89
    .address_announced    = mptcp_userspace_pm_address_announced,
90
    .address_removed    = mptcp_userspace_pm_address_removed,
91
    .subflow_established    = mptcp_userspace_pm_subflow_established,
92
+    .subflow_closed        = mptcp_userspace_pm_subflow_closed,
93
    .get_local_id        = mptcp_userspace_pm_get_local_id,
94
    .get_priority        = mptcp_userspace_pm_get_priority,
95
    .type            = MPTCP_PM_TYPE_USERSPACE,
96
--
118
--
97
2.43.0
119
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Extract subflow_established() interface of the userspace PM from the
3
Now mptcp_pm_is_backup() can directly invoke get_priority() interface
4
handler of netlink command MPTCP_PM_CMD_SUBFLOW_CREATE
4
through "ops" of "msk->pm". Instead of using mptcp_pm_is_userspace()
5
to check which is_backup() helper to invoke.
5
6
6
mptcp_pm_nl_subflow_create_doit(),
7
Then mptcp_pm_nl_is_backup() and mptcp_userspace_pm_is_backup() helpers
7
8
can be static.
8
only leave the code for obtaining msk through "info", parsing local address
9
entry and parsing remote address info in the handler.
10
11
This interface is invoked under holding the msk socket lock.
12
9
13
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
14
---
11
---
15
net/mptcp/pm_userspace.c | 54 +++++++++++++++++++++++++---------------
12
include/net/mptcp.h | 2 ++
16
1 file changed, 34 insertions(+), 20 deletions(-)
13
net/mptcp/pm.c | 7 ++-----
14
net/mptcp/pm_kernel.c | 4 +++-
15
net/mptcp/pm_userspace.c | 5 +++--
16
net/mptcp/protocol.h | 2 --
17
5 files changed, 10 insertions(+), 10 deletions(-)
17
18
19
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/net/mptcp.h
22
+++ b/include/net/mptcp.h
23
@@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops {
24
struct mptcp_pm_ops {
25
    int (*get_local_id)(struct mptcp_sock *msk,
26
             struct mptcp_pm_addr_entry *skc);
27
+    bool (*get_priority)(struct mptcp_sock *msk,
28
+             struct mptcp_addr_info *skc);
29
30
    char            name[MPTCP_PM_NAME_MAX];
31
    struct module        *owner;
32
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/net/mptcp/pm.c
35
+++ b/net/mptcp/pm.c
36
@@ -XXX,XX +XXX,XX @@ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
37
38
    mptcp_local_address((struct sock_common *)skc, &skc_local);
39
40
-    if (mptcp_pm_is_userspace(msk))
41
-        return mptcp_userspace_pm_is_backup(msk, &skc_local);
42
-
43
-    return mptcp_pm_nl_is_backup(msk, &skc_local);
44
+    return msk->pm.ops->get_priority(msk, &skc_local);
45
}
46
47
static void mptcp_pm_subflows_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
48
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name)
49
50
int mptcp_pm_validate(struct mptcp_pm_ops *pm)
51
{
52
-    if (!pm->init || !pm->get_local_id) {
53
+    if (!pm->init || !pm->get_local_id || !pm->get_priority) {
54
        pr_err("%s does not implement required ops\n", pm->name);
55
        return -EINVAL;
56
    }
57
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/net/mptcp/pm_kernel.c
60
+++ b/net/mptcp/pm_kernel.c
61
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
62
    return ret;
63
}
64
65
-bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
66
+static bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk,
67
+                 struct mptcp_addr_info *skc)
68
{
69
    struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
70
    struct mptcp_pm_addr_entry *entry;
71
@@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_initialize(struct mptcp_sock *msk)
72
73
struct mptcp_pm_ops mptcp_pm_kernel = {
74
    .get_local_id        = mptcp_pm_nl_get_local_id,
75
+    .get_priority        = mptcp_pm_nl_is_backup,
76
    .init            = mptcp_pm_nl_initialize,
77
    .name            = "kernel",
78
    .owner            = THIS_MODULE,
18
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
79
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
19
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
20
--- a/net/mptcp/pm_userspace.c
81
--- a/net/mptcp/pm_userspace.c
21
+++ b/net/mptcp/pm_userspace.c
82
+++ b/net/mptcp/pm_userspace.c
22
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
83
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
23
    return err;
84
    return mptcp_userspace_pm_append_new_local_addr(msk, skc, true);
24
}
85
}
25
86
26
+static int mptcp_userspace_pm_subflow_established(struct mptcp_sock *msk,
87
-bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
27
+                         struct mptcp_pm_param *param)
88
-                 struct mptcp_addr_info *skc)
28
+{
89
+static bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
29
+    struct mptcp_pm_addr_entry *entry = &param->entry;
90
+                     struct mptcp_addr_info *skc)
30
+    struct mptcp_addr_info *remote = &param->addr;
31
+    struct sock *sk = (struct sock *)msk;
32
+    struct mptcp_pm_local local;
33
+    int err;
34
+
35
+    err = mptcp_userspace_pm_append_new_local_addr(msk, entry, false);
36
+    if (err < 0)
37
+        return err;
38
+
39
+    local.addr = entry->addr;
40
+    local.flags = entry->flags;
41
+    local.ifindex = entry->ifindex;
42
+
43
+    err = __mptcp_subflow_connect(sk, &local, remote);
44
+    spin_lock_bh(&msk->pm.lock);
45
+    if (err)
46
+        mptcp_userspace_pm_delete_local_addr(msk, entry);
47
+    else
48
+        msk->pm.subflows++;
49
+    spin_unlock_bh(&msk->pm.lock);
50
+
51
+    return err;
52
+}
53
+
54
int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
55
{
91
{
56
    struct mptcp_pm_addr_entry entry = { 0 };
92
    struct mptcp_pm_addr_entry *entry;
57
    struct mptcp_addr_info addr_r;
93
    bool backup;
58
    struct nlattr *raddr, *laddr;
94
@@ -XXX,XX +XXX,XX @@ static void mptcp_userspace_pm_release(struct mptcp_sock *msk)
59
-    struct mptcp_pm_local local;
95
60
+    struct mptcp_pm_param param;
96
static struct mptcp_pm_ops mptcp_pm_userspace = {
61
    struct mptcp_sock *msk;
62
    int err = -EINVAL;
63
    struct sock *sk;
64
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
65
        goto create_err;
66
    }
67
68
-    err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
69
-    if (err < 0) {
70
-        NL_SET_ERR_MSG_ATTR(info->extack, laddr,
71
-                 "did not match address and id");
72
-        goto create_err;
73
-    }
74
-
75
-    local.addr = entry.addr;
76
-    local.flags = entry.flags;
77
-    local.ifindex = entry.ifindex;
78
-
79
    lock_sock(sk);
80
-    err = __mptcp_subflow_connect(sk, &local, &addr_r);
81
+    mptcp_pm_param_set_contexts(&param, &entry, &addr_r);
82
+    err = msk->pm.ops && msk->pm.ops->subflow_established ?
83
+     msk->pm.ops->subflow_established(msk, &param) :
84
+     mptcp_userspace_pm_subflow_established(msk, &param);
85
    release_sock(sk);
86
87
    if (err)
88
        GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
89
90
-    spin_lock_bh(&msk->pm.lock);
91
-    if (err)
92
-        mptcp_userspace_pm_delete_local_addr(msk, &entry);
93
-    else
94
-        msk->pm.subflows++;
95
-    spin_unlock_bh(&msk->pm.lock);
96
-
97
create_err:
98
    sock_put(sk);
99
    return err;
100
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
101
static struct mptcp_pm_ops mptcp_userspace_pm = {
102
    .address_announced    = mptcp_userspace_pm_address_announced,
103
    .address_removed    = mptcp_userspace_pm_address_removed,
104
+    .subflow_established    = mptcp_userspace_pm_subflow_established,
105
    .get_local_id        = mptcp_userspace_pm_get_local_id,
97
    .get_local_id        = mptcp_userspace_pm_get_local_id,
106
    .get_priority        = mptcp_userspace_pm_get_priority,
98
+    .get_priority        = mptcp_userspace_pm_is_backup,
107
    .type            = MPTCP_PM_TYPE_USERSPACE,
99
    .init            = mptcp_userspace_pm_init,
100
    .release        = mptcp_userspace_pm_release,
101
    .name            = "userspace",
102
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
103
index XXXXXXX..XXXXXXX 100644
104
--- a/net/mptcp/protocol.h
105
+++ b/net/mptcp/protocol.h
106
@@ -XXX,XX +XXX,XX @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
107
             struct mptcp_rm_list *rm_list);
108
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
109
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
110
-bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
111
-bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
112
int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
113
             struct netlink_callback *cb);
114
int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
108
--
115
--
109
2.43.0
116
2.43.0
diff view generated by jsdifflib
New patch
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
2
3
This patch adds a new helper set_path_manager() to set the newly added
4
net.mptcp.path_manager, and test it inside a userspace pm test.
5
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
7
---
8
tools/testing/selftests/net/mptcp/mptcp_join.sh | 15 +++++++++++++++
9
1 file changed, 15 insertions(+)
10
11
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
12
index XXXXXXX..XXXXXXX 100755
13
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
14
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
15
@@ -XXX,XX +XXX,XX @@ userspace_tests()
16
    if reset_with_events "userspace pm add & remove address" &&
17
     continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
18
        set_userspace_pm $ns1
19
+        if continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then
20
+            local pm1 pm2
21
+
22
+            pm1=$(ip netns exec ${ns1} sysctl -n net.mptcp.path_manager)
23
+            if [ "$pm1" != "userspace" ]; then
24
+                mptcp_lib_pr_fail "ns1 pm_type mapping fails"
25
+                return 1
26
+            fi
27
+
28
+            pm2=$(ip netns exec ${ns2} sysctl -n net.mptcp.path_manager)
29
+            if [ "$pm2" != "kernel" ]; then
30
+                mptcp_lib_pr_fail "ns2 pm_type mapping fails"
31
+                return 1
32
+            fi
33
+        fi
34
        pm_nl_set_limits $ns2 2 2
35
        { speed=5 \
36
            run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
37
--
38
2.43.0
diff view generated by jsdifflib
1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Update the 2nd parameter of mptcp_pm_nl_address_removed(), and define it
3
This patch adds a new helper set_path_manager() to set the newly added
4
as the address_removed() interface of the in-kernel netlink PM.
4
net.mptcp.path_manager, and test it inside a userspace pm test.
5
6
This interface is invoked under holding the msk socket lock.
7
5
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
9
---
7
---
10
net/mptcp/pm_netlink.c | 10 ++++++++--
8
.../testing/selftests/net/mptcp/mptcp_join.sh | 34 ++++++++++++++++++-
11
1 file changed, 8 insertions(+), 2 deletions(-)
9
1 file changed, 33 insertions(+), 1 deletion(-)
12
10
13
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
11
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100755
15
--- a/net/mptcp/pm_netlink.c
13
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
16
+++ b/net/mptcp/pm_netlink.c
14
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
17
@@ -XXX,XX +XXX,XX @@ static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
15
@@ -XXX,XX +XXX,XX @@ CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
18
}
16
             6 0 0 65535,
19
17
             6 0 0 0"
20
static int mptcp_pm_nl_address_removed(struct mptcp_sock *msk,
18
21
-                 const struct mptcp_pm_addr_entry *local)
19
+set_path_manager()
22
+                 struct mptcp_pm_param *param)
20
+{
21
+    local ns=$1
22
+    local pm=$2
23
+
24
+    if ! ip netns exec ${ns} sysctl net.mptcp.available_path_managers |
25
+     grep -wq "${pm}"; then
26
+        mptcp_lib_pr_fail "path manager ${pm} not found"
27
+        return 1
28
+    fi
29
+    ip netns exec ${ns} sysctl -q net.mptcp.path_manager="${pm}"
30
+}
31
+
32
init_partial()
23
{
33
{
24
+    struct mptcp_pm_addr_entry *local = &param->entry;
34
    capout=$(mktemp)
25
    bool remove_subflow;
35
@@ -XXX,XX +XXX,XX @@ userspace_tests()
26
36
    # userspace pm create destroy subflow
27
    remove_subflow = mptcp_lookup_subflow_by_saddr(&msk->conn_list, &local->addr);
37
    if reset_with_events "userspace pm create destroy subflow" &&
28
@@ -XXX,XX +XXX,XX @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
38
     continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
29
39
-        set_userspace_pm $ns2
30
    while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
40
+        if continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/path_manager'; then
31
        struct sock *sk = (struct sock *)msk;
41
+            local pm1 pm2
32
+        struct mptcp_pm_param param;
42
+
33
43
+            set_path_manager $ns1 "kernel"
34
        if (mptcp_pm_is_userspace(msk))
44
+            set_path_manager $ns2 "userspace"
35
            goto next;
45
+
36
46
+            pm1=$(ip netns exec ${ns1} sysctl -n net.mptcp.pm_type)
37
        lock_sock(sk);
47
+            if [ "$pm1" != "0" ]; then
38
-        mptcp_pm_nl_address_removed(msk, entry);
48
+                mptcp_lib_pr_fail "ns1 pm_type mapping fails"
39
+        mptcp_pm_param_set_contexts(&param, entry, NULL);
49
+                return 1
40
+        msk->pm.ops && msk->pm.ops->address_removed ?
50
+            fi
41
+            msk->pm.ops->address_removed(msk, &param) :
51
+
42
+            mptcp_pm_nl_address_removed(msk, &param);
52
+            pm2=$(ip netns exec ${ns2} sysctl -n net.mptcp.pm_type)
43
        mptcp_pm_nl_subflow_closed(msk, entry);
53
+            if [ "$pm2" != "1" ]; then
44
        release_sock(sk);
54
+                mptcp_lib_pr_fail "ns2 pm_type mapping fails"
45
55
+                return 1
46
@@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = {
56
+            fi
47
57
+        else
48
static struct mptcp_pm_ops mptcp_netlink_pm = {
58
+            set_userspace_pm $ns2
49
    .address_announced    = mptcp_pm_nl_address_announced,
59
+        fi
50
+    .address_removed    = mptcp_pm_nl_address_removed,
60
        pm_nl_set_limits $ns1 0 1
51
    .get_local_id        = mptcp_pm_nl_get_local_id,
61
        { speed=5 \
52
    .get_priority        = mptcp_pm_nl_get_priority,
62
            run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
53
    .type            = MPTCP_PM_TYPE_KERNEL,
54
--
63
--
55
2.43.0
64
2.43.0
diff view generated by jsdifflib