diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:19:14 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:50:54 -0400 |
commit | bb97d31f5130d677644d9931ef38613d1164ec94 (patch) | |
tree | 879827671531cf7b1a4aaeb8958009294e01ba04 /net/ipv4/af_inet.c | |
parent | 087fe256f0aef8d16b19a30c6fb10b899bf1a701 (diff) |
[INET]: Make inet_create try to load protocol modules
Syntax is net-pf-PROTOCOL_FAMILY-PROTOCOL-SOCK_TYPE and if this
fails net-pf-PROTOCOL_FAMILY-PROTOCOL.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 52f5ecc58c46..20f52b5f5dea 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -228,12 +228,14 @@ static int inet_create(struct socket *sock, int protocol) | |||
228 | struct proto *answer_prot; | 228 | struct proto *answer_prot; |
229 | unsigned char answer_flags; | 229 | unsigned char answer_flags; |
230 | char answer_no_check; | 230 | char answer_no_check; |
231 | int err; | 231 | int try_loading_module = 0; |
232 | int err = -ESOCKTNOSUPPORT; | ||
232 | 233 | ||
233 | sock->state = SS_UNCONNECTED; | 234 | sock->state = SS_UNCONNECTED; |
234 | 235 | ||
235 | /* Look for the requested type/protocol pair. */ | 236 | /* Look for the requested type/protocol pair. */ |
236 | answer = NULL; | 237 | answer = NULL; |
238 | lookup_protocol: | ||
237 | rcu_read_lock(); | 239 | rcu_read_lock(); |
238 | list_for_each_rcu(p, &inetsw[sock->type]) { | 240 | list_for_each_rcu(p, &inetsw[sock->type]) { |
239 | answer = list_entry(p, struct inet_protosw, list); | 241 | answer = list_entry(p, struct inet_protosw, list); |
@@ -254,9 +256,28 @@ static int inet_create(struct socket *sock, int protocol) | |||
254 | answer = NULL; | 256 | answer = NULL; |
255 | } | 257 | } |
256 | 258 | ||
257 | err = -ESOCKTNOSUPPORT; | 259 | if (unlikely(answer == NULL)) { |
258 | if (!answer) | 260 | if (try_loading_module < 2) { |
259 | goto out_rcu_unlock; | 261 | rcu_read_unlock(); |
262 | /* | ||
263 | * Be more specific, e.g. net-pf-2-proto-132-type-1 | ||
264 | * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM) | ||
265 | */ | ||
266 | if (++try_loading_module == 1) | ||
267 | request_module("net-pf-%d-proto-%d-type-%d", | ||
268 | PF_INET, protocol, sock->type); | ||
269 | /* | ||
270 | * Fall back to generic, e.g. net-pf-2-proto-132 | ||
271 | * (net-pf-PF_INET-proto-IPPROTO_SCTP) | ||
272 | */ | ||
273 | else | ||
274 | request_module("net-pf-%d-proto-%d", | ||
275 | PF_INET, protocol); | ||
276 | goto lookup_protocol; | ||
277 | } else | ||
278 | goto out_rcu_unlock; | ||
279 | } | ||
280 | |||
260 | err = -EPERM; | 281 | err = -EPERM; |
261 | if (answer->capability > 0 && !capable(answer->capability)) | 282 | if (answer->capability > 0 && !capable(answer->capability)) |
262 | goto out_rcu_unlock; | 283 | goto out_rcu_unlock; |