[INET]: Make inet_create try to load protocol modules
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>
Wed, 10 Aug 2005 03:19:14 +0000 (20:19 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 29 Aug 2005 22:50:54 +0000 (15:50 -0700)
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>
net/dccp/proto.c
net/ipv4/af_inet.c
net/sctp/protocol.c

index 70284e6afe05cda3df8b83cd2dccd502f8b838af..66c43fce17a6c579b7e03bc90bf5ff384a42a804 100644 (file)
@@ -811,8 +811,13 @@ static void __exit dccp_fini(void)
 module_init(dccp_init);
 module_exit(dccp_fini);
 
-/* __stringify doesn't likes enums, so use SOCK_DCCP (6) value directly  */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-6");
+/*
+ * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@conectiva.com.br>");
 MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
index 52f5ecc58c461670034600e421a1a8569a8e5350..20f52b5f5dea165ef8bb28b01332573b0dfe5c02 100644 (file)
@@ -228,12 +228,14 @@ static int inet_create(struct socket *sock, int protocol)
        struct proto *answer_prot;
        unsigned char answer_flags;
        char answer_no_check;
-       int err;
+       int try_loading_module = 0;
+       int err = -ESOCKTNOSUPPORT;
 
        sock->state = SS_UNCONNECTED;
 
        /* Look for the requested type/protocol pair. */
        answer = NULL;
+lookup_protocol:
        rcu_read_lock();
        list_for_each_rcu(p, &inetsw[sock->type]) {
                answer = list_entry(p, struct inet_protosw, list);
@@ -254,9 +256,28 @@ static int inet_create(struct socket *sock, int protocol)
                answer = NULL;
        }
 
-       err = -ESOCKTNOSUPPORT;
-       if (!answer)
-               goto out_rcu_unlock;
+       if (unlikely(answer == NULL)) {
+               if (try_loading_module < 2) {
+                       rcu_read_unlock();
+                       /*
+                        * Be more specific, e.g. net-pf-2-proto-132-type-1
+                        * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM)
+                        */
+                       if (++try_loading_module == 1)
+                               request_module("net-pf-%d-proto-%d-type-%d",
+                                              PF_INET, protocol, sock->type);
+                       /*
+                        * Fall back to generic, e.g. net-pf-2-proto-132
+                        * (net-pf-PF_INET-proto-IPPROTO_SCTP)
+                        */
+                       else
+                               request_module("net-pf-%d-proto-%d",
+                                              PF_INET, protocol);
+                       goto lookup_protocol;
+               } else
+                       goto out_rcu_unlock;
+       }
+
        err = -EPERM;
        if (answer->capability > 0 && !capable(answer->capability))
                goto out_rcu_unlock;
index 8d3f8096b8735e307bff00ab5c5befe6fac18212..7d8ec65263474881934d31ca9ccc6a314391e597 100644 (file)
@@ -1242,6 +1242,10 @@ SCTP_STATIC __exit void sctp_exit(void)
 module_init(sctp_init);
 module_exit(sctp_exit);
 
+/*
+ * __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly.
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132");
 MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");
 MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");
 MODULE_LICENSE("GPL");