diff options
Diffstat (limited to 'net/ipv4/tcp_ulp.c')
-rw-r--r-- | net/ipv4/tcp_ulp.c | 71 |
1 files changed, 13 insertions, 58 deletions
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c index 34e96353f115..a9162aa11af9 100644 --- a/net/ipv4/tcp_ulp.c +++ b/net/ipv4/tcp_ulp.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include<linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
@@ -29,18 +29,6 @@ static struct tcp_ulp_ops *tcp_ulp_find(const char *name) | |||
29 | return NULL; | 29 | return NULL; |
30 | } | 30 | } |
31 | 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) | ||
38 | return e; | ||
39 | } | ||
40 | |||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) | 32 | static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) |
45 | { | 33 | { |
46 | const struct tcp_ulp_ops *ulp = NULL; | 34 | const struct tcp_ulp_ops *ulp = NULL; |
@@ -63,18 +51,6 @@ static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) | |||
63 | return ulp; | 51 | return ulp; |
64 | } | 52 | } |
65 | 53 | ||
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; | ||
74 | rcu_read_unlock(); | ||
75 | return ulp; | ||
76 | } | ||
77 | |||
78 | /* Attach new upper layer protocol to the list | 54 | /* Attach new upper layer protocol to the list |
79 | * of available protocols. | 55 | * of available protocols. |
80 | */ | 56 | */ |
@@ -135,56 +111,35 @@ void tcp_cleanup_ulp(struct sock *sk) | |||
135 | icsk->icsk_ulp_ops = NULL; | 111 | icsk->icsk_ulp_ops = NULL; |
136 | } | 112 | } |
137 | 113 | ||
138 | /* Change upper layer protocol for socket */ | 114 | static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops) |
139 | int tcp_set_ulp(struct sock *sk, const char *name) | ||
140 | { | 115 | { |
141 | struct inet_connection_sock *icsk = inet_csk(sk); | 116 | struct inet_connection_sock *icsk = inet_csk(sk); |
142 | const struct tcp_ulp_ops *ulp_ops; | 117 | int err; |
143 | int err = 0; | ||
144 | 118 | ||
145 | sock_owned_by_me(sk); | 119 | err = -EEXIST; |
146 | if (icsk->icsk_ulp_ops) | 120 | if (icsk->icsk_ulp_ops) |
147 | return -EEXIST; | 121 | goto out_err; |
148 | |||
149 | ulp_ops = __tcp_ulp_find_autoload(name); | ||
150 | if (!ulp_ops) | ||
151 | return -ENOENT; | ||
152 | |||
153 | if (!ulp_ops->user_visible) { | ||
154 | module_put(ulp_ops->owner); | ||
155 | return -ENOENT; | ||
156 | } | ||
157 | 122 | ||
158 | err = ulp_ops->init(sk); | 123 | err = ulp_ops->init(sk); |
159 | if (err) { | 124 | if (err) |
160 | module_put(ulp_ops->owner); | 125 | goto out_err; |
161 | return err; | ||
162 | } | ||
163 | 126 | ||
164 | icsk->icsk_ulp_ops = ulp_ops; | 127 | icsk->icsk_ulp_ops = ulp_ops; |
165 | return 0; | 128 | return 0; |
129 | out_err: | ||
130 | module_put(ulp_ops->owner); | ||
131 | return err; | ||
166 | } | 132 | } |
167 | 133 | ||
168 | int tcp_set_ulp_id(struct sock *sk, int ulp) | 134 | int tcp_set_ulp(struct sock *sk, const char *name) |
169 | { | 135 | { |
170 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
171 | const struct tcp_ulp_ops *ulp_ops; | 136 | const struct tcp_ulp_ops *ulp_ops; |
172 | int err; | ||
173 | 137 | ||
174 | sock_owned_by_me(sk); | 138 | sock_owned_by_me(sk); |
175 | if (icsk->icsk_ulp_ops) | ||
176 | return -EEXIST; | ||
177 | 139 | ||
178 | ulp_ops = __tcp_ulp_lookup(ulp); | 140 | ulp_ops = __tcp_ulp_find_autoload(name); |
179 | if (!ulp_ops) | 141 | if (!ulp_ops) |
180 | return -ENOENT; | 142 | return -ENOENT; |
181 | 143 | ||
182 | err = ulp_ops->init(sk); | 144 | return __tcp_set_ulp(sk, ulp_ops); |
183 | if (err) { | ||
184 | module_put(ulp_ops->owner); | ||
185 | return err; | ||
186 | } | ||
187 | |||
188 | icsk->icsk_ulp_ops = ulp_ops; | ||
189 | return 0; | ||
190 | } | 145 | } |