netlink: add netlink_kernel_cfg parameter to netlink_kernel_create
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 29 Jun 2012 06:15:21 +0000 (06:15 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 29 Jun 2012 23:46:02 +0000 (16:46 -0700)
This patch adds the following structure:

struct netlink_kernel_cfg {
        unsigned int    groups;
        void            (*input)(struct sk_buff *skb);
        struct mutex    *cb_mutex;
};

That can be passed to netlink_kernel_create to set optional configurations
for netlink kernel sockets.

I've populated this structure by looking for NULL and zero parameters at the
existing code. The remaining parameters that always need to be set are still
left in the original interface.

That includes optional parameters for the netlink socket creation. This allows
easy extensibility of this interface in the future.

This patch also adapts all callers to use this new interface.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
20 files changed:
crypto/crypto_user.c
drivers/connector/connector.c
drivers/infiniband/core/netlink.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_transport_iscsi.c
drivers/staging/gdm72xx/netlink_k.c
include/linux/netlink.h
kernel/audit.c
lib/kobject_uevent.c
net/bridge/netfilter/ebt_ulog.c
net/core/rtnetlink.c
net/core/sock_diag.c
net/decnet/netfilter/dn_rtmsg.c
net/ipv4/fib_frontend.c
net/ipv4/netfilter/ipt_ULOG.c
net/netfilter/nfnetlink.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/xfrm/xfrm_user.c
security/selinux/netlink.c

index 5a37eadb4e56da5c922bab5167a295432e3cca3a..ba2c611154af5e0df373a04b22eed782da0daac5 100644 (file)
@@ -496,9 +496,12 @@ static void crypto_netlink_rcv(struct sk_buff *skb)
 
 static int __init crypto_user_init(void)
 {
+       struct netlink_kernel_cfg cfg = {
+               .input  = crypto_netlink_rcv,
+       };
+
        crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO,
-                                           0, crypto_netlink_rcv,
-                                           NULL, THIS_MODULE);
+                                           THIS_MODULE, &cfg);
        if (!crypto_nlsk)
                return -ENOMEM;
 
index 34e0e9e4d9130b4f46999f52e196e42eced5fc3f..116cf8d02834955409e1d14499846532217ff93b 100644 (file)
@@ -251,15 +251,20 @@ static const struct file_operations cn_file_ops = {
        .release = single_release
 };
 
+static struct cn_dev cdev = {
+       .input   = cn_rx_skb,
+};
+
 static int __devinit cn_init(void)
 {
        struct cn_dev *dev = &cdev;
-
-       dev->input = cn_rx_skb;
+       struct netlink_kernel_cfg cfg = {
+               .groups = CN_NETLINK_USERS + 0xf,
+               .input  = dev->input,
+       };
 
        dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
-                                        CN_NETLINK_USERS + 0xf,
-                                        dev->input, NULL, THIS_MODULE);
+                                        THIS_MODULE, &cfg);
        if (!dev->nls)
                return -EIO;
 
