sock_diag: Move the sock_ code to net/core/
authorPavel Emelyanov <xemul@parallels.com>
Tue, 6 Dec 2011 07:59:52 +0000 (07:59 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 6 Dec 2011 18:58:02 +0000 (13:58 -0500)
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>
net/core/Makefile
net/core/sock_diag.c [new file with mode: 0644]
net/ipv4/inet_diag.c

index c4ecc864020f4f3f84c88bafab64d5c3a1e3db34..674641b13aea341257094fa4f070bd4289075d9b 100644 (file)
@@ -8,7 +8,8 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
 obj-y               += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
-                       neighbour.o rtnetlink.o utils.o link_watch.o filter.o
+                       neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
+                       sock_diag.o
 
 obj-$(CONFIG_XFRM) += flow.o
 obj-y += net-sysfs.o
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
new file mode 100644 (file)
index 0000000..fbaf01c
--- /dev/null
@@ -0,0 +1,150 @@
+#include <linux/mutex.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <net/netlink.h>
+#include <net/net_namespace.h>
+#include <linux/module.h>
+
+#include <linux/inet_diag.h>
+#include <linux/sock_diag.h>
+
+static struct sock_diag_handler *sock_diag_handlers[AF_MAX];
+static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh);
+static DEFINE_MUTEX(sock_diag_table_mutex);
+
+void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
+{
+       mutex_lock(&sock_diag_table_mutex);
+       inet_rcv_compat = fn;
+       mutex_unlock(&sock_diag_table_mutex);
+}
+EXPORT_SYMBOL_GPL(sock_diag_register_inet_compat);
+
+void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
+{
+       mutex_lock(&sock_diag_table_mutex);
+       inet_rcv_compat = NULL;
+       mutex_unlock(&sock_diag_table_mutex);
+}
+EXPORT_SYMBOL_GPL(sock_diag_unregister_inet_compat);
+
+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;
+}
+EXPORT_SYMBOL_GPL(sock_diag_register);
+
+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);
+}
+EXPORT_SYMBOL_GPL(sock_diag_unregister);
+
+static inline struct sock_diag_handler *sock_diag_lock_handler(int family)
+{
+       if (sock_diag_handlers[family] == NULL)
+               request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+                               NETLINK_SOCK_DIAG, IPPROTO_IP);
+
+       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)
+{
+       int ret;
+
+       switch (nlh->nlmsg_type) {
+       case TCPDIAG_GETSOCK:
+       case DCCPDIAG_GETSOCK:
+               if (inet_rcv_compat == NULL)
+                       request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+                                       NETLINK_SOCK_DIAG, IPPROTO_IP);
+
+               mutex_lock(&sock_diag_table_mutex);
+               if (inet_rcv_compat != NULL)
+                       ret = inet_rcv_compat(skb, nlh);
+               else
+                       ret = -EOPNOTSUPP;
+               mutex_unlock(&sock_diag_table_mutex);
+
+               return ret;
+       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);
+}
+
+struct sock *sock_diag_nlsk;
+EXPORT_SYMBOL_GPL(sock_diag_nlsk);
+
+static int __init sock_diag_init(void)
+{
+       sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, 0,
+                                       sock_diag_rcv, NULL, THIS_MODULE);
+       return sock_diag_nlsk == NULL ? -ENOMEM : 0;
+}
+
+static void __exit sock_diag_exit(void)
+{
+       netlink_kernel_release(sock_diag_nlsk);
+}
+
+module_init(sock_diag_init);
+module_exit(sock_diag_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_SOCK_DIAG);
index 515dc7b6daea4396acbf96ae45730c311c2c4a7f..b56b7ba8beeb40b9dadd6f7e0c2ffcf7d6da930f 100644 (file)
@@ -46,8 +46,6 @@ struct inet_diag_entry {
        u16 userlocks;
 };
 
-static struct sock *sdiagnl;
-
 #define INET_DIAG_PUT(skb, attrtype, attrlen) \
        RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
 
@@ -314,7 +312,7 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
                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 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
                                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 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
                                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 @@ static struct sock_diag_handler inet6_diag_handler = {
        .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 @@ static int __init inet_diag_init(void)
        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 @@ static int __init inet_diag_init(void)
        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 @@ static void __exit inet_diag_exit(void)
 {
        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);