From c7598217dc29f3e3a6739415d23b297d953ee20e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 14 Aug 2005 19:31:36 -0700 Subject: [PATCH] --- yaml --- r: 6367 b: refs/heads/master c: ab33a1711cf60bfb562b1ab89ac9f23d1425e8b1 h: refs/heads/master i: 6365: 6b33bbc020a2df4d0018fa3f3747286589059e4c 6363: 0c418c9fc757bf000b24de048fa5825d5882287d 6359: 1d94c542d45ecc70b0dee59995ffbcdc33103bff 6351: 8774c65da9fe2193db2ff2b2238a90eea7088488 6335: 0465be8886d7ea9c83c403c4eebe48f046617db9 v: v3 --- [refs] | 2 +- trunk/net/netlink/af_netlink.c | 72 +++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/[refs] b/[refs] index 91ed5e60d2d6..638859dea24b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ac6d439d2097b72ea0cbc2322ce1263a38bc1fd0 +refs/heads/master: ab33a1711cf60bfb562b1ab89ac9f23d1425e8b1 diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 3c56b96b4a4b..444ed223ee43 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -102,6 +102,7 @@ struct netlink_table { struct hlist_head mc_list; unsigned int nl_nonroot; struct module *module; + int registered; }; static struct netlink_table *nl_table; @@ -343,11 +344,32 @@ static struct proto netlink_proto = { .obj_size = sizeof(struct netlink_sock), }; -static int netlink_create(struct socket *sock, int protocol) +static int __netlink_create(struct socket *sock, int protocol) { struct sock *sk; struct netlink_sock *nlk; - struct module *module; + + sock->ops = &netlink_ops; + + sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); + if (!sk) + return -ENOMEM; + + sock_init_data(sock, sk); + + nlk = nlk_sk(sk); + spin_lock_init(&nlk->cb_lock); + init_waitqueue_head(&nlk->wait); + + sk->sk_destruct = netlink_sock_destruct; + sk->sk_protocol = protocol; + return 0; +} + +static int netlink_create(struct socket *sock, int protocol) +{ + struct module *module = NULL; + int err = 0; sock->state = SS_UNCONNECTED; @@ -358,41 +380,33 @@ static int netlink_create(struct socket *sock, int protocol) return -EPROTONOSUPPORT; netlink_lock_table(); - if (!nl_table[protocol].hash.entries) { #ifdef CONFIG_KMOD - /* We do 'best effort'. If we find a matching module, - * it is loaded. If not, we don't return an error to - * allow pure userspace<->userspace communication. -HW - */ + if (!nl_table[protocol].registered) { netlink_unlock_table(); request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); netlink_lock_table(); -#endif } - module = nl_table[protocol].module; - if (!try_module_get(module)) - module = NULL; +#endif + if (nl_table[protocol].registered && + try_module_get(nl_table[protocol].module)) + module = nl_table[protocol].module; + else + err = -EPROTONOSUPPORT; netlink_unlock_table(); - sock->ops = &netlink_ops; - - sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); - if (!sk) { - module_put(module); - return -ENOMEM; - } - - sock_init_data(sock, sk); + if (err) + goto out; - nlk = nlk_sk(sk); + if ((err = __netlink_create(sock, protocol) < 0)) + goto out_module; - nlk->module = module; - spin_lock_init(&nlk->cb_lock); - init_waitqueue_head(&nlk->wait); - sk->sk_destruct = netlink_sock_destruct; + nlk_sk(sock->sk)->module = module; +out: + return err; - sk->sk_protocol = protocol; - return 0; +out_module: + module_put(module); + goto out; } static int netlink_release(struct socket *sock) @@ -437,6 +451,7 @@ static int netlink_release(struct socket *sock) if (nlk->flags & NETLINK_KERNEL_SOCKET) { netlink_table_grab(); nl_table[sk->sk_protocol].module = NULL; + nl_table[sk->sk_protocol].registered = 0; netlink_table_ungrab(); } @@ -1082,7 +1097,7 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) return NULL; - if (netlink_create(sock, unit) < 0) + if (__netlink_create(sock, unit) < 0) goto out_sock_release; sk = sock->sk; @@ -1098,6 +1113,7 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct netlink_table_grab(); nl_table[unit].module = module; + nl_table[unit].registered = 1; netlink_table_ungrab(); return sk;