1
From: Geliang Tang <tanggeliang@kylinos.cn>
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
2
3
Some path manager related refactoring and cleanups.
3
v4:
4
- include a new patch "define BPF path manager type".
4
5
5
Geliang Tang (6):
6
- add new interfaces:
6
mptcp: pm: in-kernel: avoid access entry without lock
7
    created established closed
7
mptcp: pm: in-kernel: reduce parameters of set_flags
8
    listerner_created listener_closed
8
mptcp: pm: use addr entry for get_local_id
9
mptcp: pm: in-kernel: use kmemdup helper
10
sock: add sock_kmemdup helper
11
mptcp: pm: userspace: use sock_kmemdup helper
12
9
13
include/net/sock.h | 1 +
10
- rename interfaces as:
14
net/core/sock.c | 23 +++++++++++++++++++++++
11
    address_announced address_removed
15
net/mptcp/pm.c | 9 ++++++---
12
    subflow_established subflow_closed
16
net/mptcp/pm_netlink.c | 30 +++++++++++++-----------------
13
    get_priority set_priority
17
net/mptcp/pm_userspace.c | 20 +++++++-------------
14
18
net/mptcp/protocol.h | 6 ++++--
15
- rename functions as:
19
6 files changed, 54 insertions(+), 35 deletions(-)
16
    mptcp_pm_validate
17
    mptcp_pm_register
18
    mptcp_pm_unregister
19
    mptcp_pm_initialize
20
    mptcp_pm_release
