aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c39
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);