sock_diag: Move the sock_ code to net/core/

This patch moves the sock_ code from inet_diag.c to generic sock_diag.c
file and provides necessary request_module-s calls and a pointer on
inet_diag_compat dumping routine.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 515dc7b..b56b7ba 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -46,8 +46,6 @@
 	u16 userlocks;
 };
 
-static struct sock *sdiagnl;
-
 #define INET_DIAG_PUT(skb, attrtype, attrlen) \
 	RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
 
@@ -314,7 +312,7 @@
 		kfree_skb(rep);
 		goto out;
 	}
-	err = netlink_unicast(sdiagnl, rep, NETLINK_CB(in_skb).pid,
+	err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid,
 			      MSG_DONTWAIT);
 	if (err > 0)
 		err = 0;
@@ -931,7 +929,7 @@
 				return -EINVAL;
 		}
 
-		return netlink_dump_start(sdiagnl, skb, nlh,
+		return netlink_dump_start(sock_diag_nlsk, skb, nlh,
 					  inet_diag_dump_compat, NULL, 0);
 	}
 
@@ -956,7 +954,7 @@
 				return -EINVAL;
 		}
 
-		return netlink_dump_start(sdiagnl, skb, h,
+		return netlink_dump_start(sock_diag_nlsk, skb, h,
 					  inet_diag_dump, NULL, 0);
 	}
 
@@ -973,91 +971,6 @@
 	.dump = inet_diag_handler_dump,
 };
 
-static struct sock_diag_handler *sock_diag_handlers[AF_MAX];
-static DEFINE_MUTEX(sock_diag_table_mutex);
-
-int sock_diag_register(struct sock_diag_handler *hndl)
-{
-	int err = 0;
-
-	if (hndl->family > AF_MAX)
-		return -EINVAL;
-
-	mutex_lock(&sock_diag_table_mutex);
-	if (sock_diag_handlers[hndl->family])
-		err = -EBUSY;
-	else
-		sock_diag_handlers[hndl->family] = hndl;
-	mutex_unlock(&sock_diag_table_mutex);
-
-	return err;
-}
-
-void sock_diag_unregister(struct sock_diag_handler *hnld)
-{
-	int family = hnld->family;
-
-	if (family > AF_MAX)
-		return;
-
-	mutex_lock(&sock_diag_table_mutex);
-	BUG_ON(sock_diag_handlers[family] != hnld);
-	sock_diag_handlers[family] = NULL;
-	mutex_unlock(&sock_diag_table_mutex);
-}
-
-static inline struct sock_diag_handler *sock_diag_lock_handler(int family)
-{
-	mutex_lock(&sock_diag_table_mutex);
-	return sock_diag_handlers[family];
-}
-
-static inline void sock_diag_unlock_handler(struct sock_diag_handler *h)
-{
-	mutex_unlock(&sock_diag_table_mutex);
-}
-
-static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
-{
-	int err;
-	struct sock_diag_req *req = NLMSG_DATA(nlh);
-	struct sock_diag_handler *hndl;
-
-	if (nlmsg_len(nlh) < sizeof(*req))
-		return -EINVAL;
-
-	hndl = sock_diag_lock_handler(req->sdiag_family);
-	if (hndl == NULL)
-		err = -ENOENT;
-	else
-		err = hndl->dump(skb, nlh);
-	sock_diag_unlock_handler(hndl);
-
-	return err;
-}
-
-static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
-{
-	switch (nlh->nlmsg_type) {
-	case TCPDIAG_GETSOCK:
-	case DCCPDIAG_GETSOCK:
-		return inet_diag_rcv_msg_compat(skb, nlh);
-	case SOCK_DIAG_BY_FAMILY:
-		return __sock_diag_rcv_msg(skb, nlh);
-	default:
-		return -EINVAL;
-	}
-}
-
-static DEFINE_MUTEX(sock_diag_mutex);
-
-static void sock_diag_rcv(struct sk_buff *skb)
-{
-	mutex_lock(&sock_diag_mutex);
-	netlink_rcv_skb(skb, &sock_diag_rcv_msg);
-	mutex_unlock(&sock_diag_mutex);
-}
-
 int inet_diag_register(const struct inet_diag_handler *h)
 {
 	const __u16 type = h->idiag_type;
@@ -1101,11 +1014,6 @@
 	if (!inet_diag_table)
 		goto out;
 
-	sdiagnl = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, 0,
-					sock_diag_rcv, NULL, THIS_MODULE);
-	if (sdiagnl == NULL)
-		goto out_free_table;
-
 	err = sock_diag_register(&inet_diag_handler);
 	if (err)
 		goto out_free_nl;
@@ -1114,14 +1022,13 @@
 	if (err)
 		goto out_free_inet;
 
+	sock_diag_register_inet_compat(inet_diag_rcv_msg_compat);
 out:
 	return err;
 
 out_free_inet:
 	sock_diag_unregister(&inet_diag_handler);
 out_free_nl:
-	netlink_kernel_release(sdiagnl);
-out_free_table:
 	kfree(inet_diag_table);
 	goto out;
 }
@@ -1130,11 +1037,11 @@
 {
 	sock_diag_unregister(&inet6_diag_handler);
 	sock_diag_unregister(&inet_diag_handler);
-	netlink_kernel_release(sdiagnl);
+	sock_diag_unregister_inet_compat(inet_diag_rcv_msg_compat);
 	kfree(inet_diag_table);
 }
 
 module_init(inet_diag_init);
 module_exit(inet_diag_exit);
 MODULE_LICENSE("GPL");
-MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_SOCK_DIAG);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 0);