21
22
v3:
23
- rename the 2nd parameter of get_local_id() from 'local' to 'skc'.
24
- keep the 'msk_sport' check in mptcp_userspace_pm_get_local_id().
25
- return 'err' instead of '0' in userspace_pm_subflow_create().
26
- drop 'ret' variable inmptcp_pm_data_reset().
27
- fix typos in commit log.
28
29
v2:
30
- update get_local_id interface in patch 2.
31
32
get_addr() and dump_addr() interfaces of BPF userspace pm are dropped
33
as Matt suggested.
34
35
In order to implement BPF userspace path manager, it is necessary to
36
unify the interfaces of the path manager. This set contains some
37
cleanups and refactoring to unify the interfaces in kernel space.
38
Finally, define a struct mptcp_pm_ops for a userspace path manager
39
like this:
40
41
struct mptcp_pm_ops {
42
int (*created)(struct mptcp_sock *msk);
43
int (*established)(struct mptcp_sock *msk);
44
int (*closed)(struct mptcp_sock *msk);
45
int (*address_announced)(struct mptcp_sock *msk,
46
struct mptcp_pm_addr_entry *local);
47
int (*address_removed)(struct mptcp_sock *msk, u8 id);
48
int (*subflow_established)(struct mptcp_sock *msk,
49
struct mptcp_pm_addr_entry *local,
50
struct mptcp_addr_info *remote);
51
int (*subflow_closed)(struct mptcp_sock *msk,
52
struct mptcp_pm_addr_entry *local,
53
struct mptcp_addr_info *remote);
54
int (*get_local_id)(struct mptcp_sock *msk,
55
struct mptcp_pm_addr_entry *skc);
56
bool (*get_priority)(struct mptcp_sock *msk,
57
struct mptcp_addr_info *skc);
58
int (*set_priority)(struct mptcp_sock *msk,
59
struct mptcp_pm_addr_entry *local,
60
struct mptcp_addr_info *remote);
61
int (*listener_created)(struct mptcp_sock *msk);
62
int (*listener_closed)(struct mptcp_sock *msk);
63
64
u8 type;
65
struct module *owner;
66
struct list_head list;
67
68
void (*init)(struct mptcp_sock *msk);
69
void (*release)(struct mptcp_sock *msk);
70
} ____cacheline_aligned_in_smp;
71
72
Geliang Tang (4):
73
mptcp: define struct mptcp_pm_ops
74
mptcp: define BPF path manager type
75
mptcp: register default userspace pm
76
mptcp: initialize and release mptcp_pm_ops
77
78
include/net/mptcp.h | 32 +++++
79
net/mptcp/pm.c | 109 ++++++++++++++-
80
net/mptcp/pm_netlink.c | 11 +-
81
net/mptcp/pm_userspace.c | 294 ++++++++++++++++++++++++---------------
82
net/mptcp/protocol.c | 10 +-
83
net/mptcp/protocol.h | 15 +-
84
6 files changed, 355 insertions(+), 116 deletions(-)
20
85
21
--
86
--
22
2.43.0
87
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 adds the sock version of kmemdup() helper, named sock_kmemdup(),
3
In order to allow users to develop their own BPF-based path manager,
4
to duplicate a memory block using the socket's option memory buffer.
4
this patch defines a struct ops "mptcp_pm_ops" for a userspace path
5
manager, which contains a set of interfaces.
6
7
Add a set of functions to register, unregister, find and validate a
8
given struct ops.
5
9
6
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
7
---
11
---
8
include/net/sock.h | 1 +
12
include/net/mptcp.h | 32 ++++++++++++++++++++++++
9
net/core/sock.c | 23 +++++++++++++++++++++++
13
net/mptcp/pm.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 24 insertions(+)
14
net/mptcp/protocol.h | 5 ++++
15
3 files changed, 96 insertions(+)
11
16
12
diff --git a/include/net/sock.h b/include/net/sock.h
17
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/net/sock.h
19
--- a/include/net/mptcp.h
15
+++ b/include/net/sock.h
20
+++ b/include/net/mptcp.h
16
@@ -XXX,XX +XXX,XX @@ static inline struct sk_buff *sock_alloc_send_skb(struct sock *sk,
21
@@ -XXX,XX +XXX,XX @@
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
+struct mptcp_pm_ops {
34
+    int (*created)(struct mptcp_sock *msk);
35
+    int (*established)(struct mptcp_sock *msk);
36
+    int (*closed)(struct mptcp_sock *msk);
37
+    int (*address_announced)(struct mptcp_sock *msk,
38
+                 struct mptcp_pm_addr_entry *local);
39
+    int (*address_removed)(struct mptcp_sock *msk, u8 id);
40
+    int (*subflow_established)(struct mptcp_sock *msk,
41
+                 struct mptcp_pm_addr_entry *local,
42
+                 struct mptcp_addr_info *remote);
43
+    int (*subflow_closed)(struct mptcp_sock *msk,
44
+             struct mptcp_pm_addr_entry *local,
45
+             struct mptcp_addr_info *remote);
46
+    int (*get_local_id)(struct mptcp_sock *msk,
47
+             struct mptcp_pm_addr_entry *skc);
48
+    bool (*get_priority)(struct mptcp_sock *msk,
49
+             struct mptcp_addr_info *skc);
50
+    int (*set_priority)(struct mptcp_sock *msk,
51
+             struct mptcp_pm_addr_entry *local,
52
+             struct mptcp_addr_info *remote);
53
+    int (*listener_created)(struct mptcp_sock *msk);
54
+    int (*listener_closed)(struct mptcp_sock *msk);
55
+
56
+    u8            type;
57
+    struct module        *owner;
58
+    struct list_head    list;
59
+
60
+    void (*init)(struct mptcp_sock *msk);
61
+    void (*release)(struct mptcp_sock *msk);
62
+} ____cacheline_aligned_in_smp;
63
+
64
#ifdef CONFIG_MPTCP
65
void mptcp_init(void);
66
67
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/net/mptcp/pm.c
70
+++ b/net/mptcp/pm.c
71
@@ -XXX,XX +XXX,XX @@
72
#define pr_fmt(fmt) "MPTCP: " fmt
73
74
#include <linux/kernel.h>
75
+#include <linux/rculist.h>
76
+#include <linux/spinlock.h>
77
#include <net/mptcp.h>
78
#include "protocol.h"
79
80
#include "mib.h"
81
#include "mptcp_pm_gen.h"
82
83
+static DEFINE_SPINLOCK(mptcp_pm_list_lock);
84
+static LIST_HEAD(mptcp_pm_list);
85
+
86
/* path manager command handlers */
87
88
int mptcp_pm_announce_addr(struct mptcp_sock *msk,
89
@@ -XXX,XX +XXX,XX @@ void __init mptcp_pm_init(void)
90
{
91
    mptcp_pm_nl_init();
17
}
92
}
18
93
+
19
void *sock_kmalloc(struct sock *sk, int size, gfp_t priority);
94
+/* Must be called with rcu read lock held */
20
+void *sock_kmemdup(struct sock *sk, const void *src, int size, gfp_t priority);
95
+struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type)
21
void sock_kfree_s(struct sock *sk, void *mem, int size);
22
void sock_kzfree_s(struct sock *sk, void *mem, int size);
23
void sk_send_sigurg(struct sock *sk);
24
diff --git a/net/core/sock.c b/net/core/sock.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/net/core/sock.c
27
+++ b/net/core/sock.c
28
@@ -XXX,XX +XXX,XX @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
29
}
30
EXPORT_SYMBOL(sock_kmalloc);
31
32
+/*
33
+ * Duplicate a memory block using the socket's option memory buffer.
34
+ */
35
+void *sock_kmemdup(struct sock *sk, const void *src, int size, gfp_t priority)
36
+{
96
+{
37
+    int optmem_max = READ_ONCE(sock_net(sk)->core.sysctl_optmem_max);
97
+    struct mptcp_pm_ops *pm;
38
+
98
+
39
+    if ((unsigned int)size <= optmem_max &&
99
+    list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
40
+     atomic_read(&sk->sk_omem_alloc) + size < optmem_max) {
100
+        if (pm->type == type)
41
+        void *mem;
101
+            return pm;
42
+        /* First do the add, to avoid the race if kmalloc
43
+         * might sleep.
44
+         */
45
+        atomic_add(size, &sk->sk_omem_alloc);
46
+        mem = kmemdup(src, size, priority);
47
+        if (mem)
48
+            return mem;
49
+        atomic_sub(size, &sk->sk_omem_alloc);
50
+    }
102
+    }
103
+
51
+    return NULL;
104
+    return NULL;
52
+}
105
+}
53
+EXPORT_SYMBOL(sock_kmemdup);
54
+
106
+
55
/* Free an option memory block. Note, we actually want the inline
107
+int mptcp_pm_validate(struct mptcp_pm_ops *pm)
56
* here as this allows gcc to detect the nullify and fold away the
108
+{
57
* condition entirely.
109
+    if (!pm->created && !pm->established && !pm->closed &&
110
+     !pm->address_announced && !pm->address_removed &&
111
+     !pm->subflow_established && !pm->subflow_closed &&
112
+     !pm->get_local_id && !pm->get_priority && !pm->set_priority &&
113
+     !pm->listener_created && !pm->listener_closed) {
114
+        pr_err("%u does not implement required ops\n", pm->type);
115
+        return -EINVAL;
116
+    }
117
+
118
+    return 0;
119
+}
120
+
121
+int mptcp_pm_register(struct mptcp_pm_ops *pm)
122
+{
123
+    int ret;
124
+
125
+    ret = mptcp_pm_validate(pm);
126
+    if (ret)
127
+        return ret;
128
+
129
+    spin_lock(&mptcp_pm_list_lock);
130
+    if (mptcp_pm_find(pm->type)) {
131
+        spin_unlock(&mptcp_pm_list_lock);
132
+        return -EEXIST;
133
+    }
134
+    list_add_tail_rcu(&pm->list, &mptcp_pm_list);
135
+    spin_unlock(&mptcp_pm_list_lock);
136
+
137
+    pr_debug("userspace_pm type %u registered\n", pm->type);
138
+    return 0;
139
+}
140
+
141
+void mptcp_pm_unregister(struct mptcp_pm_ops *pm)
142
+{
143
+    spin_lock(&mptcp_pm_list_lock);
144
+    list_del_rcu(&pm->list);
145
+    spin_unlock(&mptcp_pm_list_lock);
146
+}
147
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
148
index XXXXXXX..XXXXXXX 100644
149
--- a/net/mptcp/protocol.h
150
+++ b/net/mptcp/protocol.h
151
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
152
void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
153
                struct mptcp_pm_addr_entry *entry);
154
155
+struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type);
156
+int mptcp_pm_validate(struct mptcp_pm_ops *pm);
157
+int mptcp_pm_register(struct mptcp_pm_ops *pm);
158
+void mptcp_pm_unregister(struct mptcp_pm_ops *pm);
159
+
160
void mptcp_free_local_addr_list(struct mptcp_sock *msk);
161
162
void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
58
--
163
--
59
2.43.0
164
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
The number of parameters in mptcp_nl_set_flags() can be reduced.
3
This patch defines a new path manager type: MPTCP_PM_TYPE_BPF_USERSPACE,
4
Only need to pass a "local" parameter to it instead of "local->addr"
4
which is used for the userspace path manager implemented in BPF. This
5
and "local->flags".
5
path manager is also a userspace path manager, so add this new type in
6
mptcp_pm_is_userspace() too.
6
7
7
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
8
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
8
---
9
---
9
net/mptcp/pm_netlink.c | 15 ++++++++-------
10
net/mptcp/protocol.h | 6 +++++-
10
1 file changed, 8 insertions(+), 7 deletions(-)
11
1 file changed, 5 insertions(+), 1 deletion(-)
11
12
12
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
13
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/net/mptcp/pm_netlink.c
15
--- a/net/mptcp/protocol.h
15
+++ b/net/mptcp/pm_netlink.c
16
+++ b/net/mptcp/protocol.h
16
@@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
17
@@ -XXX,XX +XXX,XX @@ enum mptcp_pm_status {
17
    spin_unlock_bh(&msk->pm.lock);
18
enum mptcp_pm_type {
19
    MPTCP_PM_TYPE_KERNEL = 0,
20
    MPTCP_PM_TYPE_USERSPACE,
21
+    MPTCP_PM_TYPE_BPF_USERSPACE,
22
23
    __MPTCP_PM_TYPE_NR,
24
    __MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1,
25
@@ -XXX,XX +XXX,XX @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
26
27
static inline bool mptcp_pm_is_userspace(const struct mptcp_sock *msk)
28
{
29
-    return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_USERSPACE;
30
+    enum mptcp_pm_type pm_type = READ_ONCE(msk->pm.pm_type);
31
+
32
+    return (pm_type == MPTCP_PM_TYPE_USERSPACE ||
33
+        pm_type == MPTCP_PM_TYPE_BPF_USERSPACE);
18
}
34
}
19
35
20
-static void mptcp_nl_set_flags(struct net *net, struct mptcp_addr_info *addr,
36
static inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk)
21
-             u8 flags, u8 changed)
22
+static void mptcp_nl_set_flags(struct net *net,
23
+             struct mptcp_pm_addr_entry *local,
24
+             u8 changed)
25
{
26
-    u8 is_subflow = !!(flags & MPTCP_PM_ADDR_FLAG_SUBFLOW);
27
-    u8 bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
28
+    u8 is_subflow = !!(local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW);
29
+    u8 bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
30
    long s_slot = 0, s_num = 0;
31
    struct mptcp_sock *msk;
32
33
@@ -XXX,XX +XXX,XX @@ static void mptcp_nl_set_flags(struct net *net, struct mptcp_addr_info *addr,
34
35
        lock_sock(sk);
36
        if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
37
-            mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
38
+            mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, NULL, bkup);
39
        /* Subflows will only be recreated if the SUBFLOW flag is set */
