hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/ipv4/tcp_ulp.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Pluggable TCP upper layer protocol support.
34 *
....@@ -6,7 +7,7 @@
67 *
78 */
89
9
-#include<linux/module.h>
10
+#include <linux/module.h>
1011 #include <linux/mm.h>
1112 #include <linux/types.h>
1213 #include <linux/list.h>
....@@ -21,20 +22,9 @@
2122 {
2223 struct tcp_ulp_ops *e;
2324
24
- list_for_each_entry_rcu(e, &tcp_ulp_list, list) {
25
+ list_for_each_entry_rcu(e, &tcp_ulp_list, list,
26
+ lockdep_is_held(&tcp_ulp_list_lock)) {
2527 if (strcmp(e->name, name) == 0)
26
- return e;
27
- }
28
-
29
- return NULL;
30
-}
31
-
32
-static struct tcp_ulp_ops *tcp_ulp_find_id(const int ulp)
33
-{
34
- struct tcp_ulp_ops *e;
35
-
36
- list_for_each_entry_rcu(e, &tcp_ulp_list, list) {
37
- if (e->uid == ulp)
3828 return e;
3929 }
4030
....@@ -59,18 +49,6 @@
5949 if (!ulp || !try_module_get(ulp->owner))
6050 ulp = NULL;
6151
62
- rcu_read_unlock();
63
- return ulp;
64
-}
65
-
66
-static const struct tcp_ulp_ops *__tcp_ulp_lookup(const int uid)
67
-{
68
- const struct tcp_ulp_ops *ulp;
69
-
70
- rcu_read_lock();
71
- ulp = tcp_ulp_find_id(uid);
72
- if (!ulp || !try_module_get(ulp->owner))
73
- ulp = NULL;
7452 rcu_read_unlock();
7553 return ulp;
7654 }
....@@ -115,14 +93,30 @@
11593 offs += snprintf(buf + offs, maxlen - offs,
11694 "%s%s",
11795 offs == 0 ? "" : " ", ulp_ops->name);
96
+
97
+ if (WARN_ON_ONCE(offs >= maxlen))
98
+ break;
11899 }
119100 rcu_read_unlock();
101
+}
102
+
103
+void tcp_update_ulp(struct sock *sk, struct proto *proto,
104
+ void (*write_space)(struct sock *sk))
105
+{
106
+ struct inet_connection_sock *icsk = inet_csk(sk);
107
+
108
+ if (icsk->icsk_ulp_ops->update)
109
+ icsk->icsk_ulp_ops->update(sk, proto, write_space);
120110 }
121111
122112 void tcp_cleanup_ulp(struct sock *sk)
123113 {
124114 struct inet_connection_sock *icsk = inet_csk(sk);
125115
116
+ /* No sock_owned_by_me() check here as at the time the
117
+ * stack calls this function, the socket is dead and
118
+ * about to be destroyed.
119
+ */
126120 if (!icsk->icsk_ulp_ops)
127121 return;
128122
....@@ -133,54 +127,39 @@
133127 icsk->icsk_ulp_ops = NULL;
134128 }
135129
136
-/* Change upper layer protocol for socket */
137
-int tcp_set_ulp(struct sock *sk, const char *name)
130
+static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
138131 {
139132 struct inet_connection_sock *icsk = inet_csk(sk);
140
- const struct tcp_ulp_ops *ulp_ops;
141
- int err = 0;
133
+ int err;
142134
135
+ err = -EEXIST;
143136 if (icsk->icsk_ulp_ops)
144
- return -EEXIST;
137
+ goto out_err;
138
+
139
+ err = -ENOTCONN;
140
+ if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
141
+ goto out_err;
142
+
143
+ err = ulp_ops->init(sk);
144
+ if (err)
145
+ goto out_err;
146
+
147
+ icsk->icsk_ulp_ops = ulp_ops;
148
+ return 0;
149
+out_err:
150
+ module_put(ulp_ops->owner);
151
+ return err;
152
+}
153
+
154
+int tcp_set_ulp(struct sock *sk, const char *name)
155
+{
156
+ const struct tcp_ulp_ops *ulp_ops;
157
+
158
+ sock_owned_by_me(sk);
145159
146160 ulp_ops = __tcp_ulp_find_autoload(name);
147161 if (!ulp_ops)
148162 return -ENOENT;
149163
150
- if (!ulp_ops->user_visible) {
151
- module_put(ulp_ops->owner);
152
- return -ENOENT;
153
- }
154
-
155
- err = ulp_ops->init(sk);
156
- if (err) {
157
- module_put(ulp_ops->owner);
158
- return err;
159
- }
160
-
161
- icsk->icsk_ulp_ops = ulp_ops;
162
- return 0;
163
-}
164
-
165
-int tcp_set_ulp_id(struct sock *sk, int ulp)
166
-{
167
- struct inet_connection_sock *icsk = inet_csk(sk);
168
- const struct tcp_ulp_ops *ulp_ops;
169
- int err;
170
-
171
- if (icsk->icsk_ulp_ops)
172
- return -EEXIST;
173
-
174
- ulp_ops = __tcp_ulp_lookup(ulp);
175
- if (!ulp_ops)
176
- return -ENOENT;
177
-
178
- err = ulp_ops->init(sk);
179
- if (err) {
180
- module_put(ulp_ops->owner);
181
- return err;
182
- }
183
-
184
- icsk->icsk_ulp_ops = ulp_ops;
185
- return 0;
164
+ return __tcp_set_ulp(sk, ulp_ops);
186165 }