index 1e691dca1820d91e8d028aa7f029ad8b0f24b0de..3ae2bfd310158d58dd6051961358010947070fdd 100644 (file)
@@ -173,8 +173,11 @@ static void ibnl_rcv(struct sk_buff *skb)
 
 int __init ibnl_init(void)
 {
-       nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv,
-                                   NULL, THIS_MODULE);
+       struct netlink_kernel_cfg cfg = {
+               .input  = ibnl_rcv,
+       };
+
+       nls = netlink_kernel_create(&init_net, NETLINK_RDMA, THIS_MODULE, &cfg);
        if (!nls) {
                pr_warn("Failed to create netlink socket\n");
                return -ENOMEM;
index c77628afbf9f3e4dbb53c76e6ccf30b054b0f28a..8818dd681c194a445ea937c6f1e4b0dd70efff5f 100644 (file)
@@ -486,6 +486,10 @@ void
 scsi_netlink_init(void)
 {
        int error;
+       struct netlink_kernel_cfg cfg = {
+               .input  = scsi_nl_rcv_msg,
+               .groups = SCSI_NL_GRP_CNT,
+       };
 
        INIT_LIST_HEAD(&scsi_nl_drivers);
 
@@ -497,8 +501,7 @@ scsi_netlink_init(void)
        }
 
        scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
-                               SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL,
-                               THIS_MODULE);
+                                            THIS_MODULE, &cfg);
        if (!scsi_nl_sock) {
                printk(KERN_ERR "%s: register of receive handler failed\n",
                                __func__);
index 1cf640e575da4567fb22516bc5eff3cf3ff0efe9..6042954d8f3b2880b9976993ab5ef5183ee277b5 100644 (file)
@@ -2936,7 +2936,10 @@ EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
 static __init int iscsi_transport_init(void)
 {
        int err;
-
+       struct netlink_kernel_cfg cfg = {
+               .groups = 1,
+               .input  = iscsi_if_rx,
+       };
        printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
                ISCSI_TRANSPORT_VERSION);
 
@@ -2966,8 +2969,8 @@ static __init int iscsi_transport_init(void)
        if (err)
                goto unregister_conn_class;
 
-       nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx,
-                                   NULL, THIS_MODULE);
+       nls = netlink_kernel_create(&init_net, NETLINK_ISCSI,
+                                   THIS_MODULE, &cfg);
        if (!nls) {
                err = -ENOBUFS;
                goto unregister_session_class;
index 2489bb5597ca1c154494358b7cd862f9f0cfc88a..87c3a07ed80e2cdabb2a0bf56bd019bec707f408 100644 (file)
@@ -88,13 +88,15 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
                                                void *msg, int len))
 {
        struct sock *sock;
+       struct netlink_kernel_cfg cfg = {
+               .input  = netlink_rcv,
+       };
 
 #if !defined(DEFINE_MUTEX)
        init_MUTEX(&netlink_mutex);
 #endif
 
-       sock = netlink_kernel_create(&init_net, unit, 0, netlink_rcv, NULL,
-                                       THIS_MODULE);
+       sock = netlink_kernel_create(&init_net, unit, THIS_MODULE, &cfg);
 
        if (sock)
                rcv_cb = cb;
index ed33f0901bc22d833d7c4cb4e97060e206ae9dbe..6085e4919cb3678feb0f203a504bdcc8d1f88977 100644 (file)
@@ -174,11 +174,16 @@ struct netlink_skb_parms {
 extern void netlink_table_grab(void);
 extern void netlink_table_ungrab(void);
 
-extern struct sock *netlink_kernel_create(struct net *net,
-                                         int unit,unsigned int groups,
-                                         void (*input)(struct sk_buff *skb),
-                                         struct mutex *cb_mutex,
-                                         struct module *module);
+/* optional Netlink kernel configuration parameters */
+struct netlink_kernel_cfg {
+       unsigned int    groups;
+       void            (*input)(struct sk_buff *skb);
+       struct mutex    *cb_mutex;
+};
+
+extern struct sock *netlink_kernel_create(struct net *net, int unit,
+                                         struct module *module,
+                                         struct netlink_kernel_cfg *cfg);
 extern void netlink_kernel_release(struct sock *sk);
 extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
index 30b252a1fb61f54408262cc710ef1ee9f6ca9c5e..4a3f28d2ca65239db79eee58b0e85366aa98669f 100644 (file)
@@ -962,14 +962,17 @@ static void audit_receive(struct sk_buff  *skb)
 static int __init audit_init(void)
 {
        int i;
+       struct netlink_kernel_cfg cfg = {
+               .input  = audit_receive,
+       };
 
        if (audit_initialized == AUDIT_DISABLED)
                return 0;
 
        printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
               audit_default ? "enabled" : "disabled");
-       audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
-                                          audit_receive, NULL, THIS_MODULE);
+       audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT,
+                                          THIS_MODULE, &cfg);
        if (!audit_sock)
                audit_panic("cannot initialize netlink socket");
        else
index 1a91efa6d12133321f1e478421f72fceb6fdcad2..0401d2916d9fa25515540c0483dd486adaddc858 100644 (file)
@@ -373,13 +373,16 @@ EXPORT_SYMBOL_GPL(add_uevent_var);
 static int uevent_net_init(struct net *net)
 {
        struct uevent_sock *ue_sk;
+       struct netlink_kernel_cfg cfg = {
+               .groups = 1,
+       };
 
        ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
        if (!ue_sk)
                return -ENOMEM;
 
        ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT,
-                                         1, NULL, NULL, THIS_MODULE);
+                                         THIS_MODULE, &cfg);
        if (!ue_sk->sk) {
                printk(KERN_ERR
                       "kobject_uevent: unable to create netlink socket!\n");
index 1bd173218f7b8bd6d164adabd9d48f204aa6a292..374bdcd77039339e794fb45687af59f6133912c5 100644 (file)
@@ -282,6 +282,9 @@ static int __init ebt_ulog_init(void)
 {
        int ret;
        int i;
+       struct netlink_kernel_cfg cfg = {
+               .groups = EBT_ULOG_MAXNLGROUPS,
+       };
 
        if (nlbufsiz >= 128*1024) {
                pr_warning("Netlink buffer has to be <= 128kB,"
@@ -296,8 +299,7 @@ static int __init ebt_ulog_init(void)
        }
 
        ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
-                                         EBT_ULOG_MAXNLGROUPS, NULL, NULL,
-                                         THIS_MODULE);
+                                         THIS_MODULE, &cfg);
        if (!ebtulognl)
                ret = -ENOMEM;
        else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0)