40
        if (is_subflow && (changed & MPTCP_PM_ADDR_FLAG_FULLMESH))
41
-            mptcp_pm_nl_fullmesh(msk, addr);
42
+            mptcp_pm_nl_fullmesh(msk, &local->addr);
43
        release_sock(sk);
44
45
next:
46
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local,
47
    *local = *entry;
48
    spin_unlock_bh(&pernet->lock);
49
50
-    mptcp_nl_set_flags(net, &local->addr, local->flags, changed);
51
+    mptcp_nl_set_flags(net, local, changed);
52
    return 0;
53
}
54
55
--
37
--
56
2.43.0
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
The following code in mptcp_userspace_pm_get_local_id() that assigns "skc"
3
This patch defines the original userspace pm as the default path manager,
4
to "new_entry" is not allowed in BPF if we use the same code to implement
4
named mptcp_userspace_pm, and register it in mptcp_pm_data_init().
5
the get_local_id() interface of a BFP path manager:
5
6
6
Extract address_announce() interface of the userspace PM from the handler
7
    memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
7
of netlink command MPTCP_PM_CMD_ANNOUNCE mptcp_pm_nl_announce_doit(), only
8
    new_entry.addr = *skc;
8
leave the code for obtaining msk through "info" and parsing address entry
9
    new_entry.addr.id = 0;
9
in the handler.
10
    new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
10
11
11
Extract address_remove() interface of the userspace PM from the handler
12
To solve the issue, this patch moves this assignment to "new_entry" forward
12
of netlink command MPTCP_PM_CMD_REMOVE mptcp_pm_nl_remove_doit(), only
13
to mptcp_pm_get_local_id(), and then passing "new_entry" as a parameter to
13
leave the code for parsing address id and obtaining msk through "info"
14
both mptcp_pm_nl_get_local_id() and mptcp_userspace_pm_get_local_id().
14
in the handler.
15
16
Extract subflow_create() interface of the userspace PM from the handler of
17
netlink command MPTCP_PM_CMD_SUBFLOW_CREATE
18
19
    mptcp_pm_nl_subflow_create_doit(),
20
21
only leave the code for obtaining msk through "info", parsing local address
22
entry and parsing remote address info in the handler.
23
24
Extract subflow_destroy() interface of the userspace PM from the handler of
25
netlink command MPTCP_PM_CMD_SUBFLOW_DESTROY
26
27
    mptcp_pm_nl_subflow_destroy_doit(),
28
29
only leave the code for obtaining msk through "info", parsing local address
30
entry and parsing remote address info in the handler.
31
32
Extract set_flags() interface of the userspace PM from function
33
mptcp_userspace_pm_set_flags(), only leave the code for obtaining
34
msk through "info" in this function.
35
36
All fives interfaces are invoked under holding the msk socket lock.
37
38
Extract get_local_id() interface of the userspace PM from function
39
mptcp_userspace_pm_get_local_id(), only leave the code for setting
40
new address entry in this function.
41
42
get_flags() interface of the userspace PM is defined as the same as
43
the function mptcp_userspace_pm_get_flags(), then this function
44
becomes a wrapper.
15
45
16
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
46
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
17
---
47
---
18
net/mptcp/pm.c | 9 ++++++---
48
net/mptcp/pm.c | 1 +
19
net/mptcp/pm_netlink.c | 11 ++++-------
49
net/mptcp/pm_userspace.c | 280 +++++++++++++++++++++++----------------
20
net/mptcp/pm_userspace.c | 17 ++++++-----------
50
net/mptcp/protocol.h | 1 +
21
net/mptcp/protocol.h | 6 ++++--
51
3 files changed, 171 insertions(+), 111 deletions(-)
22
4 files changed, 20 insertions(+), 23 deletions(-)
23
52
24
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
53
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
25
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
26
--- a/net/mptcp/pm.c
55
--- a/net/mptcp/pm.c
27
+++ b/net/mptcp/pm.c
56
+++ b/net/mptcp/pm.c
28
@@ -XXX,XX +XXX,XX @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
57
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
29
58
void __init mptcp_pm_init(void)
30
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
59
{
31
{
60
    mptcp_pm_nl_init();
32
-    struct mptcp_addr_info skc_local;
61
+    mptcp_userspace_pm_init();
33
+    struct mptcp_pm_addr_entry skc_local = { 0 };
62
}
34
    struct mptcp_addr_info msk_local;
63
35
64
/* Must be called with rcu read lock held */
36
    if (WARN_ON_ONCE(!msk))
37
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
38
     * addr
39
     */
40
    mptcp_local_address((struct sock_common *)msk, &msk_local);
41
-    mptcp_local_address((struct sock_common *)skc, &skc_local);
42
-    if (mptcp_addresses_equal(&msk_local, &skc_local, false))
43
+    mptcp_local_address((struct sock_common *)skc, &skc_local.addr);
44
+    if (mptcp_addresses_equal(&msk_local, &skc_local.addr, false))
45
        return 0;
46
47
+    skc_local.addr.id = 0;
48
+    skc_local.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
49
+
50
    if (mptcp_pm_is_userspace(msk))
51
        return mptcp_userspace_pm_get_local_id(msk, &skc_local);
52
    return mptcp_pm_nl_get_local_id(msk, &skc_local);
53
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/net/mptcp/pm_netlink.c
56
+++ b/net/mptcp/pm_netlink.c
57
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
58
    return err;
59
}
60
61
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
62
+int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
63
+             struct mptcp_pm_addr_entry *skc)
64
{
65
    struct mptcp_pm_addr_entry *entry;
66
    struct pm_nl_pernet *pernet;
67
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
68
    pernet = pm_nl_get_pernet_from_msk(msk);
69
70
    rcu_read_lock();
71
-    entry = __lookup_addr(pernet, skc);
72
+    entry = __lookup_addr(pernet, &skc->addr);
73
    ret = entry ? entry->addr.id : -1;
74
    rcu_read_unlock();
75
    if (ret >= 0)
76
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
77
    if (!entry)
78
        return -ENOMEM;
79
80
-    entry->addr = *skc;
81
-    entry->addr.id = 0;
82
+    *entry = *skc;
83
    entry->addr.port = 0;
84
-    entry->ifindex = 0;
85
-    entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
86
-    entry->lsk = NULL;
87
    ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
88
    if (ret < 0)
89
        kfree(entry);
90
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
65
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
91
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
92
--- a/net/mptcp/pm_userspace.c
67
--- a/net/mptcp/pm_userspace.c
93
+++ b/net/mptcp/pm_userspace.c
68
+++ b/net/mptcp/pm_userspace.c
94
@@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
69
@@ -XXX,XX +XXX,XX @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
95
}
70
    return NULL;
