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