diff options
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 65f1a89ac6dea..1d5905c90cd4b 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -321,6 +321,12 @@ static void netlink_remove(struct sock *sk) netlink_table_ungrab(); } +static struct proto netlink_proto = { + .name = "NETLINK", + .owner = THIS_MODULE, + .obj_size = sizeof(struct netlink_sock), +}; + static int netlink_create(struct socket *sock, int protocol) { struct sock *sk; @@ -336,13 +342,11 @@ static int netlink_create(struct socket *sock, int protocol) sock->ops = &netlink_ops; - sk = sk_alloc(PF_NETLINK, GFP_KERNEL, - sizeof(struct netlink_sock), NULL); + sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); if (!sk) return -ENOMEM; - sock_init_data(sock,sk); - sk_set_owner(sk, THIS_MODULE); + sock_init_data(sock, sk); nlk = nlk_sk(sk); @@ -558,13 +562,12 @@ static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) struct sock *netlink_getsockbyfilp(struct file *filp) { struct inode *inode = filp->f_dentry->d_inode; - struct socket *socket; struct sock *sock; - if (!inode->i_sock || !(socket = SOCKET_I(inode))) + if (!S_ISSOCK(inode->i_mode)) return ERR_PTR(-ENOTSOCK); - sock = socket->sk; + sock = SOCKET_I(inode)->sk; if (sock->sk_family != AF_NETLINK) return ERR_PTR(-EINVAL); @@ -1080,11 +1083,9 @@ static int netlink_dump(struct sock *sk) len = cb->dump(skb, cb); if (len > 0) { - sock_hold(sk); spin_unlock(&nlk->cb_lock); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, len); - sock_put(sk); return 0; } @@ -1099,7 +1100,7 @@ static int netlink_dump(struct sock *sk) spin_unlock(&nlk->cb_lock); netlink_destroy_callback(cb); - sock_put(sk); + __sock_put(sk); return 0; } @@ -1138,9 +1139,11 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, return -EBUSY; } nlk->cb = cb; + sock_hold(sk); spin_unlock(&nlk->cb_lock); netlink_dump(sk); + sock_put(sk); return 0; } @@ -1369,6 +1372,10 @@ static int __init netlink_proto_init(void) int i; unsigned long max; unsigned int order; + int err = proto_register(&netlink_proto, 0); + + if (err != 0) + goto out; if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) netlink_skb_parms_too_large(); @@ -1415,15 +1422,17 @@ enomem: #endif /* The netlink device handler may be needed early. */ rtnetlink_init(); - return 0; +out: + return err; } static void __exit netlink_proto_exit(void) { - sock_unregister(PF_NETLINK); - proc_net_remove("netlink"); - kfree(nl_table); - nl_table = NULL; + sock_unregister(PF_NETLINK); + proc_net_remove("netlink"); + kfree(nl_table); + nl_table = NULL; + proto_unregister(&netlink_proto); } core_initcall(netlink_proto_init); |