96
71
}
97
int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
72
73
-int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
98
-                 struct mptcp_addr_info *skc)
74
-                 struct mptcp_addr_info *skc)
99
+                 struct mptcp_pm_addr_entry *skc)
75
+static int userspace_pm_get_local_id(struct mptcp_sock *msk,
76
+                 struct mptcp_pm_addr_entry *skc)
100
{
77
{
101
-    struct mptcp_pm_addr_entry *entry = NULL, new_entry;
78
-    struct mptcp_pm_addr_entry *entry = NULL, new_entry;
102
    __be16 msk_sport = ((struct inet_sock *)
79
-    __be16 msk_sport = ((struct inet_sock *)
103
             inet_sk((struct sock *)msk))->inet_sport;
80
-             inet_sk((struct sock *)msk))->inet_sport;
104
+    struct mptcp_pm_addr_entry *entry;
81
+    struct mptcp_pm_addr_entry *entry;
105
82
106
    spin_lock_bh(&msk->pm.lock);
83
    spin_lock_bh(&msk->pm.lock);
107
-    entry = mptcp_userspace_pm_lookup_addr(msk, skc);
84
-    entry = mptcp_userspace_pm_lookup_addr(msk, skc);
108
+    entry = mptcp_userspace_pm_lookup_addr(msk, &skc->addr);
85
+    entry = mptcp_userspace_pm_lookup_addr(msk, &skc->addr);
109
    spin_unlock_bh(&msk->pm.lock);
86
    spin_unlock_bh(&msk->pm.lock);
110
    if (entry)
87
    if (entry)
111
        return entry->addr.id;
88
        return entry->addr.id;
112
89
113
-    memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
90
+    return mptcp_userspace_pm_append_new_local_addr(msk, skc, true);
114
-    new_entry.addr = *skc;
91
+}
115
-    new_entry.addr.id = 0;
92
+
116
-    new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
93
+int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
117
-
94
+                 struct mptcp_addr_info *skc)
118
-    if (new_entry.addr.port == msk_sport)
95
+{
119
-        new_entry.addr.port = 0;
96
+    __be16 msk_sport = ((struct inet_sock *)
120
+    if (skc->addr.port == msk_sport)
97
+             inet_sk((struct sock *)msk))->inet_sport;
121
+        skc->addr.port = 0;
98
+    struct mptcp_pm_addr_entry new_entry;
99
+
100
    memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
101
    new_entry.addr = *skc;
102
    new_entry.addr.id = 0;
103
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
104
    if (new_entry.addr.port == msk_sport)
105
        new_entry.addr.port = 0;
122
106
123
-    return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
107
-    return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
124
+    return mptcp_userspace_pm_append_new_local_addr(msk, skc, true);
108
+    return userspace_pm_get_local_id(msk, &new_entry);
125
}
109
}
126
110
127
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
111
-bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
112
-                 struct mptcp_addr_info *skc)
113
+static bool userspace_pm_get_priority(struct mptcp_sock *msk,
114
+                 struct mptcp_addr_info *skc)
115
{
116
    struct mptcp_pm_addr_entry *entry;
117
    bool backup;
118
@@ -XXX,XX +XXX,XX @@ bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
119
    return backup;
120
}
121
122
+bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
123
+                 struct mptcp_addr_info *skc)
124
+{
125
+    return userspace_pm_get_priority(msk, skc);
126
+}
127
+
128
static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
129
{
130
    struct mptcp_sock *msk;
131
@@ -XXX,XX +XXX,XX @@ static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *in
132
    return msk;
133
}
134
135
+static int userspace_pm_address_announced(struct mptcp_sock *msk,
136
+                     struct mptcp_pm_addr_entry *local)
137
+{
138
+    int err;
139
+
140
+    err = mptcp_userspace_pm_append_new_local_addr(msk, local, false);
141
+    if (err < 0)
142
+        return err;
143
+
144
+    spin_lock_bh(&msk->pm.lock);
145
+
146
+    if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
147
+        msk->pm.add_addr_signaled++;
148
+        mptcp_pm_announce_addr(msk, &local->addr, false);
149
+        mptcp_pm_nl_addr_send_ack(msk);
150
+    }
151
+
152
+    spin_unlock_bh(&msk->pm.lock);
153
+
154
+    return 0;
155
+}
156
+
157
int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
158
{
159
    struct mptcp_pm_addr_entry addr_val;
160
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
161
        goto announce_err;
162
    }
163
164
-    err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
165
-    if (err < 0) {
166
-        NL_SET_ERR_MSG_ATTR(info->extack, addr,
167
-                 "did not match address and id");
168
-        goto announce_err;
169
-    }
170
-
171
    lock_sock(sk);
172
-    spin_lock_bh(&msk->pm.lock);
173
-
174
-    if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) {
175
-        msk->pm.add_addr_signaled++;
176
-        mptcp_pm_announce_addr(msk, &addr_val.addr, false);
177
-        mptcp_pm_nl_addr_send_ack(msk);
178
-    }
179
-
180
-    spin_unlock_bh(&msk->pm.lock);
181
+    err = userspace_pm_address_announced(msk, &addr_val);
182
    release_sock(sk);