index bc8a1cdaac9819561d59e4c3e14a5bd4177335c9..2b325c340b446c13fbe4ce15991678fc9fe327bd 100644 (file)
@@ -2353,8 +2353,13 @@ static struct notifier_block rtnetlink_dev_notifier = {
 static int __net_init rtnetlink_net_init(struct net *net)
 {
        struct sock *sk;
-       sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
-                                  rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
+       struct netlink_kernel_cfg cfg = {
+               .groups         = RTNLGRP_MAX,
+               .input          = rtnetlink_rcv,
+               .cb_mutex       = &rtnl_mutex,
+       };
+
+       sk = netlink_kernel_create(net, NETLINK_ROUTE, THIS_MODULE, &cfg);
        if (!sk)
                return -ENOMEM;
        net->rtnl = sk;
index ff2967acbfae021a1a0683e91cb226be7fb6d55e..07a29eb34a415d81bb3571a0f17cf3b070ac3f39 100644 (file)
@@ -171,8 +171,12 @@ 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);
+       struct netlink_kernel_cfg cfg = {
+               .input  = sock_diag_rcv,
+       };
+
+       sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG,
+                                              THIS_MODULE, &cfg);
        return sock_diag_nlsk == NULL ? -ENOMEM : 0;
 }
 
index b8f7f5b8c3509b57e6c850d590df4c52f9f60c3a..11db0ecf342ff2f32901acdb24836055ca0e383c 100644 (file)
@@ -125,11 +125,13 @@ static struct nf_hook_ops dnrmg_ops __read_mostly = {
 static int __init dn_rtmsg_init(void)
 {
        int rv = 0;
+       struct netlink_kernel_cfg cfg = {
+               .groups = DNRNG_NLGRP_MAX,
+               .input  = dnrmg_receive_user_skb,
+       };
 
        dnrmg = netlink_kernel_create(&init_net,
-                                     NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
-                                     dnrmg_receive_user_skb,
-                                     NULL, THIS_MODULE);
+                                     NETLINK_DNRTMSG, THIS_MODULE, &cfg);
        if (dnrmg == NULL) {
                printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
                return -ENOMEM;
index ae528d1b293ab34dd54f021e33b612158731619c..3e11ea225dad8e946e59f9d8de5200ab4e5a02ec 100644 (file)
@@ -976,8 +976,11 @@ static void nl_fib_input(struct sk_buff *skb)
 static int __net_init nl_fib_lookup_init(struct net *net)
 {
        struct sock *sk;
-       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0,
-                                  nl_fib_input, NULL, THIS_MODULE);
+       struct netlink_kernel_cfg cfg = {
+               .input  = nl_fib_input,
+       };
+
+       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, THIS_MODULE, &cfg);
        if (sk == NULL)
                return -EAFNOSUPPORT;
        net->ipv4.fibnl = sk;
index 99b3f53f16a7259134833cabc9e1de17e5462d6c..1109f7f6c25433d64515180eb6c9ff599dcef0f0 100644 (file)
@@ -381,6 +381,9 @@ static struct nf_logger ipt_ulog_logger __read_mostly = {
 static int __init ulog_tg_init(void)
 {
        int ret, i;
+       struct netlink_kernel_cfg cfg = {
+               .groups = ULOG_MAXNLGROUPS,
+       };
 
        pr_debug("init module\n");
 
@@ -393,9 +396,8 @@ static int __init ulog_tg_init(void)
        for (i = 0; i < ULOG_MAXNLGROUPS; i++)
                setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
 
-       nflognl = netlink_kernel_create(&init_net,
-                                       NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
-                                       NULL, THIS_MODULE);
+       nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
+                                       THIS_MODULE, &cfg);
        if (!nflognl)
                return -ENOMEM;
 
index 3e797d1fcb94272ad96b9798e91a6e6467031379..700e4616a098385b5213dbd0ddb8212baabd289f 100644 (file)
@@ -203,9 +203,12 @@ static void nfnetlink_rcv(struct sk_buff *skb)
 static int __net_init nfnetlink_net_init(struct net *net)
 {
        struct sock *nfnl;
+       struct netlink_kernel_cfg cfg = {
+               .groups = NFNLGRP_MAX,
+               .input  = nfnetlink_rcv,
+       };
 
-       nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, NFNLGRP_MAX,
-                                    nfnetlink_rcv, NULL, THIS_MODULE);
+       nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, THIS_MODULE, &cfg);
        if (!nfnl)
                return -ENOMEM;
        net->nfnl_stash = nfnl;
index b3025a603d56b21f1529262025cc2d6f00993cc9..43a124feaad88908948a19d2d7a07cb9b69f34de 100644 (file)
@@ -1503,14 +1503,16 @@ static void netlink_data_ready(struct sock *sk, int len)
  */
 
 struct sock *
-netlink_kernel_create(struct net *net, int unit, unsigned int groups,
-                     void (*input)(struct sk_buff *skb),
-                     struct mutex *cb_mutex, struct module *module)
+netlink_kernel_create(struct net *net, int unit,
+                     struct module *module,
+                     struct netlink_kernel_cfg *cfg)
 {
        struct socket *sock;
        struct sock *sk;
        struct netlink_sock *nlk;
        struct listeners *listeners = NULL;
+       struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL;
+       unsigned int groups;
 
        BUG_ON(!nl_table);
 
@@ -1532,16 +1534,18 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
        sk = sock->sk;
        sk_change_net(sk, net);
 
-       if (groups < 32)
+       if (!cfg || cfg->groups < 32)
                groups = 32;
+       else
+               groups = cfg->groups;
 
        listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
        if (!listeners)
                goto out_sock_release;
 
        sk->sk_data_ready = netlink_data_ready;
-       if (input)
-               nlk_sk(sk)->netlink_rcv = input;
+       if (cfg && cfg->input)
+               nlk_sk(sk)->netlink_rcv = cfg->input;
 
        if (netlink_insert(sk, net, 0))
                goto out_sock_release;
index 2cc7c1ee769046c1b45ce677caa6f8dac3e4a1ff..32761b53015eaec4057f9b8e8aeb2312d6e1a0f2 100644 (file)
@@ -915,10 +915,14 @@ static struct genl_multicast_group notify_grp = {
 
 static int __net_init genl_pernet_init(struct net *net)
 {
+       struct netlink_kernel_cfg cfg = {
+               .input          = genl_rcv,
+               .cb_mutex       = &genl_mutex,
+       };
+
        /* we'll bump the group number right afterwards */
-       net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0,
-                                              genl_rcv, &genl_mutex,
-                                              THIS_MODULE);
+       net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC,
+                                              THIS_MODULE, &cfg);
 
        if (!net->genl_sock && net_eq(net, &init_net))
                panic("GENL: Cannot initialize generic netlink\n");
index 540762726aaf4cc24aabf8e0c05d76c868f2a25b..e75d8e47f35cab2bdddd1051e6da556ef20eb26c 100644 (file)
@@ -2959,9 +2959,12 @@ static struct xfrm_mgr netlink_mgr = {
 static int __net_init xfrm_user_net_init(struct net *net)
 {
        struct sock *nlsk;
+       struct netlink_kernel_cfg cfg = {
+               .groups = XFRMNLGRP_MAX,
+               .input  = xfrm_netlink_rcv,
+       };
 
-       nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX,
-                                    xfrm_netlink_rcv, NULL, THIS_MODULE);
+       nlsk = netlink_kernel_create(net, NETLINK_XFRM, THIS_MODULE, &cfg);
        if (nlsk == NULL)
                return -ENOMEM;
        net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
index 8a23a35b9c5b4c8338d1a96e80b6a22f9bee54b7..8a77725423e0848e671a1f5bdb021fa414de6059 100644 (file)
@@ -111,8 +111,12 @@ void selnl_notify_policyload(u32 seqno)
 
 static int __init selnl_init(void)
 {
+       struct netlink_kernel_cfg cfg = {
+               .groups = SELNLGRP_MAX,
+       };
+
        selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
-                                     SELNLGRP_MAX, NULL, NULL, THIS_MODULE);
+                                     THIS_MODULE, &cfg);
        if (selnl == NULL)
                panic("SELinux:  Cannot create netlink socket.");
        netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);