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 | |
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>
-rw-r--r-- | net/dccp/proto.c | 9 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 29 | ||||
-rw-r--r-- | net/sctp/protocol.c | 4 |
3 files changed, 36 insertions, 6 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 70284e6afe05..66c43fce17a6 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -811,8 +811,13 @@ static void __exit dccp_fini(void) | |||
811 | module_init(dccp_init); | 811 | module_init(dccp_init); |
812 | module_exit(dccp_fini); | 812 | module_exit(dccp_fini); |
813 | 813 | ||
814 | /* __stringify doesn't likes enums, so use SOCK_DCCP (6) value directly */ | 814 | /* |
815 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-6"); | 815 | * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33) |
816 | * values directly, Also cover the case where the protocol is not specified, | ||
817 | * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP | ||
818 | */ | ||
819 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6"); | ||
820 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6"); | ||
816 | MODULE_LICENSE("GPL"); | 821 | MODULE_LICENSE("GPL"); |
817 | MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@conectiva.com.br>"); | 822 | MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@conectiva.com.br>"); |
818 | MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol"); | 823 | MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol"); |
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; |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 8d3f8096b873..7d8ec6526347 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1242,6 +1242,10 @@ SCTP_STATIC __exit void sctp_exit(void) | |||
1242 | module_init(sctp_init); | 1242 | module_init(sctp_init); |
1243 | module_exit(sctp_exit); | 1243 | module_exit(sctp_exit); |
1244 | 1244 | ||
1245 | /* | ||
1246 | * __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly. | ||
1247 | */ | ||
1248 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132"); | ||
1245 | MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>"); | 1249 | MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>"); |
1246 | MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)"); | 1250 | MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)"); |
1247 | MODULE_LICENSE("GPL"); | 1251 | MODULE_LICENSE("GPL"); |