183
+    if (err)
184
+        NL_SET_ERR_MSG_ATTR(info->extack, addr,
185
+                 "did not match address and id");
186
187
-    err = 0;
188
announce_err:
189
    sock_put(sk);
190
    return err;
191
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
192
{
193
    struct mptcp_rm_list list = { .nr = 0 };
194
    struct mptcp_subflow_context *subflow;
195
-    struct sock *sk = (struct sock *)msk;
196
    bool has_id_0 = false;
197
-    int err = -EINVAL;
198
199
-    lock_sock(sk);
200
    mptcp_for_each_subflow(msk, subflow) {
201
        if (READ_ONCE(subflow->local_id) == 0) {
202
            has_id_0 = true;
203
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
204
        }
205
    }
206
    if (!has_id_0)
207
-        goto remove_err;
208
+        return -EINVAL;
209
210
    list.ids[list.nr++] = 0;
211
212
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk)
213
    mptcp_pm_remove_addr(msk, &list);
214
    spin_unlock_bh(&msk->pm.lock);
215
216
-    err = 0;
217
-
218
-remove_err:
219
-    release_sock(sk);
220
-    return err;
221
+    return 0;
222
}
223
224
void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
225
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
226
    spin_unlock_bh(&msk->pm.lock);
227
}
228
229
+static int userspace_pm_address_removed(struct mptcp_sock *msk, u8 id)
230
+{
231
+    struct mptcp_pm_addr_entry *entry;
232
+
233
+    if (id == 0)
234
+        return mptcp_userspace_pm_remove_id_zero_address(msk);
235
+
236
+    spin_lock_bh(&msk->pm.lock);
237
+    entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
238
+    if (!entry) {
239
+        spin_unlock_bh(&msk->pm.lock);
240
+        return -EINVAL;
241
+    }
242
+
243
+    list_del_rcu(&entry->list);
244
+    spin_unlock_bh(&msk->pm.lock);
245
+
246
+    mptcp_pm_remove_addr_entry(msk, entry);
247
+
248
+    sock_kfree_s((struct sock *)msk, entry, sizeof(*entry));
249
+
250
+    return 0;
251
+}
252
+
253
int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
254
{
255
-    struct mptcp_pm_addr_entry *match;
256
    struct mptcp_sock *msk;
257
    struct nlattr *id;
258
    int err = -EINVAL;
259
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
260
261
    sk = (struct sock *)msk;
262
263
-    if (id_val == 0) {
264
-        err = mptcp_userspace_pm_remove_id_zero_address(msk);
265
-        goto out;
266
-    }
267
-
268
    lock_sock(sk);
269
-
270
-    spin_lock_bh(&msk->pm.lock);
271
-    match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
272
-    if (!match) {
273
-        spin_unlock_bh(&msk->pm.lock);
274
-        release_sock(sk);
275
-        goto out;
276
-    }
277
-
278
-    list_del_rcu(&match->list);
279
-    spin_unlock_bh(&msk->pm.lock);
280
-
281
-    mptcp_pm_remove_addr_entry(msk, match);
282
-
283
+    err = userspace_pm_address_removed(msk, id_val);
284
    release_sock(sk);
285
-
286
-    sock_kfree_s(sk, match, sizeof(*match));
287
-
288
-    err = 0;
289
-out:
290
    if (err)
291
        NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
292
                    "address with id %u not found",
293
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
294
    return err;
295
}
296
297
+static int userspace_pm_subflow_established(struct mptcp_sock *msk,
298
+                     struct mptcp_pm_addr_entry *entry,
299
+                     struct mptcp_addr_info *remote)
300
+{
301
+    struct sock *sk = (struct sock *)msk;
302
+    struct mptcp_pm_local local;
303
+    int err;
304
+
305
+    err = mptcp_userspace_pm_append_new_local_addr(msk, entry, false);
306
+    if (err < 0)
307
+        return err;
308
+
309
+    local.addr = entry->addr;
310
+    local.flags = entry->flags;
311
+    local.ifindex = entry->ifindex;
312
+
313
+    err = __mptcp_subflow_connect(sk, &local, remote);
314
+    spin_lock_bh(&msk->pm.lock);
315
+    if (err)
316
+        mptcp_userspace_pm_delete_local_addr(msk, entry);
317
+    else
318
+        msk->pm.subflows++;
319
+    spin_unlock_bh(&msk->pm.lock);
320
+
321
+    return err;
322
+}
323
+
324
int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
325
{
326
    struct mptcp_pm_addr_entry entry = { 0 };
327
    struct mptcp_addr_info addr_r;
328
    struct nlattr *raddr, *laddr;
329
-    struct mptcp_pm_local local;
330
    struct mptcp_sock *msk;
331
    int err = -EINVAL;
332
    struct sock *sk;
333
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
334
        goto create_err;
335
    }
336
337
-    err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
338
-    if (err < 0) {
339
-        NL_SET_ERR_MSG_ATTR(info->extack, laddr,
340
-                 "did not match address and id");
341
-        goto create_err;
342
-    }
343
-
344
-    local.addr = entry.addr;
345
-    local.flags = entry.flags;
346
-    local.ifindex = entry.ifindex;
347
-
348
    lock_sock(sk);
349
-    err = __mptcp_subflow_connect(sk, &local, &addr_r);
350
+    err = userspace_pm_subflow_established(msk, &entry, &addr_r);
351
    release_sock(sk);
352
353
    if (err)
354
        GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
355
356
-    spin_lock_bh(&msk->pm.lock);
357
-    if (err)
358
-        mptcp_userspace_pm_delete_local_addr(msk, &entry);
359
-    else
360
-        msk->pm.subflows++;
361
-    spin_unlock_bh(&msk->pm.lock);
362
-
363
create_err:
364
    sock_put(sk);
365
    return err;
366
@@ -XXX,XX +XXX,XX @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
367
    return NULL;
368
}
369
370
+static int userspace_pm_subflow_closed(struct mptcp_sock *msk,
371
+                 struct mptcp_pm_addr_entry *local,
372
+                 struct mptcp_addr_info *remote)
373
+{
374
+    struct sock *ssk, *sk = (struct sock *)msk;
375
+
376
+    ssk = mptcp_nl_find_ssk(msk, &local->addr, remote);
377
+    if (!ssk)
378
+        return -ESRCH;
379
+
380
+    spin_lock_bh(&msk->pm.lock);
381
+    mptcp_userspace_pm_delete_local_addr(msk, local);
382
+    spin_unlock_bh(&msk->pm.lock);
383
+    mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
384
+    mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
385
+    MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
386
+
387
+    return 0;
388
+}
389
+
390
int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info)
391
{
392
    struct mptcp_pm_addr_entry addr_l;
393
    struct mptcp_addr_info addr_r;
394
    struct nlattr *raddr, *laddr;
395
    struct mptcp_sock *msk;
396
-    struct sock *sk, *ssk;
397
    int err = -EINVAL;
398
+    struct sock *sk;
399
400
    if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR) ||
401
     GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
402
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
403
    }
404
405
    lock_sock(sk);
406
-    ssk = mptcp_nl_find_ssk(msk, &addr_l.addr, &addr_r);
407
-    if (!ssk) {
408
-        GENL_SET_ERR_MSG(info, "subflow not found");
409
-        err = -ESRCH;
410
-        goto release_sock;
411
-    }
412
-
413
-    spin_lock_bh(&msk->pm.lock);
414
-    mptcp_userspace_pm_delete_local_addr(msk, &addr_l);
415
-    spin_unlock_bh(&msk->pm.lock);
416
-    mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
417
-    mptcp_close_ssk(sk, ssk, mptcp_subflow_ctx(ssk));
418
-    MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
419
-release_sock:
420
+    err = userspace_pm_subflow_closed(msk, &addr_l, &addr_r);
421
    release_sock(sk);
422
+    if (err)
423
+        GENL_SET_ERR_MSG(info, "subflow not found");
424
425
destroy_err:
426
    sock_put(sk);
427
    return err;
428
}
429
430
+static int userspace_pm_set_priority(struct mptcp_sock *msk,
431
+                 struct mptcp_pm_addr_entry *local,
432
+                 struct mptcp_addr_info *remote)
433
+{
434
+    struct mptcp_pm_addr_entry *entry;
435
+    u8 bkup = 0;
436
+
437
+    if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
438
+        bkup = 1;
439
+
440
+    spin_lock_bh(&msk->pm.lock);
441
+    entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
442
+    if (entry) {
443
+        if (bkup)
444
+            entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
445
+        else
446
+            entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
447
+    }
448
+    spin_unlock_bh(&msk->pm.lock);
449
+
450
+    return mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, remote, bkup);
451
+}
452
+
453
int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
454
                 struct genl_info *info)
455
{
456
    struct mptcp_addr_info rem = { .family = AF_UNSPEC, };
457
-    struct mptcp_pm_addr_entry *entry;
458
    struct nlattr *attr, *attr_rem;
459
    struct mptcp_sock *msk;
460
    int ret = -EINVAL;
461
    struct sock *sk;
462
-    u8 bkup = 0;
463
464
    if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR_REMOTE))
465
        return ret;
466
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
467
        goto set_flags_err;
468
    }
469
470
-    if (local->flags & MPTCP_PM_ADDR_FLAG_BACKUP)
471
-        bkup = 1;
472
-
473
-    spin_lock_bh(&msk->pm.lock);
474
-    entry = mptcp_userspace_pm_lookup_addr(msk, &local->addr);
475
-    if (entry) {
476
-        if (bkup)
477
-            entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
478
-        else
479
-            entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
480
-    }
481
-    spin_unlock_bh(&msk->pm.lock);
482
-
483
    lock_sock(sk);
484
-    ret = mptcp_pm_nl_mp_prio_send_ack(msk, &local->addr, &rem, bkup);
485
+    ret = userspace_pm_set_priority(msk, local, &rem);
486
    release_sock(sk);
487
488
    /* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
489
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
490
    sock_put(sk);
491
    return ret;
492
}
493
+
494
+static struct mptcp_pm_ops mptcp_userspace_pm = {
495
+    .address_announced    = userspace_pm_address_announced,
496
+    .address_removed    = userspace_pm_address_removed,
497
+    .subflow_established    = userspace_pm_subflow_established,
498
+    .subflow_closed        = userspace_pm_subflow_closed,
499
+    .get_local_id        = userspace_pm_get_local_id,
500
+    .get_priority        = userspace_pm_get_priority,
501
+    .set_priority        = userspace_pm_set_priority,
502
+    .type            = MPTCP_PM_TYPE_USERSPACE,
503
+    .owner            = THIS_MODULE,
504
+};
505
+
506
+void __init mptcp_userspace_pm_init(void)
507
+{
508
+    mptcp_pm_register(&mptcp_userspace_pm);
509
+}
128
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
510
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
129
index XXXXXXX..XXXXXXX 100644
511
index XXXXXXX..XXXXXXX 100644
130
--- a/net/mptcp/protocol.h
512
--- a/net/mptcp/protocol.h
131
+++ b/net/mptcp/protocol.h
513
+++ b/net/mptcp/protocol.h
132
@@ -XXX,XX +XXX,XX @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
514
@@ -XXX,XX +XXX,XX @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
133
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
515
}
134
             struct mptcp_rm_list *rm_list);
516
135
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
517
void __init mptcp_pm_nl_init(void);
136
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
518
+void __init mptcp_userspace_pm_init(void);
137
-int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
519
void mptcp_pm_nl_work(struct mptcp_sock *msk);
138
+int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
520
unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
139
+             struct mptcp_pm_addr_entry *skc);
521
unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
140
+int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
141
+                 struct mptcp_pm_addr_entry *skc);
142
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
143
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
144
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
145
--
522
--
146
2.43.0
523
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
In mptcp_pm_nl_set_flags(), "entry" is copied to "local" when pernet->lock
3
Add a struct mptcp_pm_ops pointer "ops" in struct mptcp_pm_data, and two
4
is held to avoid direct access to entry without pernet->lock.
4
functions mptcp_pm_initialize() and mptcp_pm_release(), to set and release
5
5
this pointer. mptcp_pm_initialize() is invoked in mptcp_pm_data_reset(),
6
Therefore, "local->flags" should be passed to mptcp_nl_set_flags instead
6
while mptcp_pm_release() is invoked in __mptcp_destroy_sock().
7
of "entry->flags" when pernet->lock is not held, so as to avoid access to
7
8
entry.
8
In this way, different userspace path managers can be initialized through
9
the pm_type sysctl, and then called into their respective interfaces
10
through "ops" of "msk->pm".
9
11
10
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
12
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
11
---
13
---
12
net/mptcp/pm_netlink.c | 2 +-
14
net/mptcp/pm.c | 49 ++++++++++++++++++++++++++++++++++++++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
net/mptcp/pm_netlink.c | 11 ++++++++-
14
16
net/mptcp/pm_userspace.c | 28 +++++++++++++++++------
17
net/mptcp/protocol.c | 10 +++++++-
18
net/mptcp/protocol.h | 3 +++
19
5 files changed, 90 insertions(+), 11 deletions(-)
20
21
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/net/mptcp/pm.c
24
+++ b/net/mptcp/pm.c
25
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int
26
27
    WRITE_ONCE(pm->server_side, server_side);
28
    mptcp_event(MPTCP_EVENT_CREATED, msk, ssk, GFP_ATOMIC);
29
+
30
+    if (pm->ops && pm->ops->created)
31
+        pm->ops->created(msk);
32
}
33
34
bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
35
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk)
36
    msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
37
    spin_unlock_bh(&pm->lock);
38
39
-    if (announce)
40
+    if (announce) {
41
        mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, GFP_ATOMIC);
42
+
43
+        if (pm->ops && pm->ops->established)
44
+            pm->ops->established(msk);
45
+    }
46
}
47
48
void mptcp_pm_connection_closed(struct mptcp_sock *msk)
49
{
50
    pr_debug("msk=%p\n", msk);
51
52
-    if (msk->token)
53
+    if (msk->token) {
54
        mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);
55
+
56
+        if (msk->pm.ops && msk->pm.ops->closed)
57
+            msk->pm.ops->closed(msk);
58
+    }
59
}
60
61
void mptcp_pm_subflow_established(struct mptcp_sock *msk)
62
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
63
        WRITE_ONCE(pm->work_pending, 0);
64
        WRITE_ONCE(pm->accept_addr, 0);
65
        WRITE_ONCE(pm->accept_subflow, 0);
66
+
67
+        rcu_read_lock();
68
+        mptcp_pm_initialize(msk, mptcp_pm_find(pm_type));
69
+        rcu_read_unlock();
70
    }
71
72
    WRITE_ONCE(pm->addr_signal, 0);
73
@@ -XXX,XX +XXX,XX @@ void mptcp_pm_unregister(struct mptcp_pm_ops *pm)
74
    list_del_rcu(&pm->list);
75
    spin_unlock(&mptcp_pm_list_lock);
76
}
77
+
78
+int mptcp_pm_initialize(struct mptcp_sock *msk, struct mptcp_pm_ops *pm)
79
+{
80
+    if (!pm)
81
+        return -EINVAL;
82
+
83
+    if (!bpf_try_module_get(pm, pm->owner))
84
+        return -EBUSY;
85
+
86
+    msk->pm.ops = pm;
87
+    if (msk->pm.ops->init)
88
+        msk->pm.ops->init(msk);
89
+
90
+    pr_debug("userspace_pm type %u initialized\n", msk->pm.ops->type);
91
+    return 0;
92
+}
93
+
94
+void mptcp_pm_release(struct mptcp_sock *msk)
95
+{
96
+    struct mptcp_pm_ops *pm = msk->pm.ops;
97
+
98
+    if (!pm)
99
+        return;
100
+
101
+    msk->pm.ops = NULL;
102
+    if (pm->release)
103
+        pm->release(msk);
104
+
105
+    bpf_module_put(pm, pm->owner);
106
+}
15
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
107
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
16
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
17
--- a/net/mptcp/pm_netlink.c
109
--- a/net/mptcp/pm_netlink.c
18
+++ b/net/mptcp/pm_netlink.c
110
+++ b/net/mptcp/pm_netlink.c
19
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local,
111
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
20
    *local = *entry;
112
    int addrlen = sizeof(struct sockaddr_in);
21
    spin_unlock_bh(&pernet->lock);
113
    struct sockaddr_storage addr;
22
114
    struct sock *newsk, *ssk;
23
-    mptcp_nl_set_flags(net, &local->addr, entry->flags, changed);
115
+    struct mptcp_sock *msk;
24
+    mptcp_nl_set_flags(net, &local->addr, local->flags, changed);
116
    int backlog = 1024;
25
    return 0;
117
    int err;
26
}
118
119
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
120
                 is_ipv6 ? "msk_lock-AF_INET6" : "msk_lock-AF_INET",
121
                 &mptcp_keys[is_ipv6]);
122
123
+    msk = mptcp_sk(newsk);
124
    lock_sock(newsk);
125
-    ssk = __mptcp_nmpc_sk(mptcp_sk(newsk));
126
+    ssk = __mptcp_nmpc_sk(msk);
127
    release_sock(newsk);
128
    if (IS_ERR(ssk))
129
        return PTR_ERR(ssk);
130
@@ -XXX,XX +XXX,XX @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
131
    if (!err)
132
        mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
133
    release_sock(ssk);
134
+
135
+    if (!err) {
136
+        lock_sock(newsk);
137
+        if (msk->pm.ops && msk->pm.ops->listener_created)
138
+            msk->pm.ops->listener_created(msk);
139
+        release_sock(newsk);
140
+    }
141
    return err;
142
}
143
144
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/net/mptcp/pm_userspace.c
147
+++ b/net/mptcp/pm_userspace.c
148
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
149
    if (new_entry.addr.port == msk_sport)
150
        new_entry.addr.port = 0;
151
152
-    return userspace_pm_get_local_id(msk, &new_entry);
153
+    return msk->pm.ops && msk->pm.ops->get_local_id ?
154
+     msk->pm.ops->get_local_id(msk, &new_entry) :
155
+     userspace_pm_get_local_id(msk, &new_entry);
156
}
157
158
static bool userspace_pm_get_priority(struct mptcp_sock *msk,
159
@@ -XXX,XX +XXX,XX @@ static bool userspace_pm_get_priority(struct mptcp_sock *msk,
160
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
161
                 struct mptcp_addr_info *skc)
162
{
163
-    return userspace_pm_get_priority(msk, skc);
164
+    return msk->pm.ops && msk->pm.ops->get_priority ?
165
+     msk->pm.ops->get_priority(msk, skc) :
166
+     userspace_pm_get_priority(msk, skc);
167
}
168
169
static struct mptcp_sock *mptcp_userspace_pm_get_sock(const struct genl_info *info)
170
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
171
    }
172
173
    lock_sock(sk);
174
-    err = userspace_pm_address_announced(msk, &addr_val);
175
+    err = msk->pm.ops && msk->pm.ops->address_announced ?
176
+     msk->pm.ops->address_announced(msk, &addr_val) :
177
+     userspace_pm_address_announced(msk, &addr_val);
178
    release_sock(sk);
179
    if (err)
180
        NL_SET_ERR_MSG_ATTR(info->extack, addr,
181
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
182
    sk = (struct sock *)msk;
183
184
    lock_sock(sk);
185
-    err = userspace_pm_address_removed(msk, id_val);
186
+    err = msk->pm.ops && msk->pm.ops->address_removed ?
187
+     msk->pm.ops->address_removed(msk, id_val) :
188
+     userspace_pm_address_removed(msk, id_val);
189
    release_sock(sk);
190
    if (err)
191
        NL_SET_ERR_MSG_ATTR_FMT(info->extack, id,
192
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
193
    }
194
195
    lock_sock(sk);
196
-    err = userspace_pm_subflow_established(msk, &entry, &addr_r);
197
+    err = msk->pm.ops && msk->pm.ops->subflow_established ?
198
+     msk->pm.ops->subflow_established(msk, &entry, &addr_r) :
199
+     userspace_pm_subflow_established(msk, &entry, &addr_r);
200
    release_sock(sk);
201
202
    if (err)
203
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
204
    }
205
206
    lock_sock(sk);
207
-    err = userspace_pm_subflow_closed(msk, &addr_l, &addr_r);
208
+    err = msk->pm.ops && msk->pm.ops->subflow_closed ?
209
+     msk->pm.ops->subflow_closed(msk, &addr_l, &addr_r) :
210
+     userspace_pm_subflow_closed(msk, &addr_l, &addr_r);
211
    release_sock(sk);
212
    if (err)
213
        GENL_SET_ERR_MSG(info, "subflow not found");
214
@@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_set_flags(struct mptcp_pm_addr_entry *local,
215
    }
216
217
    lock_sock(sk);
218
-    ret = userspace_pm_set_priority(msk, local, &rem);
219
+    ret = msk->pm.ops && msk->pm.ops->set_priority ?
220
+     msk->pm.ops->set_priority(msk, local, &rem) :
221
+     userspace_pm_set_priority(msk, local, &rem);
222
    release_sock(sk);
223
224
    /* mptcp_pm_nl_mp_prio_send_ack() only fails in one case */
225
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/net/mptcp/protocol.c
228
+++ b/net/mptcp/protocol.c
229
@@ -XXX,XX +XXX,XX @@ static void __mptcp_destroy_sock(struct sock *sk)
230
    sk_stop_timer(sk, &sk->sk_timer);
231
    msk->pm.status = 0;
232
    mptcp_release_sched(msk);
233
+    mptcp_pm_release(msk);
234
235
    sk->sk_prot->destroy(sk);
236
237
@@ -XXX,XX +XXX,XX @@ static __poll_t mptcp_check_readable(struct sock *sk)
238
239
static void mptcp_check_listen_stop(struct sock *sk)
240
{
241
+    struct mptcp_sock *msk = mptcp_sk(sk);
242
    struct sock *ssk;
243
244
    if (inet_sk_state_load(sk) != TCP_LISTEN)
245
        return;
246
247
    sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
248
-    ssk = mptcp_sk(sk)->first;
249
+    ssk = msk->first;
250
    if (WARN_ON_ONCE(!ssk || inet_sk_state_load(ssk) != TCP_LISTEN))
251
        return;
252
253
@@ -XXX,XX +XXX,XX @@ static void mptcp_check_listen_stop(struct sock *sk)
254
    inet_csk_listen_stop(ssk);
255
    mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED);
256
    release_sock(ssk);
257
+
258
+    if (msk->pm.ops && msk->pm.ops->listener_closed)
259
+        msk->pm.ops->listener_closed(msk);
260
}
261
262
bool __mptcp_close(struct sock *sk, long timeout)
263
@@ -XXX,XX +XXX,XX @@ static int mptcp_listen(struct socket *sock, int backlog)
264
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
265
        mptcp_copy_inaddrs(sk, ssk);
266
        mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
267
+
268
+        if (msk->pm.ops && msk->pm.ops->listener_created)
269
+            msk->pm.ops->listener_created(msk);
270
    }
271
272
unlock:
273
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
274
index XXXXXXX..XXXXXXX 100644
275
--- a/net/mptcp/protocol.h
276
+++ b/net/mptcp/protocol.h
277
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_data {
278
    struct mptcp_addr_info remote;
279
    struct list_head anno_list;
280
    struct list_head userspace_pm_local_addr_list;
281
+    struct mptcp_pm_ops *ops;
282
283
    spinlock_t    lock;        /*protects the whole PM data */
284
285
@@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(enum mptcp_pm_type type);
286
int mptcp_pm_validate(struct mptcp_pm_ops *pm);
287
int mptcp_pm_register(struct mptcp_pm_ops *pm);
288
void mptcp_pm_unregister(struct mptcp_pm_ops *pm);
289
+int mptcp_pm_initialize(struct mptcp_sock *msk, struct mptcp_pm_ops *pm);
290
+void mptcp_pm_release(struct mptcp_sock *msk);
291
292
void mptcp_free_local_addr_list(struct mptcp_sock *msk);
27
293
28
--
294
--
29
2.43.0
295
2.43.0
diff view generated by jsdifflib
Deleted patch
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
1
3
Instead of using kmalloc() or kzalloc() to allocate an entry and
4
then immediately duplicate another entry to the newly allocated
5
one, kmemdup() helper can be used to simplify the code.
6
7
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
8
---
9
net/mptcp/pm_netlink.c | 6 ++----
10
1 file changed, 2 insertions(+), 4 deletions(-)
11
12
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/net/mptcp/pm_netlink.c
15
+++ b/net/mptcp/pm_netlink.c
16
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
17
        return ret;
18
19
    /* address not found, add to local list */
20
-    entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
21
+    entry = kmemdup(skc, sizeof(*skc), GFP_ATOMIC);
22
    if (!entry)
23
        return -ENOMEM;
24
25
-    *entry = *skc;
26
    entry->addr.port = 0;
27
    ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
28
    if (ret < 0)
29
@@ -XXX,XX +XXX,XX @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
30
        return -EINVAL;
31
    }
32
33
-    entry = kzalloc(sizeof(*entry), GFP_KERNEL_ACCOUNT);
34
+    entry = kmemdup(&addr, sizeof(addr), GFP_KERNEL_ACCOUNT);
35
    if (!entry) {
36
        GENL_SET_ERR_MSG(info, "can't allocate addr");
37
        return -ENOMEM;
38
    }
39
40
-    *entry = addr;
41
    if (entry->addr.port) {
42
        ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
43
        if (ret) {
44
--
45
2.43.0
diff view generated by jsdifflib
Deleted patch
1
From: Geliang Tang <tanggeliang@kylinos.cn>
2
1
3
Instead of using sock_kmalloc() to allocate an entry and then
4
immediately duplicate another entry to the newly allocated one,
5
sock_kmemdup() helper can be used to simplify the code.
6
7
More importantly, the code "*e = *entry;" that assigns "entry"
8
to "e" is not easy to implemented in BPF if we use the same code
9
to implement an append_new_local_addr() helper of a BFP path
10
manager. This patch avoids this type of memory assignment
11
operation.
12
13
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
14
---
15
net/mptcp/pm_userspace.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/net/mptcp/pm_userspace.c
21
+++ b/net/mptcp/pm_userspace.c
22
@@ -XXX,XX +XXX,XX @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
23
        /* Memory for the entry is allocated from the
24
         * sock option buffer.
25
         */
26
-        e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
27
+        e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC);
28
        if (!e) {
29
            ret = -ENOMEM;
30
            goto append_err;
31
        }
32
33
-        *e = *entry;
34
        if (!e->addr.id && needs_id)
35
            e->addr.id = find_next_zero_bit(id_bitmap,
36
                            MPTCP_PM_MAX_ADDR_ID + 1,
37
--
38
2.43.0
diff view generated by jsdifflib